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

Delta Between Two Patch Sets: Modules/_datetimemodule.c

Issue 17267: datetime.time support for '+' and 'now'
Left Patch Set: Created 6 years, 6 months ago
Right Patch Set: Created 6 years, 5 months ago
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:
Left: Side by side diff | Download
Right: Side by side diff | Download
« Lib/datetime.py ('K') | « Lib/test/datetimetester.py ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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 #include "Python.h" 5 #include "Python.h"
6 #include "structmember.h" 6 #include "structmember.h"
7 7
8 #include <time.h> 8 #include <time.h>
9 9
10 /* Differentiate between building the core module and building extension 10 /* Differentiate between building the core module and building extension
(...skipping 3803 matching lines...) Expand 10 before | Expand all | Expand 10 after
3814 if (tzinfo != Py_None) { 3814 if (tzinfo != Py_None) {
3815 offset = call_utcoffset(tzinfo, Py_None); 3815 offset = call_utcoffset(tzinfo, Py_None);
3816 if (offset == NULL) 3816 if (offset == NULL)
3817 return -1; 3817 return -1;
3818 offsecs = GET_TD_DAYS(offset)*86400 + GET_TD_SECONDS(offset); 3818 offsecs = GET_TD_DAYS(offset)*86400 + GET_TD_SECONDS(offset);
3819 Py_DECREF(offset); 3819 Py_DECREF(offset);
3820 } 3820 }
3821 return (TIME_GET_MINUTE(self)*60 - offsecs + TIME_GET_HOUR(self)*3600) != 0; 3821 return (TIME_GET_MINUTE(self)*60 - offsecs + TIME_GET_HOUR(self)*3600) != 0;
3822 } 3822 }
3823 3823
3824 /* Force all the time fields into range
3825 * the day argument is there just because I don't know how to normalize the
3826 * hours without it.
3827 */
3828
3829 static void
3830 normalize_time(int *hour, int *minute, int *second, int *microsecond)
3831 {
3832 int day = 0; /* Used to normalize the hour */
3833 normalize_pair(second, microsecond, 1000000);
3834 normalize_pair(minute, second, 60);
3835 normalize_pair(hour, minute, 60);
3836 normalize_pair(&day, hour, 24);
3837 }
3838
3839 /*
3840 * Time arithmetic
3841 */
3842
3843 /* time + timedelta -> time
3844 *
3845 .*/
3846 static PyObject *
3847 add_time_timedelta(PyDateTime_Time *time, PyDateTime_Delta *delta,
3848 int factor)
3849 {
3850 int hour = TIME_GET_HOUR(time);
3851 int minute = TIME_GET_MINUTE(time);
3852 int second = TIME_GET_SECOND(time) + GET_TD_SECONDS(delta) * factor;
3853 int microsecond = TIME_GET_MICROSECOND(time) +
3854 GET_TD_MICROSECONDS(delta) * factor;
3855
3856 assert(factor == 1 || factor == -1);
3857
3858 normalize_time(&hour, &minute, &second, &microsecond);
3859
3860 return new_time(hour, minute, second, microsecond,
3861 HASTZINFO(time) ? time->tzinfo : Py_None);
3862 }
3863
3864
3865 static PyObject *
3866 time_add(PyObject *left, PyObject *right)
3867 {
3868 if (PyDelta_Check(right)) {
3869 /* time + delta */
3870 return add_time_timedelta((PyDateTime_Time *) left,
3871 (PyDateTime_Delta *) right,
3872 1);
3873 }
3874 Py_RETURN_NOTIMPLEMENTED;
3875 }
3876
3877 static PyObject *
3878 time_subtract(PyObject *left, PyObject *right)
3879 {
3880 if (PyDelta_Check(right)) {
3881 /* time - delta */
3882 return add_time_timedelta((PyDateTime_Time *) left,
3883 (PyDateTime_Delta *) right,
3884 -1);
3885 }
3886 Py_RETURN_NOTIMPLEMENTED;
3887 }
3888
3824 /* Pickle support, a simple use of __reduce__. */ 3889 /* Pickle support, a simple use of __reduce__. */
3825 3890
3826 /* Let basestate be the non-tzinfo data string. 3891 /* Let basestate be the non-tzinfo data string.
3827 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo). 3892 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3828 * So it's a tuple in any (non-error) case. 3893 * So it's a tuple in any (non-error) case.
3829 * __getstate__ isn't exposed. 3894 * __getstate__ isn't exposed.
3830 */ 3895 */
3831 static PyObject * 3896 static PyObject *
3832 time_getstate(PyDateTime_Time *self) 3897 time_getstate(PyDateTime_Time *self)
3833 { 3898 {
3834 PyObject *basestate; 3899 PyObject *basestate;
3835 PyObject *result = NULL; 3900 PyObject *result = NULL;
3836 3901
3837 basestate = PyBytes_FromStringAndSize((char *)self->data, 3902 basestate = PyBytes_FromStringAndSize((char *)self->data,
3838 _PyDateTime_TIME_DATASIZE); 3903 _PyDateTime_TIME_DATASIZE);
3839 if (basestate != NULL) { 3904 if (basestate != NULL) {
3840 if (! HASTZINFO(self) || self->tzinfo == Py_None) 3905 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3841 result = PyTuple_Pack(1, basestate); 3906 result = PyTuple_Pack(1, basestate);
3842 else 3907 else
3843 result = PyTuple_Pack(2, basestate, self->tzinfo); 3908 result = PyTuple_Pack(2, basestate, self->tzinfo);
3844 Py_DECREF(basestate); 3909 Py_DECREF(basestate);
3845 } 3910 }
3846 return result; 3911 return result;
3847 }
3848
3849 /*
3850 * time arithmetic.
3851 */
3852
3853 /* factor must be 1 (to add) or -1 (to subtract). The result inherits
3854 * the tzinfo state of date.
3855 */
3856 static PyObject *
3857 add_time_timedelta(PyDateTime_Time *time, PyDateTime_Delta *delta,
3858 int factor)
3859 {
3860 /* Note that the C-level additions can't overflow, because of
3861 * invariant bounds on the member values.
3862 */
3863 int day = 0; // Used for normalize_pair
3864 int hour = TIME_GET_HOUR(time);
3865 int minute = TIME_GET_MINUTE(time);
3866 int second = TIME_GET_SECOND(time) + GET_TD_SECONDS(delta) * factor;
3867 int microsecond = TIME_GET_MICROSECOND(time) +
3868 GET_TD_MICROSECONDS(delta) * factor;
3869
3870 assert(factor == 1 || factor == -1);
3871
3872 normalize_pair(&second, &microsecond, 1000000);
3873 normalize_pair(&minute, &second, 60);
3874 normalize_pair(&hour, &minute, 60);
3875 normalize_pair(&day, &hour, 24);
3876
3877 return new_time(hour, minute, second, microsecond,
3878 HASTZINFO(time) ? time->tzinfo : Py_None);
3879 }
3880
3881 static PyObject *
3882 time_add(PyObject *left, PyObject *right)
3883 {
3884 if (PyTime_Check(left)) {
3885 /* time + ??? */
3886 if (PyDelta_Check(right))
3887 /* time + delta */
3888 return add_time_timedelta(
3889 (PyDateTime_Time *)left,
3890 (PyDateTime_Delta *)right,
3891 1);
3892 }
3893 else if (PyDelta_Check(left)) {
3894 /* delta + datetime */
3895 return add_time_timedelta((PyDateTime_Time *) right,
3896 (PyDateTime_Delta *) left,
3897 1);
3898 }
3899 Py_INCREF(Py_NotImplemented);
3900 return Py_NotImplemented;
3901 }
3902
3903 static PyObject *
3904 time_subtract(PyObject *left, PyObject *right)
3905 {
3906 if (PyTime_Check(left)) {
3907 /* time + ??? */
3908 if (PyDelta_Check(right))
3909 /* time + delta */
3910 return add_time_timedelta(
3911 (PyDateTime_Time *)left,
3912 (PyDateTime_Delta *)right,
3913 -1);
3914 }
3915 Py_INCREF(Py_NotImplemented);
3916 return Py_NotImplemented;
3917 } 3912 }
3918 3913
3919 static PyObject * 3914 static PyObject *
3920 time_reduce(PyDateTime_Time *self, PyObject *arg) 3915 time_reduce(PyDateTime_Time *self, PyObject *arg)
3921 { 3916 {
3922 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self)); 3917 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
3923 } 3918 }
3924 3919
3925 static PyMethodDef time_methods[] = { 3920 static PyMethodDef time_methods[] = {
3926 3921
(...skipping 1697 matching lines...) Expand 10 before | Expand all | Expand 10 after
5624 enough to say. 5619 enough to say.
5625 5620
5626 In any case, it's clear that the default fromutc() is strong enough to handle 5621 In any case, it's clear that the default fromutc() is strong enough to handle
5627 "almost all" time zones: so long as the standard offset is invariant, it 5622 "almost all" time zones: so long as the standard offset is invariant, it
5628 doesn't matter if daylight time transition points change from year to year, or 5623 doesn't matter if daylight time transition points change from year to year, or
5629 if daylight time is skipped in some years; it doesn't matter how large or 5624 if daylight time is skipped in some years; it doesn't matter how large or
5630 small dst() may get within its bounds; and it doesn't even matter if some 5625 small dst() may get within its bounds; and it doesn't even matter if some
5631 perverse time zone returns a negative dst()). So a breaking case must be 5626 perverse time zone returns a negative dst()). So a breaking case must be
5632 pretty bizarre, and a tzinfo subclass can override fromutc() if it is. 5627 pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
5633 --------------------------------------------------------------------------- */ 5628 --------------------------------------------------------------------------- */
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+