39
40
#define MAX_DELTA_DAYS 999999999
41
42
/* Rename the long macros in datetime.h to more reasonable short names. */
42
#define GET_YEAR PyDateTime_GET_YEAR
43
#define GET_MONTH PyDateTime_GET_MONTH
44
#define GET_DAY PyDateTime_GET_DAY
45
#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
46
#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
47
#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
48
#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
43
#define GET_YEAR PyDateTime_GET_YEAR
44
#define GET_MONTH PyDateTime_GET_MONTH
45
#define GET_DAY PyDateTime_GET_DAY
46
#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
47
#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
48
#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
49
#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
50
51
/* Date accessors for date and datetime. */
51
#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
52
((o)->data[1] = ((v) & 0x00ff)))
53
#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
54
#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
52
#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
53
((o)->data[1] = ((v) & 0x00ff)))
54
#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
55
#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
56
57
/* Date/Time accessors for datetime. */
57
#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
58
#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
59
#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
60
#define DATE_SET_MICROSECOND(o, v) \
61
(((o)->data[7] = ((v) & 0xff0000) >> 16), \
62
((o)->data[8] = ((v) & 0x00ff00) >> 8), \
63
((o)->data[9] = ((v) & 0x0000ff)))
58
#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
59
#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
60
#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
61
#define DATE_SET_MICROSECOND(o, v) \
62
(((o)->data[7] = ((v) & 0xff0000) >> 16), \
63
((o)->data[8] = ((v) & 0x00ff00) >> 8), \
64
((o)->data[9] = ((v) & 0x0000ff)))
65
66
/* Time accessors for time. */
66
#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
67
#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
68
#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
69
#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
70
#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
71
#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
72
#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
73
#define TIME_SET_MICROSECOND(o, v) \
74
(((o)->data[3] = ((v) & 0xff0000) >> 16), \
75
((o)->data[4] = ((v) & 0x00ff00) >> 8), \
76
((o)->data[5] = ((v) & 0x0000ff)))
67
#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
68
#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
69
#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
70
#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
71
#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
72
#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
73
#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
74
#define TIME_SET_MICROSECOND(o, v) \
75
(((o)->data[3] = ((v) & 0xff0000) >> 16), \
76
((o)->data[4] = ((v) & 0x00ff00) >> 8), \
77
((o)->data[5] = ((v) & 0x0000ff)))
78
79
/* Delta accessors for timedelta. */
79
#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
80
#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
81
#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
80
#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
81
#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
82
#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
83
#define SET_TD_DAYS(o, v) ((o)->days = (v))
84
#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
84
#define SET_TD_DAYS(o, v) ((o)->days = (v))
85
#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
85
86
#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
87
88
/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
90
#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
91
#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
92
93
/* M is a char or int claiming to be a valid month. The macro is equivalent
93
94
* to the two-sided Python test
96
97
#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
160
161
* are correct for non-leap years only.
162
163
static int _days_in_month[] = {
163
0, /* unused; this vector uses 1-based indexing */
164
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
164
0, /* unused; this vector uses 1-based indexing */
165
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
167
168
static int _days_before_month[] = {
168
0, /* unused; this vector uses 1-based indexing */
169
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
169
0, /* unused; this vector uses 1-based indexing */
170
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
172
173
/* year -> 1 if leap year, else 0. */
174
175
is_leap(int year)
176
/* Cast year to unsigned. The result is the same either way, but
177
* C can generate faster code for unsigned mod than for signed
178
* mod (especially for % 4 -- a good compiler should just grab
179
* the last 2 bits when the LHS is unsigned).
181
const unsigned int ayear = (unsigned int)year;
182
return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
177
/* Cast year to unsigned. The result is the same either way, but
178
* C can generate faster code for unsigned mod than for signed
179
* mod (especially for % 4 -- a good compiler should just grab
180
* the last 2 bits when the LHS is unsigned).
182
const unsigned int ayear = (unsigned int)year;
183
return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
185
186
/* year, month -> number of days in that month in that year */
187
188
days_in_month(int year, int month)
191
if (month == 2 && is_leap(year))
194
return _days_in_month[month];
192
if (month == 2 && is_leap(year))
195
return _days_in_month[month];
197
198
/* year, month -> number of days in year preceeding first day of month */
199
200
days_before_month(int year, int month)
205
days = _days_before_month[month];
206
if (month > 2 && is_leap(year))
206
days = _days_before_month[month];
207
if (month > 2 && is_leap(year))
211
212
/* year -> number of days before January 1st of year. Remember that we
215
216
days_before_year(int year)
218
/* This is incorrect if year <= 0; we really want the floor
219
* here. But so long as MINYEAR is 1, the smallest year this
220
* can see is 0 (this can happen in some normalization endcases),
221
* so we'll just special-case that.
225
return y*365 + y/4 - y/100 + y/400;
219
/* This is incorrect if year <= 0; we really want the floor
220
* here. But so long as MINYEAR is 1, the smallest year this
221
* can see is 0 (this can happen in some normalization endcases),
222
* so we'll just special-case that.
226
return y*365 + y/4 - y/100 + y/400;
232
233
/* Number of days in 4, 100, and 400 year cycles. That these have
233
234
* the correct values is asserted in the module init function.
235
#define DI4Y 1461 /* days_before_year(5); days in 4 years */
236
#define DI100Y 36524 /* days_before_year(101); days in 100 years */
237
#define DI400Y 146097 /* days_before_year(401); days in 400 years */
236
#define DI4Y 1461 /* days_before_year(5); days in 4 years */
237
#define DI100Y 36524 /* days_before_year(101); days in 100 years */
238
#define DI400Y 146097 /* days_before_year(401); days in 400 years */
239
240
/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
241
242
ord_to_ymd(int ordinal, int *year, int *month, int *day)
243
int n, n1, n4, n100, n400, leapyear, preceding;
245
/* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
246
* leap years repeats exactly every 400 years. The basic strategy is
247
* to find the closest 400-year boundary at or before ordinal, then
248
* work with the offset from that boundary to ordinal. Life is much
249
* clearer if we subtract 1 from ordinal first -- then the values
250
* of ordinal at 400-year boundaries are exactly those divisible
254
* -- --- ---- ---------- ----------------
255
* 31 Dec -400 -DI400Y -DI400Y -1
256
* 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
260
* 1 Jan 001 1 0 400-year boundary
264
* 31 Dec 400 DI400Y DI400Y -1
265
* 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
267
assert(ordinal >= 1);
269
n400 = ordinal / DI400Y;
270
n = ordinal % DI400Y;
271
*year = n400 * 400 + 1;
273
/* Now n is the (non-negative) offset, in days, from January 1 of
274
* year, to the desired date. Now compute how many 100-year cycles
276
* Note that it's possible for n100 to equal 4! In that case 4 full
277
* 100-year cycles precede the desired day, which implies the
278
* desired day is December 31 at the end of a 400-year cycle.
283
/* Now compute how many 4-year cycles precede it. */
287
/* And now how many single years. Again n1 can be 4, and again
288
* meaning that the desired day is December 31 at the end of the
294
*year += n100 * 100 + n4 * 4 + n1;
295
if (n1 == 4 || n100 == 4) {
303
/* Now the year is correct, and n is the offset from January 1. We
304
* find the month via an estimate that's either exact or one too
307
leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
308
assert(leapyear == is_leap(*year));
309
*month = (n + 50) >> 5;
310
preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
312
/* estimate is too large */
314
preceding -= days_in_month(*year, *month);
318
assert(n < days_in_month(*year, *month));
244
int n, n1, n4, n100, n400, leapyear, preceding;
246
/* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
247
* leap years repeats exactly every 400 years. The basic strategy is
248
* to find the closest 400-year boundary at or before ordinal, then
249
* work with the offset from that boundary to ordinal. Life is much
250
* clearer if we subtract 1 from ordinal first -- then the values
251
* of ordinal at 400-year boundaries are exactly those divisible
255
* -- --- ---- ---------- ----------------
256
* 31 Dec -400 -DI400Y -DI400Y -1
257
* 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
261
* 1 Jan 001 1 0 400-year boundary
265
* 31 Dec 400 DI400Y DI400Y -1
266
* 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
268
assert(ordinal >= 1);
270
n400 = ordinal / DI400Y;
271
n = ordinal % DI400Y;
272
*year = n400 * 400 + 1;
274
/* Now n is the (non-negative) offset, in days, from January 1 of
275
* year, to the desired date. Now compute how many 100-year cycles
277
* Note that it's possible for n100 to equal 4! In that case 4 full
278
* 100-year cycles precede the desired day, which implies the
279
* desired day is December 31 at the end of a 400-year cycle.
284
/* Now compute how many 4-year cycles precede it. */
288
/* And now how many single years. Again n1 can be 4, and again
289
* meaning that the desired day is December 31 at the end of the
295
*year += n100 * 100 + n4 * 4 + n1;
296
if (n1 == 4 || n100 == 4) {
304
/* Now the year is correct, and n is the offset from January 1. We
305
* find the month via an estimate that's either exact or one too
308
leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
309
assert(leapyear == is_leap(*year));
310
*month = (n + 50) >> 5;
311
preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
313
/* estimate is too large */
315
preceding -= days_in_month(*year, *month);
319
assert(n < days_in_month(*year, *month));
323
324
/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
325
326
ymd_to_ord(int year, int month, int day)
327
return days_before_year(year) + days_before_month(year, month) + day;
328
return days_before_year(year) + days_before_month(year, month) + day;
330
331
/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
332
333
weekday(int year, int month, int day)
334
return (ymd_to_ord(year, month, day) + 6) % 7;
335
return (ymd_to_ord(year, month, day) + 6) % 7;
337
338
/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
437
438
normalize_pair(int *hi, int *lo, int factor)
441
if (*lo < 0 || *lo >= factor) {
442
const int num_hi = divmod(*lo, factor, lo);
443
const int new_hi = *hi + num_hi;
444
assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
447
assert(0 <= *lo && *lo < factor);
442
if (*lo < 0 || *lo >= factor) {
443
const int num_hi = divmod(*lo, factor, lo);
444
const int new_hi = *hi + num_hi;
445
assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
448
assert(0 <= *lo && *lo < factor);
450
451
/* Fiddle days (d), seconds (s), and microseconds (us) so that
453
454
* The input values must be such that the internals don't overflow.
454
455
* The way this routine is used, we don't get close.
457
458
normalize_d_s_us(int *d, int *s, int *us)
459
if (*us < 0 || *us >= 1000000) {
460
normalize_pair(s, us, 1000000);
461
/* |s| can't be bigger than about
462
* |original s| + |original us|/1000000 now.
460
if (*us < 0 || *us >= 1000000) {
461
normalize_pair(s, us, 1000000);
462
/* |s| can't be bigger than about
463
* |original s| + |original us|/1000000 now.
466
if (*s < 0 || *s >= 24*3600) {
467
normalize_pair(d, s, 24*3600);
468
/* |d| can't be bigger than about
470
* (|original s| + |original us|/1000000) / (24*3600) now.
473
assert(0 <= *s && *s < 24*3600);
474
assert(0 <= *us && *us < 1000000);
467
if (*s < 0 || *s >= 24*3600) {
468
normalize_pair(d, s, 24*3600);
469
/* |d| can't be bigger than about
471
* (|original s| + |original us|/1000000) / (24*3600) now.
474
assert(0 <= *s && *s < 24*3600);
475
assert(0 <= *us && *us < 1000000);
477
478
/* Fiddle years (y), months (m), and days (d) so that
479
* 1 <= *d <= days_in_month(*y, *m)
480
* 1 <= *d <= days_in_month(*y, *m)
480
481
* The input values must be such that the internals don't overflow.
481
482
* The way this routine is used, we don't get close.
484
485
normalize_y_m_d(int *y, int *m, int *d)
486
int dim; /* # of days in month */
488
/* This gets muddy: the proper range for day can't be determined
489
* without knowing the correct month and year, but if day is, e.g.,
490
* plus or minus a million, the current month and year values make
491
* no sense (and may also be out of bounds themselves).
492
* Saying 12 months == 1 year should be non-controversial.
494
if (*m < 1 || *m > 12) {
496
normalize_pair(y, m, 12);
498
/* |y| can't be bigger than about
499
* |original y| + |original m|/12 now.
502
assert(1 <= *m && *m <= 12);
504
/* Now only day can be out of bounds (year may also be out of bounds
505
* for a datetime object, but we don't care about that here).
506
* If day is out of bounds, what to do is arguable, but at least the
507
* method here is principled and explainable.
509
dim = days_in_month(*y, *m);
510
if (*d < 1 || *d > dim) {
511
/* Move day-1 days from the first of the month. First try to
512
* get off cheap if we're only one day out of range
513
* (adjustments for timezone alone can't be worse than that).
518
*d = days_in_month(*y, *m);
525
else if (*d == dim + 1) {
526
/* move forward a day */
535
int ordinal = ymd_to_ord(*y, *m, 1) +
537
ord_to_ymd(ordinal, y, m, d);
487
int dim; /* # of days in month */
489
/* This gets muddy: the proper range for day can't be determined
490
* without knowing the correct month and year, but if day is, e.g.,
491
* plus or minus a million, the current month and year values make
492
* no sense (and may also be out of bounds themselves).
493
* Saying 12 months == 1 year should be non-controversial.
495
if (*m < 1 || *m > 12) {
497
normalize_pair(y, m, 12);
499
/* |y| can't be bigger than about
500
* |original y| + |original m|/12 now.
503
assert(1 <= *m && *m <= 12);
505
/* Now only day can be out of bounds (year may also be out of bounds
506
* for a datetime object, but we don't care about that here).
507
* If day is out of bounds, what to do is arguable, but at least the
508
* method here is principled and explainable.
510
dim = days_in_month(*y, *m);
511
if (*d < 1 || *d > dim) {
512
/* Move day-1 days from the first of the month. First try to
513
* get off cheap if we're only one day out of range
514
* (adjustments for timezone alone can't be worse than that).
519
*d = days_in_month(*y, *m);
526
else if (*d == dim + 1) {
527
/* move forward a day */
536
int ordinal = ymd_to_ord(*y, *m, 1) +
538
if (ordinal < 1 || ordinal > MAXORDINAL) {
541
ord_to_ymd(ordinal, y, m, d);
548
if (MINYEAR <= *y && *y <= MAXYEAR)
551
PyErr_SetString(PyExc_OverflowError,
552
"date value out of range");
544
557
/* Fiddle out-of-bounds months and days so that the result makes some kind
650
653
static PyObject *
651
654
new_date_ex(int year, int month, int day, PyTypeObject *type)
653
PyDateTime_Date *self;
656
PyDateTime_Date *self;
655
self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
657
set_date_fields(self, year, month, day);
658
return (PyObject *) self;
658
self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
660
set_date_fields(self, year, month, day);
661
return (PyObject *) self;
661
664
#define new_date(year, month, day) \
662
new_date_ex(year, month, day, &PyDateTime_DateType)
665
new_date_ex(year, month, day, &PyDateTime_DateType)
664
667
/* Create a datetime instance with no range checking. */
665
668
static PyObject *
666
669
new_datetime_ex(int year, int month, int day, int hour, int minute,
667
int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
670
int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
669
PyDateTime_DateTime *self;
670
char aware = tzinfo != Py_None;
672
PyDateTime_DateTime *self;
673
char aware = tzinfo != Py_None;
672
self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
674
self->hastzinfo = aware;
675
set_date_fields((PyDateTime_Date *)self, year, month, day);
676
DATE_SET_HOUR(self, hour);
677
DATE_SET_MINUTE(self, minute);
678
DATE_SET_SECOND(self, second);
679
DATE_SET_MICROSECOND(self, usecond);
682
self->tzinfo = tzinfo;
685
return (PyObject *)self;
675
self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
677
self->hastzinfo = aware;
678
set_date_fields((PyDateTime_Date *)self, year, month, day);
679
DATE_SET_HOUR(self, hour);
680
DATE_SET_MINUTE(self, minute);
681
DATE_SET_SECOND(self, second);
682
DATE_SET_MICROSECOND(self, usecond);
685
self->tzinfo = tzinfo;
688
return (PyObject *)self;
688
#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
689
new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
690
&PyDateTime_DateTimeType)
691
#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
692
new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
693
&PyDateTime_DateTimeType)
692
695
/* Create a time instance with no range checking. */
693
696
static PyObject *
694
697
new_time_ex(int hour, int minute, int second, int usecond,
695
PyObject *tzinfo, PyTypeObject *type)
698
PyObject *tzinfo, PyTypeObject *type)
697
PyDateTime_Time *self;
698
char aware = tzinfo != Py_None;
700
PyDateTime_Time *self;
701
char aware = tzinfo != Py_None;
700
self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
702
self->hastzinfo = aware;
704
TIME_SET_HOUR(self, hour);
705
TIME_SET_MINUTE(self, minute);
706
TIME_SET_SECOND(self, second);
707
TIME_SET_MICROSECOND(self, usecond);
710
self->tzinfo = tzinfo;
713
return (PyObject *)self;
703
self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
705
self->hastzinfo = aware;
707
TIME_SET_HOUR(self, hour);
708
TIME_SET_MINUTE(self, minute);
709
TIME_SET_SECOND(self, second);
710
TIME_SET_MICROSECOND(self, usecond);
713
self->tzinfo = tzinfo;
716
return (PyObject *)self;
716
#define new_time(hh, mm, ss, us, tzinfo) \
717
new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
719
#define new_time(hh, mm, ss, us, tzinfo) \
720
new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
719
722
/* Create a timedelta instance. Normalize the members iff normalize is
720
723
* true. Passing false is a speed optimization, if you know for sure
1105
1103
format_utcoffset(char *buf, size_t buflen, const char *sep,
1106
PyObject *tzinfo, PyObject *tzinfoarg)
1104
PyObject *tzinfo, PyObject *tzinfoarg)
1114
assert(buflen >= 1);
1116
offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1117
if (offset == -1 && PyErr_Occurred())
1128
hours = divmod(offset, 60, &minutes);
1129
PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1112
assert(buflen >= 1);
1114
offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1115
if (offset == -1 && PyErr_Occurred())
1126
hours = divmod(offset, 60, &minutes);
1127
PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1133
1131
static PyObject *
1134
1132
make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1137
PyObject *tzinfo = get_tzinfo_member(object);
1138
PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
1139
if (Zreplacement == NULL)
1141
if (tzinfo == Py_None || tzinfo == NULL)
1142
return Zreplacement;
1144
assert(tzinfoarg != NULL);
1145
temp = call_tzname(tzinfo, tzinfoarg);
1148
if (temp == Py_None) {
1150
return Zreplacement;
1153
assert(PyUnicode_Check(temp));
1154
/* Since the tzname is getting stuffed into the
1155
* format, we have to double any % signs so that
1156
* strftime doesn't treat them as format codes.
1158
Py_DECREF(Zreplacement);
1159
Zreplacement = PyObject_CallMethod(temp, "replace", "ss", "%", "%%");
1161
if (Zreplacement == NULL)
1163
if (!PyUnicode_Check(Zreplacement)) {
1164
PyErr_SetString(PyExc_TypeError,
1165
"tzname.replace() did not return a string");
1168
return Zreplacement;
1135
PyObject *tzinfo = get_tzinfo_member(object);
1136
PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
1137
if (Zreplacement == NULL)
1139
if (tzinfo == Py_None || tzinfo == NULL)
1140
return Zreplacement;
1142
assert(tzinfoarg != NULL);
1143
temp = call_tzname(tzinfo, tzinfoarg);
1146
if (temp == Py_None) {
1148
return Zreplacement;
1151
assert(PyUnicode_Check(temp));
1152
/* Since the tzname is getting stuffed into the
1153
* format, we have to double any % signs so that
1154
* strftime doesn't treat them as format codes.
1156
Py_DECREF(Zreplacement);
1157
Zreplacement = PyObject_CallMethod(temp, "replace", "ss", "%", "%%");
1159
if (Zreplacement == NULL)
1161
if (!PyUnicode_Check(Zreplacement)) {
1162
PyErr_SetString(PyExc_TypeError,
1163
"tzname.replace() did not return a string");
1166
return Zreplacement;
1171
Py_DECREF(Zreplacement);
1169
Py_DECREF(Zreplacement);
1175
1173
static PyObject *
1176
1174
make_freplacement(PyObject *object)
1178
char freplacement[64];
1179
if (PyTime_Check(object))
1180
sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1181
else if (PyDateTime_Check(object))
1182
sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1184
sprintf(freplacement, "%06d", 0);
1176
char freplacement[64];
1177
if (PyTime_Check(object))
1178
sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1179
else if (PyDateTime_Check(object))
1180
sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1182
sprintf(freplacement, "%06d", 0);
1186
return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
1184
return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
1189
1187
/* I sure don't want to reproduce the strftime code from the time module,
1196
1194
static PyObject *
1197
1195
wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
1198
PyObject *tzinfoarg)
1196
PyObject *tzinfoarg)
1200
PyObject *result = NULL; /* guilty until proved innocent */
1202
PyObject *zreplacement = NULL; /* py string, replacement for %z */
1203
PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1204
PyObject *freplacement = NULL; /* py string, replacement for %f */
1206
const char *pin; /* pointer to next char in input format */
1207
Py_ssize_t flen; /* length of input format */
1208
char ch; /* next char in input format */
1210
PyObject *newfmt = NULL; /* py string, the output format */
1211
char *pnew; /* pointer to available byte in output format */
1212
size_t totalnew; /* number bytes total in output format buffer,
1213
exclusive of trailing \0 */
1214
size_t usednew; /* number bytes used so far in output format buffer */
1216
const char *ptoappend; /* ptr to string to append to output buffer */
1217
Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
1219
assert(object && format && timetuple);
1220
assert(PyUnicode_Check(format));
1221
/* Convert the input format to a C string and size */
1222
pin = _PyUnicode_AsStringAndSize(format, &flen);
1226
/* Give up if the year is before 1900.
1227
* Python strftime() plays games with the year, and different
1228
* games depending on whether envar PYTHON2K is set. This makes
1229
* years before 1900 a nightmare, even if the platform strftime
1230
* supports them (and not all do).
1231
* We could get a lot farther here by avoiding Python's strftime
1232
* wrapper and calling the C strftime() directly, but that isn't
1233
* an option in the Python implementation of this module.
1237
PyObject *pyyear = PySequence_GetItem(timetuple, 0);
1238
if (pyyear == NULL) return NULL;
1239
assert(PyLong_Check(pyyear));
1240
year = PyLong_AsLong(pyyear);
1243
PyErr_Format(PyExc_ValueError, "year=%ld is before "
1244
"1900; the datetime strftime() "
1245
"methods require year >= 1900",
1251
/* Scan the input format, looking for %z/%Z/%f escapes, building
1252
* a new format. Since computing the replacements for those codes
1253
* is expensive, don't unless they're actually used.
1255
if (flen > INT_MAX - 1) {
1260
totalnew = flen + 1; /* realistic if no %z/%Z */
1261
newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1262
if (newfmt == NULL) goto Done;
1263
pnew = PyBytes_AsString(newfmt);
1266
while ((ch = *pin++) != '\0') {
1268
ptoappend = pin - 1;
1271
else if ((ch = *pin++) == '\0') {
1272
/* There's a lone trailing %; doesn't make sense. */
1273
PyErr_SetString(PyExc_ValueError, "strftime format "
1277
/* A % has been seen and ch is the character after it. */
1278
else if (ch == 'z') {
1279
if (zreplacement == NULL) {
1280
/* format utcoffset */
1282
PyObject *tzinfo = get_tzinfo_member(object);
1283
zreplacement = PyBytes_FromStringAndSize("", 0);
1284
if (zreplacement == NULL) goto Done;
1285
if (tzinfo != Py_None && tzinfo != NULL) {
1286
assert(tzinfoarg != NULL);
1287
if (format_utcoffset(buf,
1293
Py_DECREF(zreplacement);
1295
PyBytes_FromStringAndSize(buf,
1297
if (zreplacement == NULL)
1301
assert(zreplacement != NULL);
1302
ptoappend = PyBytes_AS_STRING(zreplacement);
1303
ntoappend = PyBytes_GET_SIZE(zreplacement);
1305
else if (ch == 'Z') {
1307
if (Zreplacement == NULL) {
1308
Zreplacement = make_Zreplacement(object,
1310
if (Zreplacement == NULL)
1313
assert(Zreplacement != NULL);
1314
assert(PyUnicode_Check(Zreplacement));
1315
ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
1317
ntoappend = Py_SIZE(Zreplacement);
1319
else if (ch == 'f') {
1320
/* format microseconds */
1321
if (freplacement == NULL) {
1322
freplacement = make_freplacement(object);
1323
if (freplacement == NULL)
1326
assert(freplacement != NULL);
1327
assert(PyBytes_Check(freplacement));
1328
ptoappend = PyBytes_AS_STRING(freplacement);
1329
ntoappend = PyBytes_GET_SIZE(freplacement);
1332
/* percent followed by neither z nor Z */
1333
ptoappend = pin - 2;
1337
/* Append the ntoappend chars starting at ptoappend to
1342
assert(ptoappend != NULL);
1343
assert(ntoappend > 0);
1344
while (usednew + ntoappend > totalnew) {
1345
size_t bigger = totalnew << 1;
1346
if ((bigger >> 1) != totalnew) { /* overflow */
1350
if (_PyBytes_Resize(&newfmt, bigger) < 0)
1353
pnew = PyBytes_AsString(newfmt) + usednew;
1355
memcpy(pnew, ptoappend, ntoappend);
1357
usednew += ntoappend;
1358
assert(usednew <= totalnew);
1361
if (_PyBytes_Resize(&newfmt, usednew) < 0)
1365
PyObject *time = PyImport_ImportModuleNoBlock("time");
1368
format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1369
if (format != NULL) {
1370
result = PyObject_CallMethod(time, "strftime", "OO",
1198
PyObject *result = NULL; /* guilty until proved innocent */
1200
PyObject *zreplacement = NULL; /* py string, replacement for %z */
1201
PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1202
PyObject *freplacement = NULL; /* py string, replacement for %f */
1204
const char *pin; /* pointer to next char in input format */
1205
Py_ssize_t flen; /* length of input format */
1206
char ch; /* next char in input format */
1208
PyObject *newfmt = NULL; /* py string, the output format */
1209
char *pnew; /* pointer to available byte in output format */
1210
size_t totalnew; /* number bytes total in output format buffer,
1211
exclusive of trailing \0 */
1212
size_t usednew; /* number bytes used so far in output format buffer */
1214
const char *ptoappend; /* ptr to string to append to output buffer */
1215
Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
1217
assert(object && format && timetuple);
1218
assert(PyUnicode_Check(format));
1219
/* Convert the input format to a C string and size */
1220
pin = _PyUnicode_AsStringAndSize(format, &flen);
1224
/* Give up if the year is before 1900.
1225
* Python strftime() plays games with the year, and different
1226
* games depending on whether envar PYTHON2K is set. This makes
1227
* years before 1900 a nightmare, even if the platform strftime
1228
* supports them (and not all do).
1229
* We could get a lot farther here by avoiding Python's strftime
1230
* wrapper and calling the C strftime() directly, but that isn't
1231
* an option in the Python implementation of this module.
1235
PyObject *pyyear = PySequence_GetItem(timetuple, 0);
1236
if (pyyear == NULL) return NULL;
1237
assert(PyLong_Check(pyyear));
1238
year = PyLong_AsLong(pyyear);
1241
PyErr_Format(PyExc_ValueError, "year=%ld is before "
1242
"1900; the datetime strftime() "
1243
"methods require year >= 1900",
1249
/* Scan the input format, looking for %z/%Z/%f escapes, building
1250
* a new format. Since computing the replacements for those codes
1251
* is expensive, don't unless they're actually used.
1253
if (flen > INT_MAX - 1) {
1258
totalnew = flen + 1; /* realistic if no %z/%Z */
1259
newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1260
if (newfmt == NULL) goto Done;
1261
pnew = PyBytes_AsString(newfmt);
1264
while ((ch = *pin++) != '\0') {
1266
ptoappend = pin - 1;
1269
else if ((ch = *pin++) == '\0') {
1270
/* There's a lone trailing %; doesn't make sense. */
1271
PyErr_SetString(PyExc_ValueError, "strftime format "
1275
/* A % has been seen and ch is the character after it. */
1276
else if (ch == 'z') {
1277
if (zreplacement == NULL) {
1278
/* format utcoffset */
1280
PyObject *tzinfo = get_tzinfo_member(object);
1281
zreplacement = PyBytes_FromStringAndSize("", 0);
1282
if (zreplacement == NULL) goto Done;
1283
if (tzinfo != Py_None && tzinfo != NULL) {
1284
assert(tzinfoarg != NULL);
1285
if (format_utcoffset(buf,
1291
Py_DECREF(zreplacement);
1293
PyBytes_FromStringAndSize(buf,
1295
if (zreplacement == NULL)
1299
assert(zreplacement != NULL);
1300
ptoappend = PyBytes_AS_STRING(zreplacement);
1301
ntoappend = PyBytes_GET_SIZE(zreplacement);
1303
else if (ch == 'Z') {
1305
if (Zreplacement == NULL) {
1306
Zreplacement = make_Zreplacement(object,
1308
if (Zreplacement == NULL)
1311
assert(Zreplacement != NULL);
1312
assert(PyUnicode_Check(Zreplacement));
1313
ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
1315
ntoappend = Py_SIZE(Zreplacement);
1317
else if (ch == 'f') {
1318
/* format microseconds */
1319
if (freplacement == NULL) {
1320
freplacement = make_freplacement(object);
1321
if (freplacement == NULL)
1324
assert(freplacement != NULL);
1325
assert(PyBytes_Check(freplacement));
1326
ptoappend = PyBytes_AS_STRING(freplacement);
1327
ntoappend = PyBytes_GET_SIZE(freplacement);
1330
/* percent followed by neither z nor Z */
1331
ptoappend = pin - 2;
1335
/* Append the ntoappend chars starting at ptoappend to
1340
assert(ptoappend != NULL);
1341
assert(ntoappend > 0);
1342
while (usednew + ntoappend > totalnew) {
1343
size_t bigger = totalnew << 1;
1344
if ((bigger >> 1) != totalnew) { /* overflow */
1348
if (_PyBytes_Resize(&newfmt, bigger) < 0)
1351
pnew = PyBytes_AsString(newfmt) + usednew;
1353
memcpy(pnew, ptoappend, ntoappend);
1355
usednew += ntoappend;
1356
assert(usednew <= totalnew);
1359
if (_PyBytes_Resize(&newfmt, usednew) < 0)
1363
PyObject *time = PyImport_ImportModuleNoBlock("time");
1366
format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1367
if (format != NULL) {
1368
result = PyObject_CallMethod(time, "strftime", "OO",
1377
Py_XDECREF(freplacement);
1378
Py_XDECREF(zreplacement);
1379
Py_XDECREF(Zreplacement);
1375
Py_XDECREF(freplacement);
1376
Py_XDECREF(zreplacement);
1377
Py_XDECREF(Zreplacement);
1384
1382
/* ---------------------------------------------------------------------------
1544
1542
static PyObject *
1545
1543
microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
1552
PyObject *tuple = NULL;
1553
PyObject *num = NULL;
1554
PyObject *result = NULL;
1556
tuple = PyNumber_Divmod(pyus, us_per_second);
1560
num = PyTuple_GetItem(tuple, 1); /* us */
1563
temp = PyLong_AsLong(num);
1565
if (temp == -1 && PyErr_Occurred())
1567
assert(0 <= temp && temp < 1000000);
1570
/* The divisor was positive, so this must be an error. */
1571
assert(PyErr_Occurred());
1575
num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1581
tuple = PyNumber_Divmod(num, seconds_per_day);
1586
num = PyTuple_GetItem(tuple, 1); /* seconds */
1589
temp = PyLong_AsLong(num);
1591
if (temp == -1 && PyErr_Occurred())
1593
assert(0 <= temp && temp < 24*3600);
1597
/* The divisor was positive, so this must be an error. */
1598
assert(PyErr_Occurred());
1602
num = PyTuple_GetItem(tuple, 0); /* leftover days */
1606
temp = PyLong_AsLong(num);
1607
if (temp == -1 && PyErr_Occurred())
1610
if ((long)d != temp) {
1611
PyErr_SetString(PyExc_OverflowError, "normalized days too "
1612
"large to fit in a C int");
1615
result = new_delta_ex(d, s, us, 0, type);
1550
PyObject *tuple = NULL;
1551
PyObject *num = NULL;
1552
PyObject *result = NULL;
1554
tuple = PyNumber_Divmod(pyus, us_per_second);
1558
num = PyTuple_GetItem(tuple, 1); /* us */
1561
temp = PyLong_AsLong(num);
1563
if (temp == -1 && PyErr_Occurred())
1565
assert(0 <= temp && temp < 1000000);
1568
/* The divisor was positive, so this must be an error. */
1569
assert(PyErr_Occurred());
1573
num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1579
tuple = PyNumber_Divmod(num, seconds_per_day);
1584
num = PyTuple_GetItem(tuple, 1); /* seconds */
1587
temp = PyLong_AsLong(num);
1589
if (temp == -1 && PyErr_Occurred())
1591
assert(0 <= temp && temp < 24*3600);
1595
/* The divisor was positive, so this must be an error. */
1596
assert(PyErr_Occurred());
1600
num = PyTuple_GetItem(tuple, 0); /* leftover days */
1604
temp = PyLong_AsLong(num);
1605
if (temp == -1 && PyErr_Occurred())
1608
if ((long)d != temp) {
1609
PyErr_SetString(PyExc_OverflowError, "normalized days too "
1610
"large to fit in a C int");
1613
result = new_delta_ex(d, s, us, 0, type);
1623
#define microseconds_to_delta(pymicros) \
1624
microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
1621
#define microseconds_to_delta(pymicros) \
1622
microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
1626
1624
static PyObject *
1627
1625
multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1633
pyus_in = delta_to_microseconds(delta);
1634
if (pyus_in == NULL)
1637
pyus_out = PyNumber_Multiply(pyus_in, intobj);
1639
if (pyus_out == NULL)
1642
result = microseconds_to_delta(pyus_out);
1643
Py_DECREF(pyus_out);
1631
pyus_in = delta_to_microseconds(delta);
1632
if (pyus_in == NULL)
1635
pyus_out = PyNumber_Multiply(pyus_in, intobj);
1637
if (pyus_out == NULL)
1640
result = microseconds_to_delta(pyus_out);
1641
Py_DECREF(pyus_out);
1647
1645
static PyObject *
1648
1646
divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1654
pyus_in = delta_to_microseconds(delta);
1655
if (pyus_in == NULL)
1658
pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1660
if (pyus_out == NULL)
1663
result = microseconds_to_delta(pyus_out);
1664
Py_DECREF(pyus_out);
1652
pyus_in = delta_to_microseconds(delta);
1653
if (pyus_in == NULL)
1656
pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1658
if (pyus_out == NULL)
1661
result = microseconds_to_delta(pyus_out);
1662
Py_DECREF(pyus_out);
1668
1666
static PyObject *
1669
1667
delta_add(PyObject *left, PyObject *right)
1671
PyObject *result = Py_NotImplemented;
1673
if (PyDelta_Check(left) && PyDelta_Check(right)) {
1675
/* The C-level additions can't overflow because of the
1678
int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1679
int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1680
int microseconds = GET_TD_MICROSECONDS(left) +
1681
GET_TD_MICROSECONDS(right);
1682
result = new_delta(days, seconds, microseconds, 1);
1685
if (result == Py_NotImplemented)
1669
PyObject *result = Py_NotImplemented;
1671
if (PyDelta_Check(left) && PyDelta_Check(right)) {
1673
/* The C-level additions can't overflow because of the
1676
int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1677
int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1678
int microseconds = GET_TD_MICROSECONDS(left) +
1679
GET_TD_MICROSECONDS(right);
1680
result = new_delta(days, seconds, microseconds, 1);
1683
if (result == Py_NotImplemented)
1690
1688
static PyObject *
1691
1689
delta_negative(PyDateTime_Delta *self)
1693
return new_delta(-GET_TD_DAYS(self),
1694
-GET_TD_SECONDS(self),
1695
-GET_TD_MICROSECONDS(self),
1691
return new_delta(-GET_TD_DAYS(self),
1692
-GET_TD_SECONDS(self),
1693
-GET_TD_MICROSECONDS(self),
1699
1697
static PyObject *
1700
1698
delta_positive(PyDateTime_Delta *self)
1702
/* Could optimize this (by returning self) if this isn't a
1703
* subclass -- but who uses unary + ? Approximately nobody.
1705
return new_delta(GET_TD_DAYS(self),
1706
GET_TD_SECONDS(self),
1707
GET_TD_MICROSECONDS(self),
1700
/* Could optimize this (by returning self) if this isn't a
1701
* subclass -- but who uses unary + ? Approximately nobody.
1703
return new_delta(GET_TD_DAYS(self),
1704
GET_TD_SECONDS(self),
1705
GET_TD_MICROSECONDS(self),
1711
1709
static PyObject *
1712
1710
delta_abs(PyDateTime_Delta *self)
1716
assert(GET_TD_MICROSECONDS(self) >= 0);
1717
assert(GET_TD_SECONDS(self) >= 0);
1719
if (GET_TD_DAYS(self) < 0)
1720
result = delta_negative(self);
1722
result = delta_positive(self);
1714
assert(GET_TD_MICROSECONDS(self) >= 0);
1715
assert(GET_TD_SECONDS(self) >= 0);
1717
if (GET_TD_DAYS(self) < 0)
1718
result = delta_negative(self);
1720
result = delta_positive(self);
1727
1725
static PyObject *
1728
1726
delta_subtract(PyObject *left, PyObject *right)
1730
PyObject *result = Py_NotImplemented;
1732
if (PyDelta_Check(left) && PyDelta_Check(right)) {
1734
PyObject *minus_right = PyNumber_Negative(right);
1736
result = delta_add(left, minus_right);
1737
Py_DECREF(minus_right);
1743
if (result == Py_NotImplemented)
1728
PyObject *result = Py_NotImplemented;
1730
if (PyDelta_Check(left) && PyDelta_Check(right)) {
1732
PyObject *minus_right = PyNumber_Negative(right);
1734
result = delta_add(left, minus_right);
1735
Py_DECREF(minus_right);
1741
if (result == Py_NotImplemented)
1748
1746
static PyObject *
1749
1747
delta_richcompare(PyObject *self, PyObject *other, int op)
1751
if (PyDelta_Check(other)) {
1752
int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1754
diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1756
diff = GET_TD_MICROSECONDS(self) -
1757
GET_TD_MICROSECONDS(other);
1759
return diff_to_bool(diff, op);
1762
Py_INCREF(Py_NotImplemented);
1763
return Py_NotImplemented;
1749
if (PyDelta_Check(other)) {
1750
int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1752
diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1754
diff = GET_TD_MICROSECONDS(self) -
1755
GET_TD_MICROSECONDS(other);
1757
return diff_to_bool(diff, op);
1760
Py_INCREF(Py_NotImplemented);
1761
return Py_NotImplemented;
1767
1765
static PyObject *delta_getstate(PyDateTime_Delta *self);
1830
1828
accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1831
1829
double *leftover)
1836
assert(num != NULL);
1838
if (PyLong_Check(num)) {
1839
prod = PyNumber_Multiply(num, factor);
1842
sum = PyNumber_Add(sofar, prod);
1847
if (PyFloat_Check(num)) {
1854
/* The Plan: decompose num into an integer part and a
1855
* fractional part, num = intpart + fracpart.
1856
* Then num * factor ==
1857
* intpart * factor + fracpart * factor
1858
* and the LHS can be computed exactly in long arithmetic.
1859
* The RHS is again broken into an int part and frac part.
1860
* and the frac part is added into *leftover.
1862
dnum = PyFloat_AsDouble(num);
1863
if (dnum == -1.0 && PyErr_Occurred())
1865
fracpart = modf(dnum, &intpart);
1866
x = PyLong_FromDouble(intpart);
1870
prod = PyNumber_Multiply(x, factor);
1875
sum = PyNumber_Add(sofar, prod);
1880
if (fracpart == 0.0)
1882
/* So far we've lost no information. Dealing with the
1883
* fractional part requires float arithmetic, and may
1884
* lose a little info.
1886
assert(PyLong_Check(factor));
1887
dnum = PyLong_AsDouble(factor);
1890
fracpart = modf(dnum, &intpart);
1891
x = PyLong_FromDouble(intpart);
1897
y = PyNumber_Add(sum, x);
1900
*leftover += fracpart;
1904
PyErr_Format(PyExc_TypeError,
1905
"unsupported type for timedelta %s component: %s",
1906
tag, Py_TYPE(num)->tp_name);
1834
assert(num != NULL);
1836
if (PyLong_Check(num)) {
1837
prod = PyNumber_Multiply(num, factor);
1840
sum = PyNumber_Add(sofar, prod);
1845
if (PyFloat_Check(num)) {
1852
/* The Plan: decompose num into an integer part and a
1853
* fractional part, num = intpart + fracpart.
1854
* Then num * factor ==
1855
* intpart * factor + fracpart * factor
1856
* and the LHS can be computed exactly in long arithmetic.
1857
* The RHS is again broken into an int part and frac part.
1858
* and the frac part is added into *leftover.
1860
dnum = PyFloat_AsDouble(num);
1861
if (dnum == -1.0 && PyErr_Occurred())
1863
fracpart = modf(dnum, &intpart);
1864
x = PyLong_FromDouble(intpart);
1868
prod = PyNumber_Multiply(x, factor);
1873
sum = PyNumber_Add(sofar, prod);
1878
if (fracpart == 0.0)
1880
/* So far we've lost no information. Dealing with the
1881
* fractional part requires float arithmetic, and may
1882
* lose a little info.
1884
assert(PyLong_Check(factor));
1885
dnum = PyLong_AsDouble(factor);
1888
fracpart = modf(dnum, &intpart);
1889
x = PyLong_FromDouble(intpart);
1895
y = PyNumber_Add(sum, x);
1898
*leftover += fracpart;
1902
PyErr_Format(PyExc_TypeError,
1903
"unsupported type for timedelta %s component: %s",
1904
tag, Py_TYPE(num)->tp_name);
1910
1908
static PyObject *
1911
1909
delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1913
PyObject *self = NULL;
1915
/* Argument objects. */
1916
PyObject *day = NULL;
1917
PyObject *second = NULL;
1918
PyObject *us = NULL;
1919
PyObject *ms = NULL;
1920
PyObject *minute = NULL;
1921
PyObject *hour = NULL;
1922
PyObject *week = NULL;
1924
PyObject *x = NULL; /* running sum of microseconds */
1925
PyObject *y = NULL; /* temp sum of microseconds */
1926
double leftover_us = 0.0;
1928
static char *keywords[] = {
1929
"days", "seconds", "microseconds", "milliseconds",
1930
"minutes", "hours", "weeks", NULL
1933
if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1936
&ms, &minute, &hour, &week) == 0)
1939
x = PyLong_FromLong(0);
1950
y = accum("microseconds", x, us, us_per_us, &leftover_us);
1954
y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1958
y = accum("seconds", x, second, us_per_second, &leftover_us);
1962
y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1966
y = accum("hours", x, hour, us_per_hour, &leftover_us);
1970
y = accum("days", x, day, us_per_day, &leftover_us);
1974
y = accum("weeks", x, week, us_per_week, &leftover_us);
1978
/* Round to nearest whole # of us, and add into x. */
1979
PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
1984
y = PyNumber_Add(x, temp);
1989
self = microseconds_to_delta_ex(x, type);
1911
PyObject *self = NULL;
1913
/* Argument objects. */
1914
PyObject *day = NULL;
1915
PyObject *second = NULL;
1916
PyObject *us = NULL;
1917
PyObject *ms = NULL;
1918
PyObject *minute = NULL;
1919
PyObject *hour = NULL;
1920
PyObject *week = NULL;
1922
PyObject *x = NULL; /* running sum of microseconds */
1923
PyObject *y = NULL; /* temp sum of microseconds */
1924
double leftover_us = 0.0;
1926
static char *keywords[] = {
1927
"days", "seconds", "microseconds", "milliseconds",
1928
"minutes", "hours", "weeks", NULL
1931
if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1934
&ms, &minute, &hour, &week) == 0)
1937
x = PyLong_FromLong(0);
1948
y = accum("microseconds", x, us, us_per_us, &leftover_us);
1952
y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1956
y = accum("seconds", x, second, us_per_second, &leftover_us);
1960
y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1964
y = accum("hours", x, hour, us_per_hour, &leftover_us);
1968
y = accum("days", x, day, us_per_day, &leftover_us);
1972
y = accum("weeks", x, week, us_per_week, &leftover_us);
1976
/* Round to nearest whole # of us, and add into x. */
1977
PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
1982
y = PyNumber_Add(x, temp);
1987
self = microseconds_to_delta_ex(x, type);
1998
1996
delta_bool(PyDateTime_Delta *self)
2000
return (GET_TD_DAYS(self) != 0
2001
|| GET_TD_SECONDS(self) != 0
2002
|| GET_TD_MICROSECONDS(self) != 0);
1998
return (GET_TD_DAYS(self) != 0
1999
|| GET_TD_SECONDS(self) != 0
2000
|| GET_TD_MICROSECONDS(self) != 0);
2005
2003
static PyObject *
2006
2004
delta_repr(PyDateTime_Delta *self)
2008
if (GET_TD_MICROSECONDS(self) != 0)
2009
return PyUnicode_FromFormat("%s(%d, %d, %d)",
2010
Py_TYPE(self)->tp_name,
2012
GET_TD_SECONDS(self),
2013
GET_TD_MICROSECONDS(self));
2014
if (GET_TD_SECONDS(self) != 0)
2015
return PyUnicode_FromFormat("%s(%d, %d)",
2016
Py_TYPE(self)->tp_name,
2018
GET_TD_SECONDS(self));
2006
if (GET_TD_MICROSECONDS(self) != 0)
2007
return PyUnicode_FromFormat("%s(%d, %d, %d)",
2008
Py_TYPE(self)->tp_name,
2010
GET_TD_SECONDS(self),
2011
GET_TD_MICROSECONDS(self));
2012
if (GET_TD_SECONDS(self) != 0)
2013
return PyUnicode_FromFormat("%s(%d, %d)",
2014
Py_TYPE(self)->tp_name,
2016
GET_TD_SECONDS(self));
2020
return PyUnicode_FromFormat("%s(%d)",
2021
Py_TYPE(self)->tp_name,
2018
return PyUnicode_FromFormat("%s(%d)",
2019
Py_TYPE(self)->tp_name,
2025
2023
static PyObject *
2026
2024
delta_str(PyDateTime_Delta *self)
2028
int us = GET_TD_MICROSECONDS(self);
2029
int seconds = GET_TD_SECONDS(self);
2030
int minutes = divmod(seconds, 60, &seconds);
2031
int hours = divmod(minutes, 60, &minutes);
2032
int days = GET_TD_DAYS(self);
2026
int us = GET_TD_MICROSECONDS(self);
2027
int seconds = GET_TD_SECONDS(self);
2028
int minutes = divmod(seconds, 60, &seconds);
2029
int hours = divmod(minutes, 60, &minutes);
2030
int days = GET_TD_DAYS(self);
2036
return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2037
days, (days == 1 || days == -1) ? "" : "s",
2038
hours, minutes, seconds, us);
2040
return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2041
days, (days == 1 || days == -1) ? "" : "s",
2042
hours, minutes, seconds);
2045
return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2046
hours, minutes, seconds, us);
2048
return PyUnicode_FromFormat("%d:%02d:%02d",
2049
hours, minutes, seconds);
2034
return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2035
days, (days == 1 || days == -1) ? "" : "s",
2036
hours, minutes, seconds, us);
2038
return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2039
days, (days == 1 || days == -1) ? "" : "s",
2040
hours, minutes, seconds);
2043
return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2044
hours, minutes, seconds, us);
2046
return PyUnicode_FromFormat("%d:%02d:%02d",
2047
hours, minutes, seconds);
2057
2055
static PyObject *
2058
2056
delta_getstate(PyDateTime_Delta *self)
2060
return Py_BuildValue("iii", GET_TD_DAYS(self),
2061
GET_TD_SECONDS(self),
2062
GET_TD_MICROSECONDS(self));
2058
return Py_BuildValue("iii", GET_TD_DAYS(self),
2059
GET_TD_SECONDS(self),
2060
GET_TD_MICROSECONDS(self));
2065
2063
static PyObject *
2066
2064
delta_reduce(PyDateTime_Delta* self)
2068
return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
2066
return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
2071
2069
#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2073
2071
static PyMemberDef delta_members[] = {
2075
{"days", T_INT, OFFSET(days), READONLY,
2076
PyDoc_STR("Number of days.")},
2078
{"seconds", T_INT, OFFSET(seconds), READONLY,
2079
PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
2081
{"microseconds", T_INT, OFFSET(microseconds), READONLY,
2082
PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2073
{"days", T_INT, OFFSET(days), READONLY,
2074
PyDoc_STR("Number of days.")},
2076
{"seconds", T_INT, OFFSET(seconds), READONLY,
2077
PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
2079
{"microseconds", T_INT, OFFSET(microseconds), READONLY,
2080
PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2086
2084
static PyMethodDef delta_methods[] = {
2087
{"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2088
PyDoc_STR("__reduce__() -> (cls, state)")},
2085
{"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2086
PyDoc_STR("__reduce__() -> (cls, state)")},
2093
2091
static char delta_doc[] =
2094
2092
PyDoc_STR("Difference between two datetime values.");
2096
2094
static PyNumberMethods delta_as_number = {
2097
delta_add, /* nb_add */
2098
delta_subtract, /* nb_subtract */
2099
delta_multiply, /* nb_multiply */
2100
0, /* nb_remainder */
2103
(unaryfunc)delta_negative, /* nb_negative */
2104
(unaryfunc)delta_positive, /* nb_positive */
2105
(unaryfunc)delta_abs, /* nb_absolute */
2106
(inquiry)delta_bool, /* nb_bool */
2116
0, /*nb_inplace_add*/
2117
0, /*nb_inplace_subtract*/
2118
0, /*nb_inplace_multiply*/
2119
0, /*nb_inplace_remainder*/
2120
0, /*nb_inplace_power*/
2121
0, /*nb_inplace_lshift*/
2122
0, /*nb_inplace_rshift*/
2123
0, /*nb_inplace_and*/
2124
0, /*nb_inplace_xor*/
2125
0, /*nb_inplace_or*/
2126
delta_divide, /* nb_floor_divide */
2127
0, /* nb_true_divide */
2128
0, /* nb_inplace_floor_divide */
2129
0, /* nb_inplace_true_divide */
2095
delta_add, /* nb_add */
2096
delta_subtract, /* nb_subtract */
2097
delta_multiply, /* nb_multiply */
2098
0, /* nb_remainder */
2101
(unaryfunc)delta_negative, /* nb_negative */
2102
(unaryfunc)delta_positive, /* nb_positive */
2103
(unaryfunc)delta_abs, /* nb_absolute */
2104
(inquiry)delta_bool, /* nb_bool */
2114
0, /*nb_inplace_add*/
2115
0, /*nb_inplace_subtract*/
2116
0, /*nb_inplace_multiply*/
2117
0, /*nb_inplace_remainder*/
2118
0, /*nb_inplace_power*/
2119
0, /*nb_inplace_lshift*/
2120
0, /*nb_inplace_rshift*/
2121
0, /*nb_inplace_and*/
2122
0, /*nb_inplace_xor*/
2123
0, /*nb_inplace_or*/
2124
delta_divide, /* nb_floor_divide */
2125
0, /* nb_true_divide */
2126
0, /* nb_inplace_floor_divide */
2127
0, /* nb_inplace_true_divide */
2132
2130
static PyTypeObject PyDateTime_DeltaType = {
2133
PyVarObject_HEAD_INIT(NULL, 0)
2134
"datetime.timedelta", /* tp_name */
2135
sizeof(PyDateTime_Delta), /* tp_basicsize */
2136
0, /* tp_itemsize */
2141
0, /* tp_reserved */
2142
(reprfunc)delta_repr, /* tp_repr */
2143
&delta_as_number, /* tp_as_number */
2144
0, /* tp_as_sequence */
2145
0, /* tp_as_mapping */
2146
(hashfunc)delta_hash, /* tp_hash */
2148
(reprfunc)delta_str, /* tp_str */
2149
PyObject_GenericGetAttr, /* tp_getattro */
2150
0, /* tp_setattro */
2151
0, /* tp_as_buffer */
2152
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2153
delta_doc, /* tp_doc */
2154
0, /* tp_traverse */
2156
delta_richcompare, /* tp_richcompare */
2157
0, /* tp_weaklistoffset */
2159
0, /* tp_iternext */
2160
delta_methods, /* tp_methods */
2161
delta_members, /* tp_members */
2165
0, /* tp_descr_get */
2166
0, /* tp_descr_set */
2167
0, /* tp_dictoffset */
2170
delta_new, /* tp_new */
2131
PyVarObject_HEAD_INIT(NULL, 0)
2132
"datetime.timedelta", /* tp_name */
2133
sizeof(PyDateTime_Delta), /* tp_basicsize */
2134
0, /* tp_itemsize */
2139
0, /* tp_reserved */
2140
(reprfunc)delta_repr, /* tp_repr */
2141
&delta_as_number, /* tp_as_number */
2142
0, /* tp_as_sequence */
2143
0, /* tp_as_mapping */
2144
(hashfunc)delta_hash, /* tp_hash */
2146
(reprfunc)delta_str, /* tp_str */
2147
PyObject_GenericGetAttr, /* tp_getattro */
2148
0, /* tp_setattro */
2149
0, /* tp_as_buffer */
2150
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2151
delta_doc, /* tp_doc */
2152
0, /* tp_traverse */
2154
delta_richcompare, /* tp_richcompare */
2155
0, /* tp_weaklistoffset */
2157
0, /* tp_iternext */
2158
delta_methods, /* tp_methods */
2159
delta_members, /* tp_members */
2163
0, /* tp_descr_get */
2164
0, /* tp_descr_set */
2165
0, /* tp_dictoffset */
2168
delta_new, /* tp_new */
2339
2337
static PyObject *
2340
2338
add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2342
PyObject *result = NULL;
2343
int year = GET_YEAR(date);
2344
int month = GET_MONTH(date);
2345
int deltadays = GET_TD_DAYS(delta);
2346
/* C-level overflow is impossible because |deltadays| < 1e9. */
2347
int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
2340
PyObject *result = NULL;
2341
int year = GET_YEAR(date);
2342
int month = GET_MONTH(date);
2343
int deltadays = GET_TD_DAYS(delta);
2344
/* C-level overflow is impossible because |deltadays| < 1e9. */
2345
int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
2349
if (normalize_date(&year, &month, &day) >= 0)
2350
result = new_date(year, month, day);
2347
if (normalize_date(&year, &month, &day) >= 0)
2348
result = new_date(year, month, day);
2354
2352
static PyObject *
2355
2353
date_add(PyObject *left, PyObject *right)
2357
if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2358
Py_INCREF(Py_NotImplemented);
2359
return Py_NotImplemented;
2361
if (PyDate_Check(left)) {
2363
if (PyDelta_Check(right))
2365
return add_date_timedelta((PyDateTime_Date *) left,
2366
(PyDateTime_Delta *) right,
2371
* 'right' must be one of us, or we wouldn't have been called
2373
if (PyDelta_Check(left))
2375
return add_date_timedelta((PyDateTime_Date *) right,
2376
(PyDateTime_Delta *) left,
2379
Py_INCREF(Py_NotImplemented);
2380
return Py_NotImplemented;
2355
if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2356
Py_INCREF(Py_NotImplemented);
2357
return Py_NotImplemented;
2359
if (PyDate_Check(left)) {
2361
if (PyDelta_Check(right))
2363
return add_date_timedelta((PyDateTime_Date *) left,
2364
(PyDateTime_Delta *) right,
2369
* 'right' must be one of us, or we wouldn't have been called
2371
if (PyDelta_Check(left))
2373
return add_date_timedelta((PyDateTime_Date *) right,
2374
(PyDateTime_Delta *) left,
2377
Py_INCREF(Py_NotImplemented);
2378
return Py_NotImplemented;
2383
2381
static PyObject *
2384
2382
date_subtract(PyObject *left, PyObject *right)
2386
if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2387
Py_INCREF(Py_NotImplemented);
2388
return Py_NotImplemented;
2390
if (PyDate_Check(left)) {
2391
if (PyDate_Check(right)) {
2393
int left_ord = ymd_to_ord(GET_YEAR(left),
2396
int right_ord = ymd_to_ord(GET_YEAR(right),
2399
return new_delta(left_ord - right_ord, 0, 0, 0);
2401
if (PyDelta_Check(right)) {
2403
return add_date_timedelta((PyDateTime_Date *) left,
2404
(PyDateTime_Delta *) right,
2408
Py_INCREF(Py_NotImplemented);
2409
return Py_NotImplemented;
2384
if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2385
Py_INCREF(Py_NotImplemented);
2386
return Py_NotImplemented;
2388
if (PyDate_Check(left)) {
2389
if (PyDate_Check(right)) {
2391
int left_ord = ymd_to_ord(GET_YEAR(left),
2394
int right_ord = ymd_to_ord(GET_YEAR(right),
2397
return new_delta(left_ord - right_ord, 0, 0, 0);
2399
if (PyDelta_Check(right)) {
2401
return add_date_timedelta((PyDateTime_Date *) left,
2402
(PyDateTime_Delta *) right,
2406
Py_INCREF(Py_NotImplemented);
2407
return Py_NotImplemented;
2415
2413
static PyObject *
2416
2414
date_repr(PyDateTime_Date *self)
2418
return PyUnicode_FromFormat("%s(%d, %d, %d)",
2419
Py_TYPE(self)->tp_name,
2420
GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2416
return PyUnicode_FromFormat("%s(%d, %d, %d)",
2417
Py_TYPE(self)->tp_name,
2418
GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2423
2421
static PyObject *
2424
2422
date_isoformat(PyDateTime_Date *self)
2426
return PyUnicode_FromFormat("%04d-%02d-%02d",
2427
GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2424
return PyUnicode_FromFormat("%04d-%02d-%02d",
2425
GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2430
2428
/* str() calls the appropriate isoformat() method. */
2431
2429
static PyObject *
2432
2430
date_str(PyDateTime_Date *self)
2434
return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
2432
return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
2438
2436
static PyObject *
2439
2437
date_ctime(PyDateTime_Date *self)
2441
return format_ctime(self, 0, 0, 0);
2439
return format_ctime(self, 0, 0, 0);
2444
2442
static PyObject *
2445
2443
date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2447
/* This method can be inherited, and needs to call the
2448
* timetuple() method appropriate to self's class.
2453
static char *keywords[] = {"format", NULL};
2455
if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2459
tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2462
result = wrap_strftime((PyObject *)self, format, tuple,
2445
/* This method can be inherited, and needs to call the
2446
* timetuple() method appropriate to self's class.
2451
static char *keywords[] = {"format", NULL};
2453
if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2457
tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2460
result = wrap_strftime((PyObject *)self, format, tuple,
2468
2466
static PyObject *
2469
2467
date_format(PyDateTime_Date *self, PyObject *args)
2473
if (!PyArg_ParseTuple(args, "U:__format__", &format))
2476
/* if the format is zero length, return str(self) */
2477
if (PyUnicode_GetSize(format) == 0)
2478
return PyObject_Str((PyObject *)self);
2480
return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
2471
if (!PyArg_ParseTuple(args, "U:__format__", &format))
2474
/* if the format is zero length, return str(self) */
2475
if (PyUnicode_GetSize(format) == 0)
2476
return PyObject_Str((PyObject *)self);
2478
return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
2483
2481
/* ISO methods. */
2612
2610
static PyObject *
2613
2611
date_getstate(PyDateTime_Date *self)
2616
field = PyBytes_FromStringAndSize((char*)self->data,
2617
_PyDateTime_DATE_DATASIZE);
2618
return Py_BuildValue("(N)", field);
2614
field = PyBytes_FromStringAndSize((char*)self->data,
2615
_PyDateTime_DATE_DATASIZE);
2616
return Py_BuildValue("(N)", field);
2621
2619
static PyObject *
2622
2620
date_reduce(PyDateTime_Date *self, PyObject *arg)
2624
return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
2622
return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
2627
2625
static PyMethodDef date_methods[] = {
2629
/* Class methods: */
2631
{"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2633
PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2636
{"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2638
PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2641
{"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2642
PyDoc_STR("Current date or datetime: same as "
2643
"self.__class__.fromtimestamp(time.time()).")},
2645
/* Instance methods: */
2647
{"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2648
PyDoc_STR("Return ctime() style string.")},
2650
{"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2651
PyDoc_STR("format -> strftime() style string.")},
2653
{"__format__", (PyCFunction)date_format, METH_VARARGS,
2654
PyDoc_STR("Formats self with strftime.")},
2656
{"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2657
PyDoc_STR("Return time tuple, compatible with time.localtime().")},
2659
{"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2660
PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2663
{"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2664
PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
2666
{"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2667
PyDoc_STR("Return the day of the week represented by the date.\n"
2668
"Monday == 1 ... Sunday == 7")},
2670
{"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2671
PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2674
{"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2675
PyDoc_STR("Return the day of the week represented by the date.\n"
2676
"Monday == 0 ... Sunday == 6")},
2678
{"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2679
PyDoc_STR("Return date with new specified fields.")},
2681
{"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2682
PyDoc_STR("__reduce__() -> (cls, state)")},
2627
/* Class methods: */
2629
{"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2631
PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2634
{"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2636
PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2639
{"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2640
PyDoc_STR("Current date or datetime: same as "
2641
"self.__class__.fromtimestamp(time.time()).")},
2643
/* Instance methods: */
2645
{"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2646
PyDoc_STR("Return ctime() style string.")},
2648
{"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2649
PyDoc_STR("format -> strftime() style string.")},
2651
{"__format__", (PyCFunction)date_format, METH_VARARGS,
2652
PyDoc_STR("Formats self with strftime.")},
2654
{"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2655
PyDoc_STR("Return time tuple, compatible with time.localtime().")},
2657
{"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2658
PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2661
{"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2662
PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
2664
{"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2665
PyDoc_STR("Return the day of the week represented by the date.\n"
2666
"Monday == 1 ... Sunday == 7")},
2668
{"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2669
PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2672
{"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2673
PyDoc_STR("Return the day of the week represented by the date.\n"
2674
"Monday == 0 ... Sunday == 6")},
2676
{"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2677
PyDoc_STR("Return date with new specified fields.")},
2679
{"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2680
PyDoc_STR("__reduce__() -> (cls, state)")},
2687
2685
static char date_doc[] =
2688
2686
PyDoc_STR("date(year, month, day) --> date object");
2690
2688
static PyNumberMethods date_as_number = {
2691
date_add, /* nb_add */
2692
date_subtract, /* nb_subtract */
2693
0, /* nb_multiply */
2694
0, /* nb_remainder */
2697
0, /* nb_negative */
2698
0, /* nb_positive */
2699
0, /* nb_absolute */
2689
date_add, /* nb_add */
2690
date_subtract, /* nb_subtract */
2691
0, /* nb_multiply */
2692
0, /* nb_remainder */
2695
0, /* nb_negative */
2696
0, /* nb_positive */
2697
0, /* nb_absolute */
2703
2701
static PyTypeObject PyDateTime_DateType = {
2704
PyVarObject_HEAD_INIT(NULL, 0)
2705
"datetime.date", /* tp_name */
2706
sizeof(PyDateTime_Date), /* tp_basicsize */
2707
0, /* tp_itemsize */
2712
0, /* tp_reserved */
2713
(reprfunc)date_repr, /* tp_repr */
2714
&date_as_number, /* tp_as_number */
2715
0, /* tp_as_sequence */
2716
0, /* tp_as_mapping */
2717
(hashfunc)date_hash, /* tp_hash */
2719
(reprfunc)date_str, /* tp_str */
2720
PyObject_GenericGetAttr, /* tp_getattro */
2721
0, /* tp_setattro */
2722
0, /* tp_as_buffer */
2723
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2724
date_doc, /* tp_doc */
2725
0, /* tp_traverse */
2727
date_richcompare, /* tp_richcompare */
2728
0, /* tp_weaklistoffset */
2730
0, /* tp_iternext */
2731
date_methods, /* tp_methods */
2733
date_getset, /* tp_getset */
2736
0, /* tp_descr_get */
2737
0, /* tp_descr_set */
2738
0, /* tp_dictoffset */
2741
date_new, /* tp_new */
2702
PyVarObject_HEAD_INIT(NULL, 0)
2703
"datetime.date", /* tp_name */
2704
sizeof(PyDateTime_Date), /* tp_basicsize */
2705
0, /* tp_itemsize */
2710
0, /* tp_reserved */
2711
(reprfunc)date_repr, /* tp_repr */
2712
&date_as_number, /* tp_as_number */
2713
0, /* tp_as_sequence */
2714
0, /* tp_as_mapping */
2715
(hashfunc)date_hash, /* tp_hash */
2717
(reprfunc)date_str, /* tp_str */
2718
PyObject_GenericGetAttr, /* tp_getattro */
2719
0, /* tp_setattro */
2720
0, /* tp_as_buffer */
2721
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2722
date_doc, /* tp_doc */
2723
0, /* tp_traverse */
2725
date_richcompare, /* tp_richcompare */
2726
0, /* tp_weaklistoffset */
2728
0, /* tp_iternext */
2729
date_methods, /* tp_methods */
2731
date_getset, /* tp_getset */
2734
0, /* tp_descr_get */
2735
0, /* tp_descr_set */
2736
0, /* tp_dictoffset */
2739
date_new, /* tp_new */
2773
2771
static PyObject *
2774
2772
tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2776
return tzinfo_nogo("tzname");
2774
return tzinfo_nogo("tzname");
2779
2777
static PyObject *
2780
2778
tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2782
return tzinfo_nogo("utcoffset");
2780
return tzinfo_nogo("utcoffset");
2785
2783
static PyObject *
2786
2784
tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2788
return tzinfo_nogo("dst");
2786
return tzinfo_nogo("dst");
2791
2789
static PyObject *
2792
2790
tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
2794
int y, m, d, hh, mm, ss, us;
2801
if (! PyDateTime_Check(dt)) {
2802
PyErr_SetString(PyExc_TypeError,
2803
"fromutc: argument must be a datetime");
2806
if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
2807
PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2812
off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
2813
if (off == -1 && PyErr_Occurred())
2816
PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2817
"utcoffset() result required");
2821
dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
2822
if (dst == -1 && PyErr_Occurred())
2825
PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2826
"dst() result required");
2833
hh = DATE_GET_HOUR(dt);
2834
mm = DATE_GET_MINUTE(dt);
2835
ss = DATE_GET_SECOND(dt);
2836
us = DATE_GET_MICROSECOND(dt);
2840
if ((mm < 0 || mm >= 60) &&
2841
normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2843
result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2847
dst = call_dst(dt->tzinfo, result, &none);
2848
if (dst == -1 && PyErr_Occurred())
2856
if ((mm < 0 || mm >= 60) &&
2857
normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2860
result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2792
int y, m, d, hh, mm, ss, us;
2799
if (! PyDateTime_Check(dt)) {
2800
PyErr_SetString(PyExc_TypeError,
2801
"fromutc: argument must be a datetime");
2804
if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
2805
PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2810
off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
2811
if (off == -1 && PyErr_Occurred())
2814
PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2815
"utcoffset() result required");
2819
dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
2820
if (dst == -1 && PyErr_Occurred())
2823
PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2824
"dst() result required");
2831
hh = DATE_GET_HOUR(dt);
2832
mm = DATE_GET_MINUTE(dt);
2833
ss = DATE_GET_SECOND(dt);
2834
us = DATE_GET_MICROSECOND(dt);
2838
if ((mm < 0 || mm >= 60) &&
2839
normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2841
result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2845
dst = call_dst(dt->tzinfo, result, &none);
2846
if (dst == -1 && PyErr_Occurred())
2854
if ((mm < 0 || mm >= 60) &&
2855
normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2858
result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2864
PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
2865
"inconsistent results; cannot convert");
2862
PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
2863
"inconsistent results; cannot convert");
2867
/* fall thru to failure */
2865
/* fall thru to failure */
2878
2876
static PyObject *
2879
2877
tzinfo_reduce(PyObject *self)
2881
PyObject *args, *state, *tmp;
2882
PyObject *getinitargs, *getstate;
2884
tmp = PyTuple_New(0);
2888
getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
2889
if (getinitargs != NULL) {
2890
args = PyObject_CallObject(getinitargs, tmp);
2891
Py_DECREF(getinitargs);
2903
getstate = PyObject_GetAttrString(self, "__getstate__");
2904
if (getstate != NULL) {
2905
state = PyObject_CallObject(getstate, tmp);
2906
Py_DECREF(getstate);
2907
if (state == NULL) {
2917
dictptr = _PyObject_GetDictPtr(self);
2918
if (dictptr && *dictptr && PyDict_Size(*dictptr))
2925
if (state == Py_None) {
2927
return Py_BuildValue("(ON)", Py_TYPE(self), args);
2930
return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
2879
PyObject *args, *state, *tmp;
2880
PyObject *getinitargs, *getstate;
2882
tmp = PyTuple_New(0);
2886
getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
2887
if (getinitargs != NULL) {
2888
args = PyObject_CallObject(getinitargs, tmp);
2889
Py_DECREF(getinitargs);
2901
getstate = PyObject_GetAttrString(self, "__getstate__");
2902
if (getstate != NULL) {
2903
state = PyObject_CallObject(getstate, tmp);
2904
Py_DECREF(getstate);
2905
if (state == NULL) {
2915
dictptr = _PyObject_GetDictPtr(self);
2916
if (dictptr && *dictptr && PyDict_Size(*dictptr))
2923
if (state == Py_None) {
2925
return Py_BuildValue("(ON)", Py_TYPE(self), args);
2928
return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
2933
2931
static PyMethodDef tzinfo_methods[] = {
2935
{"tzname", (PyCFunction)tzinfo_tzname, METH_O,
2936
PyDoc_STR("datetime -> string name of time zone.")},
2938
{"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
2939
PyDoc_STR("datetime -> minutes east of UTC (negative for "
2942
{"dst", (PyCFunction)tzinfo_dst, METH_O,
2943
PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
2945
{"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
2946
PyDoc_STR("datetime in UTC -> datetime in local time.")},
2948
{"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
2949
PyDoc_STR("-> (cls, state)")},
2933
{"tzname", (PyCFunction)tzinfo_tzname, METH_O,
2934
PyDoc_STR("datetime -> string name of time zone.")},
2936
{"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
2937
PyDoc_STR("datetime -> minutes east of UTC (negative for "
2940
{"dst", (PyCFunction)tzinfo_dst, METH_O,
2941
PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
2943
{"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
2944
PyDoc_STR("datetime in UTC -> datetime in local time.")},
2946
{"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
2947
PyDoc_STR("-> (cls, state)")},
2954
2952
static char tzinfo_doc[] =
2955
2953
PyDoc_STR("Abstract base class for time zone info objects.");
2957
2955
static PyTypeObject PyDateTime_TZInfoType = {
2958
PyVarObject_HEAD_INIT(NULL, 0)
2959
"datetime.tzinfo", /* tp_name */
2960
sizeof(PyDateTime_TZInfo), /* tp_basicsize */
2961
0, /* tp_itemsize */
2966
0, /* tp_reserved */
2968
0, /* tp_as_number */
2969
0, /* tp_as_sequence */
2970
0, /* tp_as_mapping */
2974
PyObject_GenericGetAttr, /* tp_getattro */
2975
0, /* tp_setattro */
2976
0, /* tp_as_buffer */
2977
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2978
tzinfo_doc, /* tp_doc */
2979
0, /* tp_traverse */
2981
0, /* tp_richcompare */
2982
0, /* tp_weaklistoffset */
2984
0, /* tp_iternext */
2985
tzinfo_methods, /* tp_methods */
2990
0, /* tp_descr_get */
2991
0, /* tp_descr_set */
2992
0, /* tp_dictoffset */
2995
PyType_GenericNew, /* tp_new */
2956
PyVarObject_HEAD_INIT(NULL, 0)
2957
"datetime.tzinfo", /* tp_name */
2958
sizeof(PyDateTime_TZInfo), /* tp_basicsize */
2959
0, /* tp_itemsize */
2964
0, /* tp_reserved */
2966
0, /* tp_as_number */
2967
0, /* tp_as_sequence */
2968
0, /* tp_as_mapping */
2972
PyObject_GenericGetAttr, /* tp_getattro */
2973
0, /* tp_setattro */
2974
0, /* tp_as_buffer */
2975
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2976
tzinfo_doc, /* tp_doc */
2977
0, /* tp_traverse */
2979
0, /* tp_richcompare */
2980
0, /* tp_weaklistoffset */
2982
0, /* tp_iternext */
2983
tzinfo_methods, /* tp_methods */
2988
0, /* tp_descr_get */
2989
0, /* tp_descr_set */
2990
0, /* tp_dictoffset */
2993
PyType_GenericNew, /* tp_new */
3052
3050
static char *time_kws[] = {"hour", "minute", "second", "microsecond",
3055
3053
static PyObject *
3056
3054
time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3058
PyObject *self = NULL;
3064
PyObject *tzinfo = Py_None;
3066
/* Check for invocation from pickle with __getstate__ state */
3067
if (PyTuple_GET_SIZE(args) >= 1 &&
3068
PyTuple_GET_SIZE(args) <= 2 &&
3069
PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3070
PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3071
((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24)
3073
PyDateTime_Time *me;
3076
if (PyTuple_GET_SIZE(args) == 2) {
3077
tzinfo = PyTuple_GET_ITEM(args, 1);
3078
if (check_tzinfo_subclass(tzinfo) < 0) {
3079
PyErr_SetString(PyExc_TypeError, "bad "
3080
"tzinfo state arg");
3084
aware = (char)(tzinfo != Py_None);
3085
me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3087
char *pdata = PyBytes_AS_STRING(state);
3089
memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3091
me->hastzinfo = aware;
3094
me->tzinfo = tzinfo;
3097
return (PyObject *)me;
3100
if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3101
&hour, &minute, &second, &usecond,
3103
if (check_time_args(hour, minute, second, usecond) < 0)
3105
if (check_tzinfo_subclass(tzinfo) < 0)
3107
self = new_time_ex(hour, minute, second, usecond, tzinfo,
3056
PyObject *self = NULL;
3062
PyObject *tzinfo = Py_None;
3064
/* Check for invocation from pickle with __getstate__ state */
3065
if (PyTuple_GET_SIZE(args) >= 1 &&
3066
PyTuple_GET_SIZE(args) <= 2 &&
3067
PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3068
PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3069
((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24)
3071
PyDateTime_Time *me;
3074
if (PyTuple_GET_SIZE(args) == 2) {
3075
tzinfo = PyTuple_GET_ITEM(args, 1);
3076
if (check_tzinfo_subclass(tzinfo) < 0) {
3077
PyErr_SetString(PyExc_TypeError, "bad "
3078
"tzinfo state arg");
3082
aware = (char)(tzinfo != Py_None);
3083
me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3085
char *pdata = PyBytes_AS_STRING(state);
3087
memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3089
me->hastzinfo = aware;
3092
me->tzinfo = tzinfo;
3095
return (PyObject *)me;
3098
if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3099
&hour, &minute, &second, &usecond,
3101
if (check_time_args(hour, minute, second, usecond) < 0)
3103
if (check_tzinfo_subclass(tzinfo) < 0)
3105
self = new_time_ex(hour, minute, second, usecond, tzinfo,
3153
3151
static PyObject *
3154
3152
time_repr(PyDateTime_Time *self)
3156
const char *type_name = Py_TYPE(self)->tp_name;
3157
int h = TIME_GET_HOUR(self);
3158
int m = TIME_GET_MINUTE(self);
3159
int s = TIME_GET_SECOND(self);
3160
int us = TIME_GET_MICROSECOND(self);
3161
PyObject *result = NULL;
3154
const char *type_name = Py_TYPE(self)->tp_name;
3155
int h = TIME_GET_HOUR(self);
3156
int m = TIME_GET_MINUTE(self);
3157
int s = TIME_GET_SECOND(self);
3158
int us = TIME_GET_MICROSECOND(self);
3159
PyObject *result = NULL;
3164
result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3165
type_name, h, m, s, us);
3167
result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3168
type_name, h, m, s);
3170
result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3171
if (result != NULL && HASTZINFO(self))
3172
result = append_keyword_tzinfo(result, self->tzinfo);
3162
result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3163
type_name, h, m, s, us);
3165
result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3166
type_name, h, m, s);
3168
result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3169
if (result != NULL && HASTZINFO(self))
3170
result = append_keyword_tzinfo(result, self->tzinfo);
3176
3174
static PyObject *
3177
3175
time_str(PyDateTime_Time *self)
3179
return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
3177
return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
3182
3180
static PyObject *
3183
3181
time_isoformat(PyDateTime_Time *self, PyObject *unused)
3187
int us = TIME_GET_MICROSECOND(self);;
3190
result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d",
3191
TIME_GET_HOUR(self),
3192
TIME_GET_MINUTE(self),
3193
TIME_GET_SECOND(self),
3196
result = PyUnicode_FromFormat("%02d:%02d:%02d",
3197
TIME_GET_HOUR(self),
3198
TIME_GET_MINUTE(self),
3199
TIME_GET_SECOND(self));
3201
if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
3204
/* We need to append the UTC offset. */
3205
if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3210
PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3185
int us = TIME_GET_MICROSECOND(self);;
3188
result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d",
3189
TIME_GET_HOUR(self),
3190
TIME_GET_MINUTE(self),
3191
TIME_GET_SECOND(self),
3194
result = PyUnicode_FromFormat("%02d:%02d:%02d",
3195
TIME_GET_HOUR(self),
3196
TIME_GET_MINUTE(self),
3197
TIME_GET_SECOND(self));
3199
if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
3202
/* We need to append the UTC offset. */
3203
if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3208
PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3214
3212
static PyObject *
3215
3213
time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3220
static char *keywords[] = {"format", NULL};
3222
if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3226
/* Python's strftime does insane things with the year part of the
3227
* timetuple. The year is forced to (the otherwise nonsensical)
3228
* 1900 to worm around that.
3230
tuple = Py_BuildValue("iiiiiiiii",
3231
1900, 1, 1, /* year, month, day */
3232
TIME_GET_HOUR(self),
3233
TIME_GET_MINUTE(self),
3234
TIME_GET_SECOND(self),
3235
0, 1, -1); /* weekday, daynum, dst */
3238
assert(PyTuple_Size(tuple) == 9);
3239
result = wrap_strftime((PyObject *)self, format, tuple,
3218
static char *keywords[] = {"format", NULL};
3220
if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3224
/* Python's strftime does insane things with the year part of the
3225
* timetuple. The year is forced to (the otherwise nonsensical)
3226
* 1900 to worm around that.
3228
tuple = Py_BuildValue("iiiiiiiii",
3229
1900, 1, 1, /* year, month, day */
3230
TIME_GET_HOUR(self),
3231
TIME_GET_MINUTE(self),
3232
TIME_GET_SECOND(self),
3233
0, 1, -1); /* weekday, daynum, dst */
3236
assert(PyTuple_Size(tuple) == 9);
3237
result = wrap_strftime((PyObject *)self, format, tuple,
3249
3247
static PyObject *
3250
3248
time_richcompare(PyObject *self, PyObject *other, int op)
3254
int offset1, offset2;
3256
if (! PyTime_Check(other)) {
3257
Py_INCREF(Py_NotImplemented);
3258
return Py_NotImplemented;
3260
if (classify_two_utcoffsets(self, &offset1, &n1, Py_None,
3261
other, &offset2, &n2, Py_None) < 0)
3263
assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3264
/* If they're both naive, or both aware and have the same offsets,
3265
* we get off cheap. Note that if they're both naive, offset1 ==
3266
* offset2 == 0 at this point.
3268
if (n1 == n2 && offset1 == offset2) {
3269
diff = memcmp(((PyDateTime_Time *)self)->data,
3270
((PyDateTime_Time *)other)->data,
3271
_PyDateTime_TIME_DATASIZE);
3272
return diff_to_bool(diff, op);
3275
if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3276
assert(offset1 != offset2); /* else last "if" handled it */
3277
/* Convert everything except microseconds to seconds. These
3278
* can't overflow (no more than the # of seconds in 2 days).
3280
offset1 = TIME_GET_HOUR(self) * 3600 +
3281
(TIME_GET_MINUTE(self) - offset1) * 60 +
3282
TIME_GET_SECOND(self);
3283
offset2 = TIME_GET_HOUR(other) * 3600 +
3284
(TIME_GET_MINUTE(other) - offset2) * 60 +
3285
TIME_GET_SECOND(other);
3286
diff = offset1 - offset2;
3288
diff = TIME_GET_MICROSECOND(self) -
3289
TIME_GET_MICROSECOND(other);
3290
return diff_to_bool(diff, op);
3294
PyErr_SetString(PyExc_TypeError,
3295
"can't compare offset-naive and "
3296
"offset-aware times");
3252
int offset1, offset2;
3254
if (! PyTime_Check(other)) {
3255
Py_INCREF(Py_NotImplemented);
3256
return Py_NotImplemented;
3258
if (classify_two_utcoffsets(self, &offset1, &n1, Py_None,
3259
other, &offset2, &n2, Py_None) < 0)
3261
assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3262
/* If they're both naive, or both aware and have the same offsets,
3263
* we get off cheap. Note that if they're both naive, offset1 ==
3264
* offset2 == 0 at this point.
3266
if (n1 == n2 && offset1 == offset2) {
3267
diff = memcmp(((PyDateTime_Time *)self)->data,
3268
((PyDateTime_Time *)other)->data,
3269
_PyDateTime_TIME_DATASIZE);
3270
return diff_to_bool(diff, op);
3273
if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3274
assert(offset1 != offset2); /* else last "if" handled it */
3275
/* Convert everything except microseconds to seconds. These
3276
* can't overflow (no more than the # of seconds in 2 days).
3278
offset1 = TIME_GET_HOUR(self) * 3600 +
3279
(TIME_GET_MINUTE(self) - offset1) * 60 +
3280
TIME_GET_SECOND(self);
3281
offset2 = TIME_GET_HOUR(other) * 3600 +
3282
(TIME_GET_MINUTE(other) - offset2) * 60 +
3283
TIME_GET_SECOND(other);
3284
diff = offset1 - offset2;
3286
diff = TIME_GET_MICROSECOND(self) -
3287
TIME_GET_MICROSECOND(other);
3288
return diff_to_bool(diff, op);
3292
PyErr_SetString(PyExc_TypeError,
3293
"can't compare offset-naive and "
3294
"offset-aware times");
3301
3299
time_hash(PyDateTime_Time *self)
3303
if (self->hashcode == -1) {
3308
n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3309
assert(n != OFFSET_UNKNOWN);
3310
if (n == OFFSET_ERROR)
3313
/* Reduce this to a hash of another object. */
3315
self->hashcode = generic_hash(
3316
(unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
3317
return self->hashcode;
3323
assert(n == OFFSET_AWARE);
3324
assert(HASTZINFO(self));
3325
hour = divmod(TIME_GET_HOUR(self) * 60 +
3326
TIME_GET_MINUTE(self) - offset,
3329
if (0 <= hour && hour < 24)
3330
temp = new_time(hour, minute,
3331
TIME_GET_SECOND(self),
3332
TIME_GET_MICROSECOND(self),
3335
temp = Py_BuildValue("iiii",
3337
TIME_GET_SECOND(self),
3338
TIME_GET_MICROSECOND(self));
3341
self->hashcode = PyObject_Hash(temp);
3345
return self->hashcode;
3301
if (self->hashcode == -1) {
3306
n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3307
assert(n != OFFSET_UNKNOWN);
3308
if (n == OFFSET_ERROR)
3311
/* Reduce this to a hash of another object. */
3313
self->hashcode = generic_hash(
3314
(unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
3315
return self->hashcode;
3321
assert(n == OFFSET_AWARE);
3322
assert(HASTZINFO(self));
3323
hour = divmod(TIME_GET_HOUR(self) * 60 +
3324
TIME_GET_MINUTE(self) - offset,
3327
if (0 <= hour && hour < 24)
3328
temp = new_time(hour, minute,
3329
TIME_GET_SECOND(self),
3330
TIME_GET_MICROSECOND(self),
3333
temp = Py_BuildValue("iiii",
3335
TIME_GET_SECOND(self),
3336
TIME_GET_MICROSECOND(self));
3339
self->hashcode = PyObject_Hash(temp);
3343
return self->hashcode;
3348
3346
static PyObject *
3349
3347
time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3353
int hh = TIME_GET_HOUR(self);
3354
int mm = TIME_GET_MINUTE(self);
3355
int ss = TIME_GET_SECOND(self);
3356
int us = TIME_GET_MICROSECOND(self);
3357
PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
3351
int hh = TIME_GET_HOUR(self);
3352
int mm = TIME_GET_MINUTE(self);
3353
int ss = TIME_GET_SECOND(self);
3354
int us = TIME_GET_MICROSECOND(self);
3355
PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
3359
if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3361
&hh, &mm, &ss, &us, &tzinfo))
3363
tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3366
clone = time_new(Py_TYPE(self), tuple, NULL);
3357
if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3359
&hh, &mm, &ss, &us, &tzinfo))
3361
tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3364
clone = time_new(Py_TYPE(self), tuple, NULL);
3372
3370
time_bool(PyDateTime_Time *self)
3377
if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3378
/* Since utcoffset is in whole minutes, nothing can
3379
* alter the conclusion that this is nonzero.
3384
if (HASTZINFO(self) && self->tzinfo != Py_None) {
3385
offset = call_utcoffset(self->tzinfo, Py_None, &none);
3386
if (offset == -1 && PyErr_Occurred())
3389
return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
3375
if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3376
/* Since utcoffset is in whole minutes, nothing can
3377
* alter the conclusion that this is nonzero.
3382
if (HASTZINFO(self) && self->tzinfo != Py_None) {
3383
offset = call_utcoffset(self->tzinfo, Py_None, &none);
3384
if (offset == -1 && PyErr_Occurred())
3387
return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
3392
3390
/* Pickle support, a simple use of __reduce__. */
3399
3397
static PyObject *
3400
3398
time_getstate(PyDateTime_Time *self)
3402
PyObject *basestate;
3403
PyObject *result = NULL;
3400
PyObject *basestate;
3401
PyObject *result = NULL;
3405
basestate = PyBytes_FromStringAndSize((char *)self->data,
3406
_PyDateTime_TIME_DATASIZE);
3407
if (basestate != NULL) {
3408
if (! HASTZINFO(self) || self->tzinfo == Py_None)
3409
result = PyTuple_Pack(1, basestate);
3411
result = PyTuple_Pack(2, basestate, self->tzinfo);
3412
Py_DECREF(basestate);
3403
basestate = PyBytes_FromStringAndSize((char *)self->data,
3404
_PyDateTime_TIME_DATASIZE);
3405
if (basestate != NULL) {
3406
if (! HASTZINFO(self) || self->tzinfo == Py_None)
3407
result = PyTuple_Pack(1, basestate);
3409
result = PyTuple_Pack(2, basestate, self->tzinfo);
3410
Py_DECREF(basestate);
3417
3415
static PyObject *
3418
3416
time_reduce(PyDateTime_Time *self, PyObject *arg)
3420
return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
3418
return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
3423
3421
static PyMethodDef time_methods[] = {
3425
{"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3426
PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3429
{"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3430
PyDoc_STR("format -> strftime() style string.")},
3432
{"__format__", (PyCFunction)date_format, METH_VARARGS,
3433
PyDoc_STR("Formats self with strftime.")},
3435
{"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3436
PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
3438
{"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3439
PyDoc_STR("Return self.tzinfo.tzname(self).")},
3441
{"dst", (PyCFunction)time_dst, METH_NOARGS,
3442
PyDoc_STR("Return self.tzinfo.dst(self).")},
3444
{"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3445
PyDoc_STR("Return time with new specified fields.")},
3447
{"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3448
PyDoc_STR("__reduce__() -> (cls, state)")},
3423
{"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3424
PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3427
{"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3428
PyDoc_STR("format -> strftime() style string.")},
3430
{"__format__", (PyCFunction)date_format, METH_VARARGS,
3431
PyDoc_STR("Formats self with strftime.")},
3433
{"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3434
PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
3436
{"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3437
PyDoc_STR("Return self.tzinfo.tzname(self).")},
3439
{"dst", (PyCFunction)time_dst, METH_NOARGS,
3440
PyDoc_STR("Return self.tzinfo.dst(self).")},
3442
{"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3443
PyDoc_STR("Return time with new specified fields.")},
3445
{"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3446
PyDoc_STR("__reduce__() -> (cls, state)")},
3453
3451
static char time_doc[] =
3567
3565
static char *datetime_kws[] = {
3568
"year", "month", "day", "hour", "minute", "second",
3569
"microsecond", "tzinfo", NULL
3566
"year", "month", "day", "hour", "minute", "second",
3567
"microsecond", "tzinfo", NULL
3572
3570
static PyObject *
3573
3571
datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3575
PyObject *self = NULL;
3584
PyObject *tzinfo = Py_None;
3586
/* Check for invocation from pickle with __getstate__ state */
3587
if (PyTuple_GET_SIZE(args) >= 1 &&
3588
PyTuple_GET_SIZE(args) <= 2 &&
3589
PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3590
PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
3591
MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
3593
PyDateTime_DateTime *me;
3596
if (PyTuple_GET_SIZE(args) == 2) {
3597
tzinfo = PyTuple_GET_ITEM(args, 1);
3598
if (check_tzinfo_subclass(tzinfo) < 0) {
3599
PyErr_SetString(PyExc_TypeError, "bad "
3600
"tzinfo state arg");
3604
aware = (char)(tzinfo != Py_None);
3605
me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
3607
char *pdata = PyBytes_AS_STRING(state);
3609
memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
3611
me->hastzinfo = aware;
3614
me->tzinfo = tzinfo;
3617
return (PyObject *)me;
3620
if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
3621
&year, &month, &day, &hour, &minute,
3622
&second, &usecond, &tzinfo)) {
3623
if (check_date_args(year, month, day) < 0)
3625
if (check_time_args(hour, minute, second, usecond) < 0)
3627
if (check_tzinfo_subclass(tzinfo) < 0)
3629
self = new_datetime_ex(year, month, day,
3630
hour, minute, second, usecond,
3573
PyObject *self = NULL;
3582
PyObject *tzinfo = Py_None;
3584
/* Check for invocation from pickle with __getstate__ state */
3585
if (PyTuple_GET_SIZE(args) >= 1 &&
3586
PyTuple_GET_SIZE(args) <= 2 &&
3587
PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3588
PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
3589
MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
3591
PyDateTime_DateTime *me;
3594
if (PyTuple_GET_SIZE(args) == 2) {
3595
tzinfo = PyTuple_GET_ITEM(args, 1);
3596
if (check_tzinfo_subclass(tzinfo) < 0) {
3597
PyErr_SetString(PyExc_TypeError, "bad "
3598
"tzinfo state arg");
3602
aware = (char)(tzinfo != Py_None);
3603
me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
3605
char *pdata = PyBytes_AS_STRING(state);
3607
memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
3609
me->hastzinfo = aware;
3612
me->tzinfo = tzinfo;
3615
return (PyObject *)me;
3618
if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
3619
&year, &month, &day, &hour, &minute,
3620
&second, &usecond, &tzinfo)) {
3621
if (check_date_args(year, month, day) < 0)
3623
if (check_time_args(hour, minute, second, usecond) < 0)
3625
if (check_tzinfo_subclass(tzinfo) < 0)
3627
self = new_datetime_ex(year, month, day,
3628
hour, minute, second, usecond,
3636
3634
/* TM_FUNC is the shared type of localtime() and gmtime(). */
3784
3782
static PyObject *
3785
3783
datetime_utcnow(PyObject *cls, PyObject *dummy)
3787
return datetime_best_possible(cls, gmtime, Py_None);
3785
return datetime_best_possible(cls, gmtime, Py_None);
3790
3788
/* Return new local datetime from timestamp (Python timestamp -- a double). */
3791
3789
static PyObject *
3792
3790
datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
3796
PyObject *tzinfo = Py_None;
3797
static char *keywords[] = {"timestamp", "tz", NULL};
3799
if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3800
keywords, ×tamp, &tzinfo))
3802
if (check_tzinfo_subclass(tzinfo) < 0)
3805
self = datetime_from_timestamp(cls,
3806
tzinfo == Py_None ? localtime : gmtime,
3809
if (self != NULL && tzinfo != Py_None) {
3810
/* Convert UTC to tzinfo's zone. */
3811
PyObject *temp = self;
3812
self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3794
PyObject *tzinfo = Py_None;
3795
static char *keywords[] = {"timestamp", "tz", NULL};
3797
if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3798
keywords, ×tamp, &tzinfo))
3800
if (check_tzinfo_subclass(tzinfo) < 0)
3803
self = datetime_from_timestamp(cls,
3804
tzinfo == Py_None ? localtime : gmtime,
3807
if (self != NULL && tzinfo != Py_None) {
3808
/* Convert UTC to tzinfo's zone. */
3809
PyObject *temp = self;
3810
self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3818
3816
/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3819
3817
static PyObject *
3820
3818
datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
3823
PyObject *result = NULL;
3821
PyObject *result = NULL;
3825
if (PyArg_ParseTuple(args, "d:utcfromtimestamp", ×tamp))
3826
result = datetime_from_timestamp(cls, gmtime, timestamp,
3823
if (PyArg_ParseTuple(args, "d:utcfromtimestamp", ×tamp))
3824
result = datetime_from_timestamp(cls, gmtime, timestamp,
3831
3829
/* Return new datetime from time.strptime(). */
3832
3830
static PyObject *
3833
3831
datetime_strptime(PyObject *cls, PyObject *args)
3835
static PyObject *module = NULL;
3836
PyObject *result = NULL, *obj, *st = NULL, *frac = NULL;
3837
const Py_UNICODE *string, *format;
3839
if (!PyArg_ParseTuple(args, "uu:strptime", &string, &format))
3842
if (module == NULL &&
3843
(module = PyImport_ImportModuleNoBlock("_strptime")) == NULL)
3846
/* _strptime._strptime returns a two-element tuple. The first
3847
element is a time.struct_time object. The second is the
3848
microseconds (which are not defined for time.struct_time). */
3849
obj = PyObject_CallMethod(module, "_strptime", "uu", string, format);
3851
int i, good_timetuple = 1;
3853
if (PySequence_Check(obj) && PySequence_Size(obj) == 2) {
3854
st = PySequence_GetItem(obj, 0);
3855
frac = PySequence_GetItem(obj, 1);
3856
if (st == NULL || frac == NULL)
3858
/* copy y/m/d/h/m/s values out of the
3860
if (good_timetuple &&
3861
PySequence_Check(st) &&
3862
PySequence_Size(st) >= 6) {
3863
for (i=0; i < 6; i++) {
3864
PyObject *p = PySequence_GetItem(st, i);
3869
if (PyLong_Check(p))
3870
ia[i] = PyLong_AsLong(p);
3875
/* if (PyLong_CheckExact(p)) {
3876
ia[i] = PyLong_AsLongAndOverflow(p, &overflow);
3886
/* follow that up with a little dose of microseconds */
3887
if (PyLong_Check(frac))
3888
ia[6] = PyLong_AsLong(frac);
3895
result = PyObject_CallFunction(cls, "iiiiiii",
3896
ia[0], ia[1], ia[2],
3897
ia[3], ia[4], ia[5],
3900
PyErr_SetString(PyExc_ValueError,
3901
"unexpected value from _strptime._strptime");
3833
static PyObject *module = NULL;
3834
PyObject *result = NULL, *obj, *st = NULL, *frac = NULL;
3835
const Py_UNICODE *string, *format;
3837
if (!PyArg_ParseTuple(args, "uu:strptime", &string, &format))
3840
if (module == NULL &&
3841
(module = PyImport_ImportModuleNoBlock("_strptime")) == NULL)
3844
/* _strptime._strptime returns a two-element tuple. The first
3845
element is a time.struct_time object. The second is the
3846
microseconds (which are not defined for time.struct_time). */
3847
obj = PyObject_CallMethod(module, "_strptime", "uu", string, format);
3849
int i, good_timetuple = 1;
3851
if (PySequence_Check(obj) && PySequence_Size(obj) == 2) {
3852
st = PySequence_GetItem(obj, 0);
3853
frac = PySequence_GetItem(obj, 1);
3854
if (st == NULL || frac == NULL)
3856
/* copy y/m/d/h/m/s values out of the
3858
if (good_timetuple &&
3859
PySequence_Check(st) &&
3860
PySequence_Size(st) >= 6) {
3861
for (i=0; i < 6; i++) {
3862
PyObject *p = PySequence_GetItem(st, i);
3867
if (PyLong_Check(p))
3868
ia[i] = PyLong_AsLong(p);
3873
/* if (PyLong_CheckExact(p)) {
3874
ia[i] = PyLong_AsLongAndOverflow(p, &overflow);
3884
/* follow that up with a little dose of microseconds */
3885
if (PyLong_Check(frac))
3886
ia[6] = PyLong_AsLong(frac);
3893
result = PyObject_CallFunction(cls, "iiiiiii",
3894
ia[0], ia[1], ia[2],
3895
ia[3], ia[4], ia[5],
3898
PyErr_SetString(PyExc_ValueError,
3899
"unexpected value from _strptime._strptime");
3909
3907
/* Return new datetime from date/datetime and time arguments. */
3910
3908
static PyObject *
3911
3909
datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
3913
static char *keywords[] = {"date", "time", NULL};
3916
PyObject *result = NULL;
3918
if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
3919
&PyDateTime_DateType, &date,
3920
&PyDateTime_TimeType, &time)) {
3921
PyObject *tzinfo = Py_None;
3923
if (HASTZINFO(time))
3924
tzinfo = ((PyDateTime_Time *)time)->tzinfo;
3925
result = PyObject_CallFunction(cls, "iiiiiiiO",
3929
TIME_GET_HOUR(time),
3930
TIME_GET_MINUTE(time),
3931
TIME_GET_SECOND(time),
3932
TIME_GET_MICROSECOND(time),
3911
static char *keywords[] = {"date", "time", NULL};
3914
PyObject *result = NULL;
3916
if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
3917
&PyDateTime_DateType, &date,
3918
&PyDateTime_TimeType, &time)) {
3919
PyObject *tzinfo = Py_None;
3921
if (HASTZINFO(time))
3922
tzinfo = ((PyDateTime_Time *)time)->tzinfo;
3923
result = PyObject_CallFunction(cls, "iiiiiiiO",
3927
TIME_GET_HOUR(time),
3928
TIME_GET_MINUTE(time),
3929
TIME_GET_SECOND(time),
3930
TIME_GET_MICROSECOND(time),
3981
3979
static PyObject *
3982
3980
add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
3985
/* Note that the C-level additions can't overflow, because of
3986
* invariant bounds on the member values.
3988
int year = GET_YEAR(date);
3989
int month = GET_MONTH(date);
3990
int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
3991
int hour = DATE_GET_HOUR(date);
3992
int minute = DATE_GET_MINUTE(date);
3993
int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
3994
int microsecond = DATE_GET_MICROSECOND(date) +
3995
GET_TD_MICROSECONDS(delta) * factor;
3983
/* Note that the C-level additions can't overflow, because of
3984
* invariant bounds on the member values.
3986
int year = GET_YEAR(date);
3987
int month = GET_MONTH(date);
3988
int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
3989
int hour = DATE_GET_HOUR(date);
3990
int minute = DATE_GET_MINUTE(date);
3991
int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
3992
int microsecond = DATE_GET_MICROSECOND(date) +
3993
GET_TD_MICROSECONDS(delta) * factor;
3997
assert(factor == 1 || factor == -1);
3998
if (normalize_datetime(&year, &month, &day,
3999
&hour, &minute, &second, µsecond) < 0)
4002
return new_datetime(year, month, day,
4003
hour, minute, second, microsecond,
4004
HASTZINFO(date) ? date->tzinfo : Py_None);
3995
assert(factor == 1 || factor == -1);
3996
if (normalize_datetime(&year, &month, &day,
3997
&hour, &minute, &second, µsecond) < 0)
4000
return new_datetime(year, month, day,
4001
hour, minute, second, microsecond,
4002
HASTZINFO(date) ? date->tzinfo : Py_None);
4007
4005
static PyObject *
4008
4006
datetime_add(PyObject *left, PyObject *right)
4010
if (PyDateTime_Check(left)) {
4011
/* datetime + ??? */
4012
if (PyDelta_Check(right))
4013
/* datetime + delta */
4014
return add_datetime_timedelta(
4015
(PyDateTime_DateTime *)left,
4016
(PyDateTime_Delta *)right,
4019
else if (PyDelta_Check(left)) {
4020
/* delta + datetime */
4021
return add_datetime_timedelta((PyDateTime_DateTime *) right,
4022
(PyDateTime_Delta *) left,
4025
Py_INCREF(Py_NotImplemented);
4026
return Py_NotImplemented;
4008
if (PyDateTime_Check(left)) {
4009
/* datetime + ??? */
4010
if (PyDelta_Check(right))
4011
/* datetime + delta */
4012
return add_datetime_timedelta(
4013
(PyDateTime_DateTime *)left,
4014
(PyDateTime_Delta *)right,
4017
else if (PyDelta_Check(left)) {
4018
/* delta + datetime */
4019
return add_datetime_timedelta((PyDateTime_DateTime *) right,
4020
(PyDateTime_Delta *) left,
4023
Py_INCREF(Py_NotImplemented);
4024
return Py_NotImplemented;
4029
4027
static PyObject *
4030
4028
datetime_subtract(PyObject *left, PyObject *right)
4032
PyObject *result = Py_NotImplemented;
4034
if (PyDateTime_Check(left)) {
4035
/* datetime - ??? */
4036
if (PyDateTime_Check(right)) {
4037
/* datetime - datetime */
4039
int offset1, offset2;
4040
int delta_d, delta_s, delta_us;
4042
if (classify_two_utcoffsets(left, &offset1, &n1, left,
4043
right, &offset2, &n2,
4046
assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4048
PyErr_SetString(PyExc_TypeError,
4049
"can't subtract offset-naive and "
4050
"offset-aware datetimes");
4053
delta_d = ymd_to_ord(GET_YEAR(left),
4056
ymd_to_ord(GET_YEAR(right),
4059
/* These can't overflow, since the values are
4060
* normalized. At most this gives the number of
4061
* seconds in one day.
4063
delta_s = (DATE_GET_HOUR(left) -
4064
DATE_GET_HOUR(right)) * 3600 +
4065
(DATE_GET_MINUTE(left) -
4066
DATE_GET_MINUTE(right)) * 60 +
4067
(DATE_GET_SECOND(left) -
4068
DATE_GET_SECOND(right));
4069
delta_us = DATE_GET_MICROSECOND(left) -
4070
DATE_GET_MICROSECOND(right);
4071
/* (left - offset1) - (right - offset2) =
4072
* (left - right) + (offset2 - offset1)
4074
delta_s += (offset2 - offset1) * 60;
4075
result = new_delta(delta_d, delta_s, delta_us, 1);
4077
else if (PyDelta_Check(right)) {
4078
/* datetime - delta */
4079
result = add_datetime_timedelta(
4080
(PyDateTime_DateTime *)left,
4081
(PyDateTime_Delta *)right,
4086
if (result == Py_NotImplemented)
4030
PyObject *result = Py_NotImplemented;
4032
if (PyDateTime_Check(left)) {
4033
/* datetime - ??? */
4034
if (PyDateTime_Check(right)) {
4035
/* datetime - datetime */
4037
int offset1, offset2;
4038
int delta_d, delta_s, delta_us;
4040
if (classify_two_utcoffsets(left, &offset1, &n1, left,
4041
right, &offset2, &n2,
4044
assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4046
PyErr_SetString(PyExc_TypeError,
4047
"can't subtract offset-naive and "
4048
"offset-aware datetimes");
4051
delta_d = ymd_to_ord(GET_YEAR(left),
4054
ymd_to_ord(GET_YEAR(right),
4057
/* These can't overflow, since the values are
4058
* normalized. At most this gives the number of
4059
* seconds in one day.
4061
delta_s = (DATE_GET_HOUR(left) -
4062
DATE_GET_HOUR(right)) * 3600 +
4063
(DATE_GET_MINUTE(left) -
4064
DATE_GET_MINUTE(right)) * 60 +
4065
(DATE_GET_SECOND(left) -
4066
DATE_GET_SECOND(right));
4067
delta_us = DATE_GET_MICROSECOND(left) -
4068
DATE_GET_MICROSECOND(right);
4069
/* (left - offset1) - (right - offset2) =
4070
* (left - right) + (offset2 - offset1)
4072
delta_s += (offset2 - offset1) * 60;
4073
result = new_delta(delta_d, delta_s, delta_us, 1);
4075
else if (PyDelta_Check(right)) {
4076
/* datetime - delta */
4077
result = add_datetime_timedelta(
4078
(PyDateTime_DateTime *)left,
4079
(PyDateTime_Delta *)right,
4084
if (result == Py_NotImplemented)
4091
4089
/* Various ways to turn a datetime into a string. */
4093
4091
static PyObject *
4094
4092
datetime_repr(PyDateTime_DateTime *self)
4096
const char *type_name = Py_TYPE(self)->tp_name;
4094
const char *type_name = Py_TYPE(self)->tp_name;
4099
if (DATE_GET_MICROSECOND(self)) {
4100
baserepr = PyUnicode_FromFormat(
4101
"%s(%d, %d, %d, %d, %d, %d, %d)",
4103
GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4104
DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4105
DATE_GET_SECOND(self),
4106
DATE_GET_MICROSECOND(self));
4108
else if (DATE_GET_SECOND(self)) {
4109
baserepr = PyUnicode_FromFormat(
4110
"%s(%d, %d, %d, %d, %d, %d)",
4112
GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4113
DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4114
DATE_GET_SECOND(self));
4117
baserepr = PyUnicode_FromFormat(
4118
"%s(%d, %d, %d, %d, %d)",
4120
GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4121
DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4123
if (baserepr == NULL || ! HASTZINFO(self))
4125
return append_keyword_tzinfo(baserepr, self->tzinfo);
4097
if (DATE_GET_MICROSECOND(self)) {
4098
baserepr = PyUnicode_FromFormat(
4099
"%s(%d, %d, %d, %d, %d, %d, %d)",
4101
GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4102
DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4103
DATE_GET_SECOND(self),
4104
DATE_GET_MICROSECOND(self));
4106
else if (DATE_GET_SECOND(self)) {
4107
baserepr = PyUnicode_FromFormat(
4108
"%s(%d, %d, %d, %d, %d, %d)",
4110
GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4111
DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4112
DATE_GET_SECOND(self));
4115
baserepr = PyUnicode_FromFormat(
4116
"%s(%d, %d, %d, %d, %d)",
4118
GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4119
DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4121
if (baserepr == NULL || ! HASTZINFO(self))
4123
return append_keyword_tzinfo(baserepr, self->tzinfo);
4128
4126
static PyObject *
4129
4127
datetime_str(PyDateTime_DateTime *self)
4131
return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
4129
return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
4134
4132
static PyObject *
4135
4133
datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
4138
static char *keywords[] = {"sep", NULL};
4141
int us = DATE_GET_MICROSECOND(self);
4143
if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
4146
result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d.%06d",
4147
GET_YEAR(self), GET_MONTH(self),
4148
GET_DAY(self), (int)sep,
4149
DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4150
DATE_GET_SECOND(self), us);
4152
result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d",
4153
GET_YEAR(self), GET_MONTH(self),
4154
GET_DAY(self), (int)sep,
4155
DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4156
DATE_GET_SECOND(self));
4158
if (!result || !HASTZINFO(self))
4161
/* We need to append the UTC offset. */
4162
if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4163
(PyObject *)self) < 0) {
4167
PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4136
static char *keywords[] = {"sep", NULL};
4139
int us = DATE_GET_MICROSECOND(self);
4141
if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
4144
result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d.%06d",
4145
GET_YEAR(self), GET_MONTH(self),
4146
GET_DAY(self), (int)sep,
4147
DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4148
DATE_GET_SECOND(self), us);
4150
result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d",
4151
GET_YEAR(self), GET_MONTH(self),
4152
GET_DAY(self), (int)sep,
4153
DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4154
DATE_GET_SECOND(self));
4156
if (!result || !HASTZINFO(self))
4159
/* We need to append the UTC offset. */
4160
if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4161
(PyObject *)self) < 0) {
4165
PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4171
4169
static PyObject *
4172
4170
datetime_ctime(PyDateTime_DateTime *self)
4174
return format_ctime((PyDateTime_Date *)self,
4175
DATE_GET_HOUR(self),
4176
DATE_GET_MINUTE(self),
4177
DATE_GET_SECOND(self));
4172
return format_ctime((PyDateTime_Date *)self,
4173
DATE_GET_HOUR(self),
4174
DATE_GET_MINUTE(self),
4175
DATE_GET_SECOND(self));
4180
4178
/* Miscellaneous methods. */
4182
4180
static PyObject *
4183
4181
datetime_richcompare(PyObject *self, PyObject *other, int op)
4187
int offset1, offset2;
4189
if (! PyDateTime_Check(other)) {
4190
if (PyDate_Check(other)) {
4191
/* Prevent invocation of date_richcompare. We want to
4192
return NotImplemented here to give the other object
4193
a chance. But since DateTime is a subclass of
4194
Date, if the other object is a Date, it would
4195
compute an ordering based on the date part alone,
4196
and we don't want that. So force unequal or
4197
uncomparable here in that case. */
4202
return cmperror(self, other);
4204
Py_INCREF(Py_NotImplemented);
4205
return Py_NotImplemented;
4208
if (classify_two_utcoffsets(self, &offset1, &n1, self,
4209
other, &offset2, &n2, other) < 0)
4211
assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4212
/* If they're both naive, or both aware and have the same offsets,
4213
* we get off cheap. Note that if they're both naive, offset1 ==
4214
* offset2 == 0 at this point.
4216
if (n1 == n2 && offset1 == offset2) {
4217
diff = memcmp(((PyDateTime_DateTime *)self)->data,
4218
((PyDateTime_DateTime *)other)->data,
4219
_PyDateTime_DATETIME_DATASIZE);
4220
return diff_to_bool(diff, op);
4223
if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4224
PyDateTime_Delta *delta;
4226
assert(offset1 != offset2); /* else last "if" handled it */
4227
delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4231
diff = GET_TD_DAYS(delta);
4233
diff = GET_TD_SECONDS(delta) |
4234
GET_TD_MICROSECONDS(delta);
4236
return diff_to_bool(diff, op);
4240
PyErr_SetString(PyExc_TypeError,
4241
"can't compare offset-naive and "
4242
"offset-aware datetimes");
4185
int offset1, offset2;
4187
if (! PyDateTime_Check(other)) {
4188
if (PyDate_Check(other)) {
4189
/* Prevent invocation of date_richcompare. We want to
4190
return NotImplemented here to give the other object
4191
a chance. But since DateTime is a subclass of
4192
Date, if the other object is a Date, it would
4193
compute an ordering based on the date part alone,
4194
and we don't want that. So force unequal or
4195
uncomparable here in that case. */
4200
return cmperror(self, other);
4202
Py_INCREF(Py_NotImplemented);
4203
return Py_NotImplemented;
4206
if (classify_two_utcoffsets(self, &offset1, &n1, self,
4207
other, &offset2, &n2, other) < 0)
4209
assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4210
/* If they're both naive, or both aware and have the same offsets,
4211
* we get off cheap. Note that if they're both naive, offset1 ==
4212
* offset2 == 0 at this point.
4214
if (n1 == n2 && offset1 == offset2) {
4215
diff = memcmp(((PyDateTime_DateTime *)self)->data,
4216
((PyDateTime_DateTime *)other)->data,
4217
_PyDateTime_DATETIME_DATASIZE);
4218
return diff_to_bool(diff, op);
4221
if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4222
PyDateTime_Delta *delta;
4224
assert(offset1 != offset2); /* else last "if" handled it */
4225
delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4229
diff = GET_TD_DAYS(delta);
4231
diff = GET_TD_SECONDS(delta) |
4232
GET_TD_MICROSECONDS(delta);
4234
return diff_to_bool(diff, op);
4238
PyErr_SetString(PyExc_TypeError,
4239
"can't compare offset-naive and "
4240
"offset-aware datetimes");
4247
4245
datetime_hash(PyDateTime_DateTime *self)
4249
if (self->hashcode == -1) {
4254
n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4256
assert(n != OFFSET_UNKNOWN);
4257
if (n == OFFSET_ERROR)
4260
/* Reduce this to a hash of another object. */
4261
if (n == OFFSET_NAIVE) {
4262
self->hashcode = generic_hash(
4263
(unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
4264
return self->hashcode;
4270
assert(n == OFFSET_AWARE);
4271
assert(HASTZINFO(self));
4272
days = ymd_to_ord(GET_YEAR(self),
4275
seconds = DATE_GET_HOUR(self) * 3600 +
4276
(DATE_GET_MINUTE(self) - offset) * 60 +
4277
DATE_GET_SECOND(self);
4278
temp = new_delta(days,
4280
DATE_GET_MICROSECOND(self),
4284
self->hashcode = PyObject_Hash(temp);
4288
return self->hashcode;
4247
if (self->hashcode == -1) {
4252
n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4254
assert(n != OFFSET_UNKNOWN);
4255
if (n == OFFSET_ERROR)
4258
/* Reduce this to a hash of another object. */
4259
if (n == OFFSET_NAIVE) {
4260
self->hashcode = generic_hash(
4261
(unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
4262
return self->hashcode;
4268
assert(n == OFFSET_AWARE);
4269
assert(HASTZINFO(self));
4270
days = ymd_to_ord(GET_YEAR(self),
4273
seconds = DATE_GET_HOUR(self) * 3600 +
4274
(DATE_GET_MINUTE(self) - offset) * 60 +
4275
DATE_GET_SECOND(self);
4276
temp = new_delta(days,
4278
DATE_GET_MICROSECOND(self),
4282
self->hashcode = PyObject_Hash(temp);
4286
return self->hashcode;
4291
4289
static PyObject *
4292
4290
datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
4296
int y = GET_YEAR(self);
4297
int m = GET_MONTH(self);
4298
int d = GET_DAY(self);
4299
int hh = DATE_GET_HOUR(self);
4300
int mm = DATE_GET_MINUTE(self);
4301
int ss = DATE_GET_SECOND(self);
4302
int us = DATE_GET_MICROSECOND(self);
4303
PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
4294
int y = GET_YEAR(self);
4295
int m = GET_MONTH(self);
4296
int d = GET_DAY(self);
4297
int hh = DATE_GET_HOUR(self);
4298
int mm = DATE_GET_MINUTE(self);
4299
int ss = DATE_GET_SECOND(self);
4300
int us = DATE_GET_MICROSECOND(self);
4301
PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
4305
if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4307
&y, &m, &d, &hh, &mm, &ss, &us,
4310
tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4313
clone = datetime_new(Py_TYPE(self), tuple, NULL);
4303
if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4305
&y, &m, &d, &hh, &mm, &ss, &us,
4308
tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4311
clone = datetime_new(Py_TYPE(self), tuple, NULL);
4318
4316
static PyObject *
4319
4317
datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
4321
int y, m, d, hh, mm, ss, us;
4326
static char *keywords[] = {"tz", NULL};
4328
if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4329
&PyDateTime_TZInfoType, &tzinfo))
4332
if (!HASTZINFO(self) || self->tzinfo == Py_None)
4335
/* Conversion to self's own time zone is a NOP. */
4336
if (self->tzinfo == tzinfo) {
4338
return (PyObject *)self;
4341
/* Convert self to UTC. */
4342
offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4343
if (offset == -1 && PyErr_Occurred())
4349
m = GET_MONTH(self);
4351
hh = DATE_GET_HOUR(self);
4352
mm = DATE_GET_MINUTE(self);
4353
ss = DATE_GET_SECOND(self);
4354
us = DATE_GET_MICROSECOND(self);
4357
if ((mm < 0 || mm >= 60) &&
4358
normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
4361
/* Attach new tzinfo and let fromutc() do the rest. */
4362
result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4363
if (result != NULL) {
4364
PyObject *temp = result;
4366
result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4319
int y, m, d, hh, mm, ss, us;
4324
static char *keywords[] = {"tz", NULL};
4326
if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4327
&PyDateTime_TZInfoType, &tzinfo))
4330
if (!HASTZINFO(self) || self->tzinfo == Py_None)
4333
/* Conversion to self's own time zone is a NOP. */
4334
if (self->tzinfo == tzinfo) {
4336
return (PyObject *)self;
4339
/* Convert self to UTC. */
4340
offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4341
if (offset == -1 && PyErr_Occurred())
4347
m = GET_MONTH(self);
4349
hh = DATE_GET_HOUR(self);
4350
mm = DATE_GET_MINUTE(self);
4351
ss = DATE_GET_SECOND(self);
4352
us = DATE_GET_MICROSECOND(self);
4355
if ((mm < 0 || mm >= 60) &&
4356
normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
4359
/* Attach new tzinfo and let fromutc() do the rest. */
4360
result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4361
if (result != NULL) {
4362
PyObject *temp = result;
4364
result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4372
PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4373
"a naive datetime");
4370
PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4371
"a naive datetime");
4377
4375
static PyObject *
4378
4376
datetime_timetuple(PyDateTime_DateTime *self)
4382
if (HASTZINFO(self) && self->tzinfo != Py_None) {
4385
dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4386
if (dstflag == -1 && PyErr_Occurred())
4391
else if (dstflag != 0)
4395
return build_struct_time(GET_YEAR(self),
4398
DATE_GET_HOUR(self),
4399
DATE_GET_MINUTE(self),
4400
DATE_GET_SECOND(self),
4380
if (HASTZINFO(self) && self->tzinfo != Py_None) {
4383
dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4384
if (dstflag == -1 && PyErr_Occurred())
4389
else if (dstflag != 0)
4393
return build_struct_time(GET_YEAR(self),
4396
DATE_GET_HOUR(self),
4397
DATE_GET_MINUTE(self),
4398
DATE_GET_SECOND(self),
4404
4402
static PyObject *
4405
4403
datetime_getdate(PyDateTime_DateTime *self)
4407
return new_date(GET_YEAR(self),
4405
return new_date(GET_YEAR(self),
4412
4410
static PyObject *
4413
4411
datetime_gettime(PyDateTime_DateTime *self)
4415
return new_time(DATE_GET_HOUR(self),
4416
DATE_GET_MINUTE(self),
4417
DATE_GET_SECOND(self),
4418
DATE_GET_MICROSECOND(self),
4413
return new_time(DATE_GET_HOUR(self),
4414
DATE_GET_MINUTE(self),
4415
DATE_GET_SECOND(self),
4416
DATE_GET_MICROSECOND(self),
4422
4420
static PyObject *
4423
4421
datetime_gettimetz(PyDateTime_DateTime *self)
4425
return new_time(DATE_GET_HOUR(self),
4426
DATE_GET_MINUTE(self),
4427
DATE_GET_SECOND(self),
4428
DATE_GET_MICROSECOND(self),
4429
HASTZINFO(self) ? self->tzinfo : Py_None);
4423
return new_time(DATE_GET_HOUR(self),
4424
DATE_GET_MINUTE(self),
4425
DATE_GET_SECOND(self),
4426
DATE_GET_MICROSECOND(self),
4427
HASTZINFO(self) ? self->tzinfo : Py_None);
4432
4430
static PyObject *
4433
4431
datetime_utctimetuple(PyDateTime_DateTime *self)
4435
int y = GET_YEAR(self);
4436
int m = GET_MONTH(self);
4437
int d = GET_DAY(self);
4438
int hh = DATE_GET_HOUR(self);
4439
int mm = DATE_GET_MINUTE(self);
4440
int ss = DATE_GET_SECOND(self);
4441
int us = 0; /* microseconds are ignored in a timetuple */
4444
if (HASTZINFO(self) && self->tzinfo != Py_None) {
4447
offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4448
if (offset == -1 && PyErr_Occurred())
4451
/* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4452
* 0 in a UTC timetuple regardless of what dst() says.
4455
/* Subtract offset minutes & normalize. */
4459
stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4461
/* At the edges, it's possible we overflowed
4462
* beyond MINYEAR or MAXYEAR.
4464
if (PyErr_ExceptionMatches(PyExc_OverflowError))
4470
return build_struct_time(y, m, d, hh, mm, ss, 0);
4433
int y = GET_YEAR(self);
4434
int m = GET_MONTH(self);
4435
int d = GET_DAY(self);
4436
int hh = DATE_GET_HOUR(self);
4437
int mm = DATE_GET_MINUTE(self);
4438
int ss = DATE_GET_SECOND(self);
4439
int us = 0; /* microseconds are ignored in a timetuple */
4442
if (HASTZINFO(self) && self->tzinfo != Py_None) {
4445
offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4446
if (offset == -1 && PyErr_Occurred())
4449
/* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4450
* 0 in a UTC timetuple regardless of what dst() says.
4453
/* Subtract offset minutes & normalize. */
4457
stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4459
/* At the edges, it's possible we overflowed
4460
* beyond MINYEAR or MAXYEAR.
4462
if (PyErr_ExceptionMatches(PyExc_OverflowError))
4468
return build_struct_time(y, m, d, hh, mm, ss, 0);
4473
4471
/* Pickle support, a simple use of __reduce__. */
4480
4478
static PyObject *
4481
4479
datetime_getstate(PyDateTime_DateTime *self)
4483
PyObject *basestate;
4484
PyObject *result = NULL;
4481
PyObject *basestate;
4482
PyObject *result = NULL;
4486
basestate = PyBytes_FromStringAndSize((char *)self->data,
4487
_PyDateTime_DATETIME_DATASIZE);
4488
if (basestate != NULL) {
4489
if (! HASTZINFO(self) || self->tzinfo == Py_None)
4490
result = PyTuple_Pack(1, basestate);
4492
result = PyTuple_Pack(2, basestate, self->tzinfo);
4493
Py_DECREF(basestate);
4484
basestate = PyBytes_FromStringAndSize((char *)self->data,
4485
_PyDateTime_DATETIME_DATASIZE);
4486
if (basestate != NULL) {
4487
if (! HASTZINFO(self) || self->tzinfo == Py_None)
4488
result = PyTuple_Pack(1, basestate);
4490
result = PyTuple_Pack(2, basestate, self->tzinfo);
4491
Py_DECREF(basestate);
4498
4496
static PyObject *
4499
4497
datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
4501
return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
4499
return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
4504
4502
static PyMethodDef datetime_methods[] = {
4506
/* Class methods: */
4508
{"now", (PyCFunction)datetime_now,
4509
METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4510
PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
4512
{"utcnow", (PyCFunction)datetime_utcnow,
4513
METH_NOARGS | METH_CLASS,
4514
PyDoc_STR("Return a new datetime representing UTC day and time.")},
4516
{"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4517
METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4518
PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
4520
{"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4521
METH_VARARGS | METH_CLASS,
4522
PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4523
"(like time.time()).")},
4525
{"strptime", (PyCFunction)datetime_strptime,
4526
METH_VARARGS | METH_CLASS,
4527
PyDoc_STR("string, format -> new datetime parsed from a string "
4528
"(like time.strptime()).")},
4530
{"combine", (PyCFunction)datetime_combine,
4531
METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4532
PyDoc_STR("date, time -> datetime with same date and time fields")},
4534
/* Instance methods: */
4536
{"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4537
PyDoc_STR("Return date object with same year, month and day.")},
4539
{"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4540
PyDoc_STR("Return time object with same time but with tzinfo=None.")},
4542
{"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4543
PyDoc_STR("Return time object with same time and tzinfo.")},
4545
{"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4546
PyDoc_STR("Return ctime() style string.")},
4548
{"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
4549
PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4551
{"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
4552
PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
4554
{"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
4555
PyDoc_STR("[sep] -> string in ISO 8601 format, "
4556
"YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4557
"sep is used to separate the year from the time, and "
4558
"defaults to 'T'.")},
4560
{"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
4561
PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4563
{"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
4564
PyDoc_STR("Return self.tzinfo.tzname(self).")},
4566
{"dst", (PyCFunction)datetime_dst, METH_NOARGS,
4567
PyDoc_STR("Return self.tzinfo.dst(self).")},
4569
{"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
4570
PyDoc_STR("Return datetime with new specified fields.")},
4572
{"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
4573
PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
4575
{"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4576
PyDoc_STR("__reduce__() -> (cls, state)")},
4504
/* Class methods: */
4506
{"now", (PyCFunction)datetime_now,
4507
METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4508
PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
4510
{"utcnow", (PyCFunction)datetime_utcnow,
4511
METH_NOARGS | METH_CLASS,
4512
PyDoc_STR("Return a new datetime representing UTC day and time.")},
4514
{"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4515
METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4516
PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
4518
{"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4519
METH_VARARGS | METH_CLASS,
4520
PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4521
"(like time.time()).")},
4523
{"strptime", (PyCFunction)datetime_strptime,
4524
METH_VARARGS | METH_CLASS,
4525
PyDoc_STR("string, format -> new datetime parsed from a string "
4526
"(like time.strptime()).")},
4528
{"combine", (PyCFunction)datetime_combine,
4529
METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4530
PyDoc_STR("date, time -> datetime with same date and time fields")},
4532
/* Instance methods: */
4534
{"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4535
PyDoc_STR("Return date object with same year, month and day.")},
4537
{"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4538
PyDoc_STR("Return time object with same time but with tzinfo=None.")},
4540
{"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4541
PyDoc_STR("Return time object with same time and tzinfo.")},
4543
{"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4544
PyDoc_STR("Return ctime() style string.")},
4546
{"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
4547
PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4549
{"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
4550
PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
4552
{"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
4553
PyDoc_STR("[sep] -> string in ISO 8601 format, "
4554
"YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4555
"sep is used to separate the year from the time, and "
4556
"defaults to 'T'.")},
4558
{"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
4559
PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4561
{"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
4562
PyDoc_STR("Return self.tzinfo.tzname(self).")},
4564
{"dst", (PyCFunction)datetime_dst, METH_NOARGS,
4565
PyDoc_STR("Return self.tzinfo.dst(self).")},
4567
{"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
4568
PyDoc_STR("Return datetime with new specified fields.")},
4570
{"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
4571
PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
4573
{"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4574
PyDoc_STR("__reduce__() -> (cls, state)")},
4581
4579
static char datetime_doc[] =
4585
4583
instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
4587
4585
static PyNumberMethods datetime_as_number = {
4588
datetime_add, /* nb_add */
4589
datetime_subtract, /* nb_subtract */
4590
0, /* nb_multiply */
4591
0, /* nb_remainder */
4594
0, /* nb_negative */
4595
0, /* nb_positive */
4596
0, /* nb_absolute */
4586
datetime_add, /* nb_add */
4587
datetime_subtract, /* nb_subtract */
4588
0, /* nb_multiply */
4589
0, /* nb_remainder */
4592
0, /* nb_negative */
4593
0, /* nb_positive */
4594
0, /* nb_absolute */
4600
4598
static PyTypeObject PyDateTime_DateTimeType = {
4601
PyVarObject_HEAD_INIT(NULL, 0)
4602
"datetime.datetime", /* tp_name */
4603
sizeof(PyDateTime_DateTime), /* tp_basicsize */
4604
0, /* tp_itemsize */
4605
(destructor)datetime_dealloc, /* tp_dealloc */
4609
0, /* tp_reserved */
4610
(reprfunc)datetime_repr, /* tp_repr */
4611
&datetime_as_number, /* tp_as_number */
4612
0, /* tp_as_sequence */
4613
0, /* tp_as_mapping */
4614
(hashfunc)datetime_hash, /* tp_hash */
4616
(reprfunc)datetime_str, /* tp_str */
4617
PyObject_GenericGetAttr, /* tp_getattro */
4618
0, /* tp_setattro */
4619
0, /* tp_as_buffer */
4620
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4621
datetime_doc, /* tp_doc */
4622
0, /* tp_traverse */
4624
datetime_richcompare, /* tp_richcompare */
4625
0, /* tp_weaklistoffset */
4627
0, /* tp_iternext */
4628
datetime_methods, /* tp_methods */
4630
datetime_getset, /* tp_getset */
4631
&PyDateTime_DateType, /* tp_base */
4633
0, /* tp_descr_get */
4634
0, /* tp_descr_set */
4635
0, /* tp_dictoffset */
4637
datetime_alloc, /* tp_alloc */
4638
datetime_new, /* tp_new */
4599
PyVarObject_HEAD_INIT(NULL, 0)
4600
"datetime.datetime", /* tp_name */
4601
sizeof(PyDateTime_DateTime), /* tp_basicsize */
4602
0, /* tp_itemsize */
4603
(destructor)datetime_dealloc, /* tp_dealloc */
4607
0, /* tp_reserved */
4608
(reprfunc)datetime_repr, /* tp_repr */
4609
&datetime_as_number, /* tp_as_number */
4610
0, /* tp_as_sequence */
4611
0, /* tp_as_mapping */
4612
(hashfunc)datetime_hash, /* tp_hash */
4614
(reprfunc)datetime_str, /* tp_str */
4615
PyObject_GenericGetAttr, /* tp_getattro */
4616
0, /* tp_setattro */
4617
0, /* tp_as_buffer */
4618
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4619
datetime_doc, /* tp_doc */
4620
0, /* tp_traverse */
4622
datetime_richcompare, /* tp_richcompare */
4623
0, /* tp_weaklistoffset */
4625
0, /* tp_iternext */
4626
datetime_methods, /* tp_methods */
4628
datetime_getset, /* tp_getset */
4629
&PyDateTime_DateType, /* tp_base */
4631
0, /* tp_descr_get */
4632
0, /* tp_descr_set */
4633
0, /* tp_dictoffset */
4635
datetime_alloc, /* tp_alloc */
4636
datetime_new, /* tp_new */
4642
4640
/* ---------------------------------------------------------------------------
4646
4644
static PyMethodDef module_methods[] = {
4650
4648
/* C API. Clients get at this via PyDateTime_IMPORT, defined in
4653
4651
static PyDateTime_CAPI CAPI = {
4654
&PyDateTime_DateType,
4655
&PyDateTime_DateTimeType,
4656
&PyDateTime_TimeType,
4657
&PyDateTime_DeltaType,
4658
&PyDateTime_TZInfoType,
4663
datetime_fromtimestamp,
4652
&PyDateTime_DateType,
4653
&PyDateTime_DateTimeType,
4654
&PyDateTime_TimeType,
4655
&PyDateTime_DeltaType,
4656
&PyDateTime_TZInfoType,
4661
datetime_fromtimestamp,
4669
4667
static struct PyModuleDef datetimemodule = {
4670
PyModuleDef_HEAD_INIT,
4672
"Fast implementation of the datetime type.",
4668
PyModuleDef_HEAD_INIT,
4670
"Fast implementation of the datetime type.",
4682
4680
PyInit_datetime(void)
4684
PyObject *m; /* a module object */
4685
PyObject *d; /* its dict */
4688
m = PyModule_Create(&datetimemodule);
4692
if (PyType_Ready(&PyDateTime_DateType) < 0)
4694
if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4696
if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4698
if (PyType_Ready(&PyDateTime_TimeType) < 0)
4700
if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4703
/* timedelta values */
4704
d = PyDateTime_DeltaType.tp_dict;
4706
x = new_delta(0, 0, 1, 0);
4707
if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4711
x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4712
if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4716
x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4717
if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4722
d = PyDateTime_DateType.tp_dict;
4724
x = new_date(1, 1, 1);
4725
if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4729
x = new_date(MAXYEAR, 12, 31);
4730
if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4734
x = new_delta(1, 0, 0, 0);
4735
if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4740
d = PyDateTime_TimeType.tp_dict;
4742
x = new_time(0, 0, 0, 0, Py_None);
4743
if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4747
x = new_time(23, 59, 59, 999999, Py_None);
4748
if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4752
x = new_delta(0, 0, 1, 0);
4753
if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4757
/* datetime values */
4758
d = PyDateTime_DateTimeType.tp_dict;
4760
x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
4761
if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4765
x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
4766
if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4770
x = new_delta(0, 0, 1, 0);
4771
if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4775
/* module initialization */
4776
PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4777
PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
4779
Py_INCREF(&PyDateTime_DateType);
4780
PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
4782
Py_INCREF(&PyDateTime_DateTimeType);
4783
PyModule_AddObject(m, "datetime",
4784
(PyObject *)&PyDateTime_DateTimeType);
4786
Py_INCREF(&PyDateTime_TimeType);
4787
PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
4789
Py_INCREF(&PyDateTime_DeltaType);
4790
PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
4792
Py_INCREF(&PyDateTime_TZInfoType);
4793
PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
4682
PyObject *m; /* a module object */
4683
PyObject *d; /* its dict */
4686
m = PyModule_Create(&datetimemodule);
4690
if (PyType_Ready(&PyDateTime_DateType) < 0)
4692
if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4694
if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4696
if (PyType_Ready(&PyDateTime_TimeType) < 0)
4698
if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4701
/* timedelta values */
4702
d = PyDateTime_DeltaType.tp_dict;
4704
x = new_delta(0, 0, 1, 0);
4705
if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4709
x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4710
if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4714
x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4715
if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4720
d = PyDateTime_DateType.tp_dict;
4722
x = new_date(1, 1, 1);
4723
if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4727
x = new_date(MAXYEAR, 12, 31);
4728
if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4732
x = new_delta(1, 0, 0, 0);
4733
if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4738
d = PyDateTime_TimeType.tp_dict;
4740
x = new_time(0, 0, 0, 0, Py_None);
4741
if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4745
x = new_time(23, 59, 59, 999999, Py_None);
4746
if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4750
x = new_delta(0, 0, 1, 0);
4751
if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4755
/* datetime values */
4756
d = PyDateTime_DateTimeType.tp_dict;
4758
x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
4759
if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4763
x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
4764
if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4768
x = new_delta(0, 0, 1, 0);
4769
if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4773
/* module initialization */
4774
PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4775
PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
4777
Py_INCREF(&PyDateTime_DateType);
4778
PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
4780
Py_INCREF(&PyDateTime_DateTimeType);
4781
PyModule_AddObject(m, "datetime",
4782
(PyObject *)&PyDateTime_DateTimeType);
4784
Py_INCREF(&PyDateTime_TimeType);
4785
PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
4787
Py_INCREF(&PyDateTime_DeltaType);
4788
PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
4790
Py_INCREF(&PyDateTime_TZInfoType);
4791
PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
4795
4793
x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
4798
4796
PyModule_AddObject(m, "datetime_CAPI", x);
4800
/* A 4-year cycle has an extra leap day over what we'd get from
4801
* pasting together 4 single years.
4803
assert(DI4Y == 4 * 365 + 1);
4804
assert(DI4Y == days_before_year(4+1));
4806
/* Similarly, a 400-year cycle has an extra leap day over what we'd
4807
* get from pasting together 4 100-year cycles.
4809
assert(DI400Y == 4 * DI100Y + 1);
4810
assert(DI400Y == days_before_year(400+1));
4812
/* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4813
* pasting together 25 4-year cycles.
4815
assert(DI100Y == 25 * DI4Y - 1);
4816
assert(DI100Y == days_before_year(100+1));
4818
us_per_us = PyLong_FromLong(1);
4819
us_per_ms = PyLong_FromLong(1000);
4820
us_per_second = PyLong_FromLong(1000000);
4821
us_per_minute = PyLong_FromLong(60000000);
4822
seconds_per_day = PyLong_FromLong(24 * 3600);
4823
if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
4824
us_per_minute == NULL || seconds_per_day == NULL)
4827
/* The rest are too big for 32-bit ints, but even
4828
* us_per_week fits in 40 bits, so doubles should be exact.
4830
us_per_hour = PyLong_FromDouble(3600000000.0);
4831
us_per_day = PyLong_FromDouble(86400000000.0);
4832
us_per_week = PyLong_FromDouble(604800000000.0);
4833
if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
4798
/* A 4-year cycle has an extra leap day over what we'd get from
4799
* pasting together 4 single years.
4801
assert(DI4Y == 4 * 365 + 1);
4802
assert(DI4Y == days_before_year(4+1));
4804
/* Similarly, a 400-year cycle has an extra leap day over what we'd
4805
* get from pasting together 4 100-year cycles.
4807
assert(DI400Y == 4 * DI100Y + 1);
4808
assert(DI400Y == days_before_year(400+1));
4810
/* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4811
* pasting together 25 4-year cycles.
4813
assert(DI100Y == 25 * DI4Y - 1);
4814
assert(DI100Y == days_before_year(100+1));
4816
us_per_us = PyLong_FromLong(1);
4817
us_per_ms = PyLong_FromLong(1000);
4818
us_per_second = PyLong_FromLong(1000000);
4819
us_per_minute = PyLong_FromLong(60000000);
4820
seconds_per_day = PyLong_FromLong(24 * 3600);
4821
if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
4822
us_per_minute == NULL || seconds_per_day == NULL)
4825
/* The rest are too big for 32-bit ints, but even
4826
* us_per_week fits in 40 bits, so doubles should be exact.
4828
us_per_hour = PyLong_FromDouble(3600000000.0);
4829
us_per_day = PyLong_FromDouble(86400000000.0);
4830
us_per_week = PyLong_FromDouble(604800000000.0);
4831
if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
4838
4836
/* ---------------------------------------------------------------------------
4839
4837
Some time zone algebra. For a datetime x, let
4840
4838
x.n = x stripped of its timezone -- its naive time.
4841
4839
x.o = x.utcoffset(), and assuming that doesn't raise an exception or
4843
4841
x.d = x.dst(), and assuming that doesn't raise an exception or
4845
4843
x.s = x's standard offset, x.o - x.d
4847
4845
Now some derived rules, where k is a duration (timedelta).