Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1104)

Side by Side Diff: Modules/datetimemodule.c

Issue 22042: Review for Python issue 5094 (Closed) Base URL: http://svn.python.org/view/*checkout*/python/trunk/
Patch Set: Created 15 years, 1 month ago , Downloaded from: http://bugs.python.org/file13029/datetime-utc-doc.patch
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« Lib/test/test_datetime.py ('K') | « Lib/test/test_datetime.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* C implementation for the date/time type documented at 1 /* C implementation for the date/time type documented at
2 * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage 2 * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
3 */ 3 */
4 4
5 #define PY_SSIZE_T_CLEAN 5 #define PY_SSIZE_T_CLEAN
6 6
7 #include "Python.h" 7 #include "Python.h"
8 #include "modsupport.h" 8 #include "modsupport.h"
9 #include "structmember.h" 9 #include "structmember.h"
10 10
11 #include <time.h> 11 #include <time.h>
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 * 1 <= M <= 12 96 * 1 <= M <= 12
97 */ 97 */
98 #define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12) 98 #define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
99 99
100 /* Forward declarations. */ 100 /* Forward declarations. */
101 static PyTypeObject PyDateTime_DateType; 101 static PyTypeObject PyDateTime_DateType;
102 static PyTypeObject PyDateTime_DateTimeType; 102 static PyTypeObject PyDateTime_DateTimeType;
103 static PyTypeObject PyDateTime_DeltaType; 103 static PyTypeObject PyDateTime_DeltaType;
104 static PyTypeObject PyDateTime_TimeType; 104 static PyTypeObject PyDateTime_TimeType;
105 static PyTypeObject PyDateTime_TZInfoType; 105 static PyTypeObject PyDateTime_TZInfoType;
106 static PyTypeObject PyDateTime_UTCType;
106 107
107 /* --------------------------------------------------------------------------- 108 /* ---------------------------------------------------------------------------
108 * Math utilities. 109 * Math utilities.
109 */ 110 */
110 111
111 /* k = i+j overflows iff k differs in sign from both inputs, 112 /* k = i+j overflows iff k differs in sign from both inputs,
112 * iff k^i has sign bit set and k^j has sign bit set, 113 * iff k^i has sign bit set and k^j has sign bit set,
113 * iff (k^i)&(k^j) has sign bit set. 114 * iff (k^i)&(k^j) has sign bit set.
114 */ 115 */
115 #define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \ 116 #define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
(...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 SET_TD_DAYS(self, days); 745 SET_TD_DAYS(self, days);
745 SET_TD_SECONDS(self, seconds); 746 SET_TD_SECONDS(self, seconds);
746 SET_TD_MICROSECONDS(self, microseconds); 747 SET_TD_MICROSECONDS(self, microseconds);
747 } 748 }
748 return (PyObject *) self; 749 return (PyObject *) self;
749 } 750 }
750 751
751 #define new_delta(d, s, us, normalize) \ 752 #define new_delta(d, s, us, normalize) \
752 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType) 753 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
753 754
755 static PyObject *
756 new_utc_ex(PyTypeObject *type)
757 {
758 return type->tp_alloc(type, 0);
759 }
760
761 #define new_utc() \
762 new_utc_ex(&PyDateTime_UTCType)
763
754 /* --------------------------------------------------------------------------- 764 /* ---------------------------------------------------------------------------
755 * tzinfo helpers. 765 * tzinfo helpers.
756 */ 766 */
757 767
758 /* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not 768 /* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
759 * raise TypeError and return -1. 769 * raise TypeError and return -1.
760 */ 770 */
761 static int 771 static int
762 check_tzinfo_subclass(PyObject *p) 772 check_tzinfo_subclass(PyObject *p)
763 { 773 {
(...skipping 2275 matching lines...) Expand 10 before | Expand all | Expand 10 after
3039 0, /* tp_dict */ 3049 0, /* tp_dict */
3040 0, /* tp_descr_get */ 3050 0, /* tp_descr_get */
3041 0, /* tp_descr_set */ 3051 0, /* tp_descr_set */
3042 0, /* tp_dictoffset */ 3052 0, /* tp_dictoffset */
3043 0, /* tp_init */ 3053 0, /* tp_init */
3044 0, /* tp_alloc */ 3054 0, /* tp_alloc */
3045 PyType_GenericNew, /* tp_new */ 3055 PyType_GenericNew, /* tp_new */
3046 0, /* tp_free */ 3056 0, /* tp_free */
3047 }; 3057 };
3048 3058
3059 static int
3060 utc_init(PyObject *self)
brett.cannon 2009/02/27 04:12:29 This function is never used.
3061 {
3062 return 0;
3063 }
3064
3065 static PyObject *
3066 utc_tzname(PyObject *self, PyObject *dt)
3067 {
3068 return PyString_FromString("UTC");
3069 }
3070
3071 static PyObject *
3072 utc_utcoffset(PyObject *self, PyObject *dt)
3073 {
3074 return new_delta(0, 0, 0, 0);
3075 }
3076
3077 static PyObject *
3078 utc_dst(PyObject *self, PyObject *dt)
3079 {
3080 return new_delta(0, 0, 0, 0);
3081 }
3082
3083 static PyMethodDef utc_methods[] = {
3084
3085 {"tzname", (PyCFunction)utc_tzname, METH_O,
brett.cannon 2009/02/27 04:12:29 Ditch the tab spacing.
3086 PyDoc_STR("Always 'UTC'.")},
3087
3088 {"utcoffset", (PyCFunction)utc_utcoffset, METH_O,
3089 PyDoc_STR("Always 0 minutes.")},
3090
3091 {"dst", (PyCFunction)utc_dst, METH_O,
3092 PyDoc_STR("Always 0 minutes.")},
3093
3094 {NULL, NULL}
3095 };
3096
3097 static char utc_doc[] =
3098 PyDoc_STR("UTC timezone class.");
brett.cannon 2009/02/27 04:12:29 Mention it is an implementation of tzinfo.
3099
3100 statichere PyTypeObject PyDateTime_UTCType = {
3101 PyObject_HEAD_INIT(NULL)
3102 0, /* ob_size */
3103 "datetime.UTC", /* tp_name */
3104 sizeof(PyDateTime_UTC), /* tp_basicsize */
3105 0, /* tp_itemsize */
3106 0, /* tp_dealloc */
3107 0, /* tp_print */
3108 0, /* tp_getattr */
3109 0, /* tp_setattr */
3110 0, /* tp_compare */
3111 0, /* tp_repr */
3112 0, /* tp_as_number */
3113 0, /* tp_as_sequence */
3114 0, /* tp_as_mapping */
3115 0, /* tp_hash */
3116 0, /* tp_call */
3117 0, /* tp_str */
3118 0, /* tp_getattro */
3119 0, /* tp_setattro */
3120 0, /* tp_as_buffer */
3121 Py_TPFLAGS_DEFAULT, /* tp_flags */
3122 utc_doc, /* tp_doc */
3123 0, /* tp_traverse */
3124 0, /* tp_clear */
3125 0, /* tp_richcompare */
3126 0, /* tp_weaklistoffset */
3127 0, /* tp_iter */
3128 0, /* tp_iternext */
3129 utc_methods, /* tp_methods */
3130 0, /* tp_members */
3131 0, /* tp_getset */
3132 &PyDateTime_TZInfoType, /* tp_base */
3133 0, /* tp_dict */
3134 0, /* tp_descr_get */
3135 0, /* tp_descr_set */
3136 0, /* tp_dictoffset */
3137 0, /* tp_init */
3138 0, /* tp_alloc */
3139 PyType_GenericNew, /* tp_new */
3140 };
3141
3049 /* 3142 /*
3050 * PyDateTime_Time implementation. 3143 * PyDateTime_Time implementation.
3051 */ 3144 */
3052 3145
3053 /* Accessor properties. 3146 /* Accessor properties.
3054 */ 3147 */
3055 3148
3056 static PyObject * 3149 static PyObject *
3057 time_hour(PyDateTime_Time *self, void *unused) 3150 time_hour(PyDateTime_Time *self, void *unused)
3058 { 3151 {
(...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after
3835 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self); 3928 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3836 Py_DECREF(temp); 3929 Py_DECREF(temp);
3837 } 3930 }
3838 return self; 3931 return self;
3839 } 3932 }
3840 3933
3841 /* Return best possible UTC time -- this isn't constrained by the 3934 /* Return best possible UTC time -- this isn't constrained by the
3842 * precision of a timestamp. 3935 * precision of a timestamp.
3843 */ 3936 */
3844 static PyObject * 3937 static PyObject *
3845 datetime_utcnow(PyObject *cls, PyObject *dummy) 3938 datetime_utcnow(PyObject *cls, PyObject *args, PyObject *kw)
3846 { 3939 {
3847 » return datetime_best_possible(cls, gmtime, Py_None); 3940 PyObject *utc = Py_None;
3941 PyObject *tz_aware = Py_False;
3942 static char *keywords[] = {"tz_aware", NULL};
3943 ··
3944 » if (! PyArg_ParseTupleAndKeywords(args, kw, "|b",
3945 » » » » » keywords, &tz_aware))
3946 » » return NULL;
3947 if (tz_aware == Py_True)
brett.cannon 2009/02/27 04:12:29 Use PyObject_IsTrue() instead of checking for Py_T
3948 utc = new_utc();
brett.cannon 2009/02/27 04:12:29 Check for errors on the return value.
3949
3950 » return datetime_best_possible(cls, gmtime, utc);
3848 } 3951 }
3849 3952
3850 /* Return new local datetime from timestamp (Python timestamp -- a double). */ 3953 /* Return new local datetime from timestamp (Python timestamp -- a double). */
3851 static PyObject * 3954 static PyObject *
3852 datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw) 3955 datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
3853 { 3956 {
3854 PyObject *self; 3957 PyObject *self;
3855 double timestamp; 3958 double timestamp;
3856 PyObject *tzinfo = Py_None; 3959 PyObject *tzinfo = Py_None;
3857 static char *keywords[] = {"timestamp", "tz", NULL}; 3960 static char *keywords[] = {"timestamp", "tz", NULL};
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after
4560 4663
4561 static PyMethodDef datetime_methods[] = { 4664 static PyMethodDef datetime_methods[] = {
4562 4665
4563 /* Class methods: */ 4666 /* Class methods: */
4564 4667
4565 {"now", (PyCFunction)datetime_now, 4668 {"now", (PyCFunction)datetime_now,
4566 METH_VARARGS | METH_KEYWORDS | METH_CLASS, 4669 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4567 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")}, 4670 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
4568 4671
4569 {"utcnow", (PyCFunction)datetime_utcnow, 4672 {"utcnow", (PyCFunction)datetime_utcnow,
4570 » METH_NOARGS | METH_CLASS, 4673 » METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4571 » PyDoc_STR("Return a new datetime representing UTC day and time.")}, 4674 » PyDoc_STR("[tz_aware] -> Return a new datetime "\
4675 "representing UTC day and time.")},
4572 4676
4573 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp, 4677 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4574 METH_VARARGS | METH_KEYWORDS | METH_CLASS, 4678 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4575 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")}, 4679 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
4576 4680
4577 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp, 4681 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4578 METH_VARARGS | METH_CLASS, 4682 METH_VARARGS | METH_CLASS,
4579 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp " 4683 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4580 "(like time.time()).")}, 4684 "(like time.time()).")},
4581 4685
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
4709 4813
4710 /* C API. Clients get at this via PyDateTime_IMPORT, defined in 4814 /* C API. Clients get at this via PyDateTime_IMPORT, defined in
4711 * datetime.h. 4815 * datetime.h.
4712 */ 4816 */
4713 static PyDateTime_CAPI CAPI = { 4817 static PyDateTime_CAPI CAPI = {
4714 &PyDateTime_DateType, 4818 &PyDateTime_DateType,
4715 &PyDateTime_DateTimeType, 4819 &PyDateTime_DateTimeType,
4716 &PyDateTime_TimeType, 4820 &PyDateTime_TimeType,
4717 &PyDateTime_DeltaType, 4821 &PyDateTime_DeltaType,
4718 &PyDateTime_TZInfoType, 4822 &PyDateTime_TZInfoType,
4823 &PyDateTime_UTCType,
4719 new_date_ex, 4824 new_date_ex,
4720 new_datetime_ex, 4825 new_datetime_ex,
4721 new_time_ex, 4826 new_time_ex,
4722 new_delta_ex, 4827 new_delta_ex,
4723 datetime_fromtimestamp, 4828 datetime_fromtimestamp,
4724 date_fromtimestamp 4829 date_fromtimestamp
4725 }; 4830 };
4726 4831
4727 4832
4728 PyMODINIT_FUNC 4833 PyMODINIT_FUNC
(...skipping 11 matching lines...) Expand all
4740 if (PyType_Ready(&PyDateTime_DateType) < 0) 4845 if (PyType_Ready(&PyDateTime_DateType) < 0)
4741 return; 4846 return;
4742 if (PyType_Ready(&PyDateTime_DateTimeType) < 0) 4847 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4743 return; 4848 return;
4744 if (PyType_Ready(&PyDateTime_DeltaType) < 0) 4849 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4745 return; 4850 return;
4746 if (PyType_Ready(&PyDateTime_TimeType) < 0) 4851 if (PyType_Ready(&PyDateTime_TimeType) < 0)
4747 return; 4852 return;
4748 if (PyType_Ready(&PyDateTime_TZInfoType) < 0) 4853 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4749 return; 4854 return;
4855 if (PyType_Ready(&PyDateTime_UTCType) < 0)
4856 return;
4750 4857
4751 /* timedelta values */ 4858 /* timedelta values */
4752 d = PyDateTime_DeltaType.tp_dict; 4859 d = PyDateTime_DeltaType.tp_dict;
4753 4860
4754 x = new_delta(0, 0, 1, 0); 4861 x = new_delta(0, 0, 1, 0);
4755 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0) 4862 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4756 return; 4863 return;
4757 Py_DECREF(x); 4864 Py_DECREF(x);
4758 4865
4759 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0); 4866 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
4833 4940
4834 Py_INCREF(&PyDateTime_TimeType); 4941 Py_INCREF(&PyDateTime_TimeType);
4835 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType); 4942 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
4836 4943
4837 Py_INCREF(&PyDateTime_DeltaType); 4944 Py_INCREF(&PyDateTime_DeltaType);
4838 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType); 4945 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
4839 4946
4840 Py_INCREF(&PyDateTime_TZInfoType); 4947 Py_INCREF(&PyDateTime_TZInfoType);
4841 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType); 4948 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
4842 4949
4950 Py_INCREF(&PyDateTime_UTCType);
4951 PyModule_AddObject(m, "UTC", (PyObject *) &PyDateTime_UTCType);
4952
4843 x = PyCObject_FromVoidPtrAndDesc(&CAPI, (void*) DATETIME_API_MAGIC, 4953 x = PyCObject_FromVoidPtrAndDesc(&CAPI, (void*) DATETIME_API_MAGIC,
4844 NULL); 4954 NULL);
4845 if (x == NULL) 4955 if (x == NULL)
4846 return; 4956 return;
4847 PyModule_AddObject(m, "datetime_CAPI", x); 4957 PyModule_AddObject(m, "datetime_CAPI", x);
4848 4958
4849 /* A 4-year cycle has an extra leap day over what we'd get from 4959 /* A 4-year cycle has an extra leap day over what we'd get from
4850 * pasting together 4 single years. 4960 * pasting together 4 single years.
4851 */ 4961 */
4852 assert(DI4Y == 4 * 365 + 1); 4962 assert(DI4Y == 4 * 365 + 1);
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
5073 enough to say. 5183 enough to say.
5074 5184
5075 In any case, it's clear that the default fromutc() is strong enough to handle 5185 In any case, it's clear that the default fromutc() is strong enough to handle
5076 "almost all" time zones: so long as the standard offset is invariant, it 5186 "almost all" time zones: so long as the standard offset is invariant, it
5077 doesn't matter if daylight time transition points change from year to year, or 5187 doesn't matter if daylight time transition points change from year to year, or
5078 if daylight time is skipped in some years; it doesn't matter how large or 5188 if daylight time is skipped in some years; it doesn't matter how large or
5079 small dst() may get within its bounds; and it doesn't even matter if some 5189 small dst() may get within its bounds; and it doesn't even matter if some
5080 perverse time zone returns a negative dst()). So a breaking case must be 5190 perverse time zone returns a negative dst()). So a breaking case must be
5081 pretty bizarre, and a tzinfo subclass can override fromutc() if it is. 5191 pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
5082 --------------------------------------------------------------------------- */ 5192 --------------------------------------------------------------------------- */
OLDNEW
« Lib/test/test_datetime.py ('K') | « Lib/test/test_datetime.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b