~ubuntu-branches/ubuntu/natty/python3.1/natty-security

« back to all changes in this revision

Viewing changes to Modules/datetimemodule.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2010-07-06 16:52:42 UTC
  • mfrom: (1.2.1 upstream) (2.1.11 sid)
  • Revision ID: james.westby@ubuntu.com-20100706165242-2xv4i019r3et6c0j
Tags: 3.1.2+20100706-1ubuntu1
* Merge with Debian; remaining changes:
  - Regenerate the control file.
  - Add debian/patches/overwrite-semaphore-check for Lucid buildds.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
 * final result fits in a C int (this can be an issue on 64-bit boxes).
26
26
 */
27
27
#if SIZEOF_INT < 4
28
 
#       error "datetime.c requires that C int have at least 32 bits"
 
28
#       error "datetime.c requires that C int have at least 32 bits"
29
29
#endif
30
30
 
31
31
#define MINYEAR 1
32
32
#define MAXYEAR 9999
 
33
#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
33
34
 
34
35
/* Nine decimal digits is easy to communicate, and leaves enough room
35
36
 * so that two delta days can be added w/o fear of overflowing a signed
39
40
#define MAX_DELTA_DAYS 999999999
40
41
 
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
49
50
 
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))
55
56
 
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)))
64
65
 
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)))
77
78
 
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)
82
83
 
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))
86
87
 
87
88
/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
88
89
 * p->hastzinfo.
89
90
 */
90
 
#define HASTZINFO(p)            (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
 
91
#define HASTZINFO(p)            (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
91
92
 
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
94
 
 *      1 <= M <= 12
 
95
 *      1 <= M <= 12
95
96
 */
96
97
#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
97
98
 
111
112
 * iff (k^i)&(k^j) has sign bit set.
112
113
 */
113
114
#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
114
 
        ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
 
115
    ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
115
116
 
116
117
/* Compute Python divmod(x, y), returning the quotient and storing the
117
118
 * remainder into *r.  The quotient is the floor of x/y, and that's
125
126
static int
126
127
divmod(int x, int y, int *r)
127
128
{
128
 
        int quo;
 
129
    int quo;
129
130
 
130
 
        assert(y > 0);
131
 
        quo = x / y;
132
 
        *r = x - quo * y;
133
 
        if (*r < 0) {
134
 
                --quo;
135
 
                *r += y;
136
 
        }
137
 
        assert(0 <= *r && *r < y);
138
 
        return quo;
 
131
    assert(y > 0);
 
132
    quo = x / y;
 
133
    *r = x - quo * y;
 
134
    if (*r < 0) {
 
135
        --quo;
 
136
        *r += y;
 
137
    }
 
138
    assert(0 <= *r && *r < y);
 
139
    return quo;
139
140
}
140
141
 
141
142
/* Round a double to the nearest long.  |x| must be small enough to fit
144
145
static long
145
146
round_to_long(double x)
146
147
{
147
 
        if (x >= 0.0)
148
 
                x = floor(x + 0.5);
149
 
        else
150
 
                x = ceil(x - 0.5);
151
 
        return (long)x;
 
148
    if (x >= 0.0)
 
149
        x = floor(x + 0.5);
 
150
    else
 
151
        x = ceil(x - 0.5);
 
152
    return (long)x;
152
153
}
153
154
 
154
155
/* ---------------------------------------------------------------------------
160
161
 * are correct for non-leap years only.
161
162
 */
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
165
166
};
166
167
 
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
170
171
};
171
172
 
172
173
/* year -> 1 if leap year, else 0. */
173
174
static int
174
175
is_leap(int year)
175
176
{
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).
180
 
         */
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).
 
181
     */
 
182
    const unsigned int ayear = (unsigned int)year;
 
183
    return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
183
184
}
184
185
 
185
186
/* year, month -> number of days in that month in that year */
186
187
static int
187
188
days_in_month(int year, int month)
188
189
{
189
 
        assert(month >= 1);
190
 
        assert(month <= 12);
191
 
        if (month == 2 && is_leap(year))
192
 
                return 29;
193
 
        else
194
 
                return _days_in_month[month];
 
190
    assert(month >= 1);
 
191
    assert(month <= 12);
 
192
    if (month == 2 && is_leap(year))
 
193
        return 29;
 
194
    else
 
195
        return _days_in_month[month];
195
196
}
196
197
 
197
198
/* year, month -> number of days in year preceeding first day of month */
198
199
static int
199
200
days_before_month(int year, int month)
200
201
{
201
 
        int days;
 
202
    int days;
202
203
 
203
 
        assert(month >= 1);
204
 
        assert(month <= 12);
205
 
        days = _days_before_month[month];
206
 
        if (month > 2 && is_leap(year))
207
 
                ++days;
208
 
        return days;
 
204
    assert(month >= 1);
 
205
    assert(month <= 12);
 
206
    days = _days_before_month[month];
 
207
    if (month > 2 && is_leap(year))
 
208
        ++days;
 
209
    return days;
209
210
}
210
211
 
211
212
/* year -> number of days before January 1st of year.  Remember that we
214
215
static int
215
216
days_before_year(int year)
216
217
{
217
 
        int y = year - 1;
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.
222
 
         */
223
 
        assert (year >= 0);
224
 
        if (y >= 0)
225
 
                return y*365 + y/4 - y/100 + y/400;
226
 
        else {
227
 
                assert(y == -1);
228
 
                return -366;
229
 
        }
 
218
    int y = year - 1;
 
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.
 
223
     */
 
224
    assert (year >= 0);
 
225
    if (y >= 0)
 
226
        return y*365 + y/4 - y/100 + y/400;
 
227
    else {
 
228
        assert(y == -1);
 
229
        return -366;
 
230
    }
230
231
}
231
232
 
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.
234
235
 */
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  */
238
239
 
239
240
/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
240
241
static void
241
242
ord_to_ymd(int ordinal, int *year, int *month, int *day)
242
243
{
243
 
        int n, n1, n4, n100, n400, leapyear, preceding;
244
 
 
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
251
 
         * by DI400Y:
252
 
         *
253
 
         *    D  M   Y            n              n-1
254
 
         *    -- --- ----        ----------     ----------------
255
 
         *    31 Dec -400        -DI400Y       -DI400Y -1
256
 
         *     1 Jan -399         -DI400Y +1   -DI400Y      400-year boundary
257
 
         *    ...
258
 
         *    30 Dec  000        -1             -2
259
 
         *    31 Dec  000         0             -1
260
 
         *     1 Jan  001         1              0          400-year boundary
261
 
         *     2 Jan  001         2              1
262
 
         *     3 Jan  001         3              2
263
 
         *    ...
264
 
         *    31 Dec  400         DI400Y        DI400Y -1
265
 
         *     1 Jan  401         DI400Y +1     DI400Y      400-year boundary
266
 
         */
267
 
        assert(ordinal >= 1);
268
 
        --ordinal;
269
 
        n400 = ordinal / DI400Y;
270
 
        n = ordinal % DI400Y;
271
 
        *year = n400 * 400 + 1;
272
 
 
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
275
 
         * precede n.
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.
279
 
         */
280
 
        n100 = n / DI100Y;
281
 
        n = n % DI100Y;
282
 
 
283
 
        /* Now compute how many 4-year cycles precede it. */
284
 
        n4 = n / DI4Y;
285
 
        n = n % DI4Y;
286
 
 
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
289
 
         * 4-year cycle.
290
 
         */
291
 
        n1 = n / 365;
292
 
        n = n % 365;
293
 
 
294
 
        *year += n100 * 100 + n4 * 4 + n1;
295
 
        if (n1 == 4 || n100 == 4) {
296
 
                assert(n == 0);
297
 
                *year -= 1;
298
 
                *month = 12;
299
 
                *day = 31;
300
 
                return;
301
 
        }
302
 
 
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
305
 
         * large.
306
 
         */
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));
311
 
        if (preceding > n) {
312
 
                /* estimate is too large */
313
 
                *month -= 1;
314
 
                preceding -= days_in_month(*year, *month);
315
 
        }
316
 
        n -= preceding;
317
 
        assert(0 <= n);
318
 
        assert(n < days_in_month(*year, *month));
319
 
 
320
 
        *day = n + 1;
 
244
    int n, n1, n4, n100, n400, leapyear, preceding;
 
245
 
 
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
 
252
     * by DI400Y:
 
253
     *
 
254
     *    D  M   Y            n              n-1
 
255
     *    -- --- ----        ----------     ----------------
 
256
     *    31 Dec -400        -DI400Y       -DI400Y -1
 
257
     *     1 Jan -399         -DI400Y +1   -DI400Y      400-year boundary
 
258
     *    ...
 
259
     *    30 Dec  000        -1             -2
 
260
     *    31 Dec  000         0             -1
 
261
     *     1 Jan  001         1              0          400-year boundary
 
262
     *     2 Jan  001         2              1
 
263
     *     3 Jan  001         3              2
 
264
     *    ...
 
265
     *    31 Dec  400         DI400Y        DI400Y -1
 
266
     *     1 Jan  401         DI400Y +1     DI400Y      400-year boundary
 
267
     */
 
268
    assert(ordinal >= 1);
 
269
    --ordinal;
 
270
    n400 = ordinal / DI400Y;
 
271
    n = ordinal % DI400Y;
 
272
    *year = n400 * 400 + 1;
 
273
 
 
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
 
276
     * precede n.
 
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.
 
280
     */
 
281
    n100 = n / DI100Y;
 
282
    n = n % DI100Y;
 
283
 
 
284
    /* Now compute how many 4-year cycles precede it. */
 
285
    n4 = n / DI4Y;
 
286
    n = n % DI4Y;
 
287
 
 
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
 
290
     * 4-year cycle.
 
291
     */
 
292
    n1 = n / 365;
 
293
    n = n % 365;
 
294
 
 
295
    *year += n100 * 100 + n4 * 4 + n1;
 
296
    if (n1 == 4 || n100 == 4) {
 
297
        assert(n == 0);
 
298
        *year -= 1;
 
299
        *month = 12;
 
300
        *day = 31;
 
301
        return;
 
302
    }
 
303
 
 
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
 
306
     * large.
 
307
     */
 
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));
 
312
    if (preceding > n) {
 
313
        /* estimate is too large */
 
314
        *month -= 1;
 
315
        preceding -= days_in_month(*year, *month);
 
316
    }
 
317
    n -= preceding;
 
318
    assert(0 <= n);
 
319
    assert(n < days_in_month(*year, *month));
 
320
 
 
321
    *day = n + 1;
321
322
}
322
323
 
323
324
/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
324
325
static int
325
326
ymd_to_ord(int year, int month, int day)
326
327
{
327
 
        return days_before_year(year) + days_before_month(year, month) + day;
 
328
    return days_before_year(year) + days_before_month(year, month) + day;
328
329
}
329
330
 
330
331
/* Day of week, where Monday==0, ..., Sunday==6.  1/1/1 was a Monday. */
331
332
static int
332
333
weekday(int year, int month, int day)
333
334
{
334
 
        return (ymd_to_ord(year, month, day) + 6) % 7;
 
335
    return (ymd_to_ord(year, month, day) + 6) % 7;
335
336
}
336
337
 
337
338
/* Ordinal of the Monday starting week 1 of the ISO year.  Week 1 is the
340
341
static int
341
342
iso_week1_monday(int year)
342
343
{
343
 
        int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
344
 
        /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
345
 
        int first_weekday = (first_day + 6) % 7;
346
 
        /* ordinal of closest Monday at or before 1/1 */
347
 
        int week1_monday  = first_day - first_weekday;
 
344
    int first_day = ymd_to_ord(year, 1, 1);     /* ord of 1/1 */
 
345
    /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
 
346
    int first_weekday = (first_day + 6) % 7;
 
347
    /* ordinal of closest Monday at or before 1/1 */
 
348
    int week1_monday  = first_day - first_weekday;
348
349
 
349
 
        if (first_weekday > 3)  /* if 1/1 was Fri, Sat, Sun */
350
 
                week1_monday += 7;
351
 
        return week1_monday;
 
350
    if (first_weekday > 3)      /* if 1/1 was Fri, Sat, Sun */
 
351
        week1_monday += 7;
 
352
    return week1_monday;
352
353
}
353
354
 
354
355
/* ---------------------------------------------------------------------------
361
362
static int
362
363
check_delta_day_range(int days)
363
364
{
364
 
        if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
365
 
                return 0;
366
 
        PyErr_Format(PyExc_OverflowError,
367
 
                     "days=%d; must have magnitude <= %d",
368
 
                     days, MAX_DELTA_DAYS);
369
 
        return -1;
 
365
    if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
 
366
        return 0;
 
367
    PyErr_Format(PyExc_OverflowError,
 
368
                 "days=%d; must have magnitude <= %d",
 
369
                 days, MAX_DELTA_DAYS);
 
370
    return -1;
370
371
}
371
372
 
372
373
/* Check that date arguments are in range.  Return 0 if they are.  If they
376
377
check_date_args(int year, int month, int day)
377
378
{
378
379
 
379
 
        if (year < MINYEAR || year > MAXYEAR) {
380
 
                PyErr_SetString(PyExc_ValueError,
381
 
                                "year is out of range");
382
 
                return -1;
383
 
        }
384
 
        if (month < 1 || month > 12) {
385
 
                PyErr_SetString(PyExc_ValueError,
386
 
                                "month must be in 1..12");
387
 
                return -1;
388
 
        }
389
 
        if (day < 1 || day > days_in_month(year, month)) {
390
 
                PyErr_SetString(PyExc_ValueError,
391
 
                                "day is out of range for month");
392
 
                return -1;
393
 
        }
394
 
        return 0;
 
380
    if (year < MINYEAR || year > MAXYEAR) {
 
381
        PyErr_SetString(PyExc_ValueError,
 
382
                        "year is out of range");
 
383
        return -1;
 
384
    }
 
385
    if (month < 1 || month > 12) {
 
386
        PyErr_SetString(PyExc_ValueError,
 
387
                        "month must be in 1..12");
 
388
        return -1;
 
389
    }
 
390
    if (day < 1 || day > days_in_month(year, month)) {
 
391
        PyErr_SetString(PyExc_ValueError,
 
392
                        "day is out of range for month");
 
393
        return -1;
 
394
    }
 
395
    return 0;
395
396
}
396
397
 
397
398
/* Check that time arguments are in range.  Return 0 if they are.  If they
400
401
static int
401
402
check_time_args(int h, int m, int s, int us)
402
403
{
403
 
        if (h < 0 || h > 23) {
404
 
                PyErr_SetString(PyExc_ValueError,
405
 
                                "hour must be in 0..23");
406
 
                return -1;
407
 
        }
408
 
        if (m < 0 || m > 59) {
409
 
                PyErr_SetString(PyExc_ValueError,
410
 
                                "minute must be in 0..59");
411
 
                return -1;
412
 
        }
413
 
        if (s < 0 || s > 59) {
414
 
                PyErr_SetString(PyExc_ValueError,
415
 
                                "second must be in 0..59");
416
 
                return -1;
417
 
        }
418
 
        if (us < 0 || us > 999999) {
419
 
                PyErr_SetString(PyExc_ValueError,
420
 
                                "microsecond must be in 0..999999");
421
 
                return -1;
422
 
        }
423
 
        return 0;
 
404
    if (h < 0 || h > 23) {
 
405
        PyErr_SetString(PyExc_ValueError,
 
406
                        "hour must be in 0..23");
 
407
        return -1;
 
408
    }
 
409
    if (m < 0 || m > 59) {
 
410
        PyErr_SetString(PyExc_ValueError,
 
411
                        "minute must be in 0..59");
 
412
        return -1;
 
413
    }
 
414
    if (s < 0 || s > 59) {
 
415
        PyErr_SetString(PyExc_ValueError,
 
416
                        "second must be in 0..59");
 
417
        return -1;
 
418
    }
 
419
    if (us < 0 || us > 999999) {
 
420
        PyErr_SetString(PyExc_ValueError,
 
421
                        "microsecond must be in 0..999999");
 
422
        return -1;
 
423
    }
 
424
    return 0;
424
425
}
425
426
 
426
427
/* ---------------------------------------------------------------------------
436
437
static void
437
438
normalize_pair(int *hi, int *lo, int factor)
438
439
{
439
 
        assert(factor > 0);
440
 
        assert(lo != hi);
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));
445
 
                *hi = new_hi;
446
 
        }
447
 
        assert(0 <= *lo && *lo < factor);
 
440
    assert(factor > 0);
 
441
    assert(lo != hi);
 
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));
 
446
        *hi = new_hi;
 
447
    }
 
448
    assert(0 <= *lo && *lo < factor);
448
449
}
449
450
 
450
451
/* Fiddle days (d), seconds (s), and microseconds (us) so that
451
 
 *      0 <= *s < 24*3600
452
 
 *      0 <= *us < 1000000
 
452
 *      0 <= *s < 24*3600
 
453
 *      0 <= *us < 1000000
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.
455
456
 */
456
457
static void
457
458
normalize_d_s_us(int *d, int *s, int *us)
458
459
{
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.
463
 
                 */
 
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.
 
464
         */
464
465
 
465
 
        }
466
 
        if (*s < 0 || *s >= 24*3600) {
467
 
                normalize_pair(d, s, 24*3600);
468
 
                /* |d| can't be bigger than about
469
 
                 * |original d| +
470
 
                 * (|original s| + |original us|/1000000) / (24*3600) now.
471
 
                 */
472
 
        }
473
 
        assert(0 <= *s && *s < 24*3600);
474
 
        assert(0 <= *us && *us < 1000000);
 
466
    }
 
467
    if (*s < 0 || *s >= 24*3600) {
 
468
        normalize_pair(d, s, 24*3600);
 
469
        /* |d| can't be bigger than about
 
470
         * |original d| +
 
471
         * (|original s| + |original us|/1000000) / (24*3600) now.
 
472
         */
 
473
    }
 
474
    assert(0 <= *s && *s < 24*3600);
 
475
    assert(0 <= *us && *us < 1000000);
475
476
}
476
477
 
477
478
/* Fiddle years (y), months (m), and days (d) so that
478
 
 *      1 <= *m <= 12
479
 
 *      1 <= *d <= days_in_month(*y, *m)
 
479
 *      1 <= *m <= 12
 
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.
482
483
 */
483
 
static void
 
484
static int
484
485
normalize_y_m_d(int *y, int *m, int *d)
485
486
{
486
 
        int dim;        /* # of days in month */
487
 
 
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.
493
 
         */
494
 
        if (*m < 1 || *m > 12) {
495
 
                --*m;
496
 
                normalize_pair(y, m, 12);
497
 
                ++*m;
498
 
                /* |y| can't be bigger than about
499
 
                 * |original y| + |original m|/12 now.
500
 
                 */
501
 
        }
502
 
        assert(1 <= *m && *m <= 12);
503
 
 
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.
508
 
         */
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).
514
 
                 */
515
 
                if (*d == 0) {
516
 
                        --*m;
517
 
                        if (*m > 0)
518
 
                                *d = days_in_month(*y, *m);
519
 
                        else {
520
 
                                --*y;
521
 
                                *m = 12;
522
 
                                *d = 31;
523
 
                        }
524
 
                }
525
 
                else if (*d == dim + 1) {
526
 
                        /* move forward a day */
527
 
                        ++*m;
528
 
                        *d = 1;
529
 
                        if (*m > 12) {
530
 
                                *m = 1;
531
 
                                ++*y;
532
 
                        }
533
 
                }
534
 
                else {
535
 
                        int ordinal = ymd_to_ord(*y, *m, 1) +
536
 
                                                  *d - 1;
537
 
                        ord_to_ymd(ordinal, y, m, d);
538
 
                }
539
 
        }
540
 
        assert(*m > 0);
541
 
        assert(*d > 0);
 
487
    int dim;            /* # of days in month */
 
488
 
 
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.
 
494
     */
 
495
    if (*m < 1 || *m > 12) {
 
496
        --*m;
 
497
        normalize_pair(y, m, 12);
 
498
        ++*m;
 
499
        /* |y| can't be bigger than about
 
500
         * |original y| + |original m|/12 now.
 
501
         */
 
502
    }
 
503
    assert(1 <= *m && *m <= 12);
 
504
 
 
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.
 
509
     */
 
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).
 
515
         */
 
516
        if (*d == 0) {
 
517
            --*m;
 
518
            if (*m > 0)
 
519
                *d = days_in_month(*y, *m);
 
520
            else {
 
521
                --*y;
 
522
                *m = 12;
 
523
                *d = 31;
 
524
            }
 
525
        }
 
526
        else if (*d == dim + 1) {
 
527
            /* move forward a day */
 
528
            ++*m;
 
529
            *d = 1;
 
530
            if (*m > 12) {
 
531
                *m = 1;
 
532
                ++*y;
 
533
            }
 
534
        }
 
535
        else {
 
536
            int ordinal = ymd_to_ord(*y, *m, 1) +
 
537
                                      *d - 1;
 
538
            if (ordinal < 1 || ordinal > MAXORDINAL) {
 
539
                goto error;
 
540
            } else {
 
541
                ord_to_ymd(ordinal, y, m, d);
 
542
                return 0;
 
543
            }
 
544
        }
 
545
    }
 
546
    assert(*m > 0);
 
547
    assert(*d > 0);
 
548
    if (MINYEAR <= *y && *y <= MAXYEAR)
 
549
        return 0;
 
550
 error:
 
551
    PyErr_SetString(PyExc_OverflowError,
 
552
            "date value out of range");
 
553
    return -1;
 
554
 
542
555
}
543
556
 
544
557
/* Fiddle out-of-bounds months and days so that the result makes some kind
548
561
static int
549
562
normalize_date(int *year, int *month, int *day)
550
563
{
551
 
        int result;
552
 
 
553
 
        normalize_y_m_d(year, month, day);
554
 
        if (MINYEAR <= *year && *year <= MAXYEAR)
555
 
                result = 0;
556
 
        else {
557
 
                PyErr_SetString(PyExc_OverflowError,
558
 
                                "date value out of range");
559
 
                result = -1;
560
 
        }
561
 
        return result;
 
564
    return normalize_y_m_d(year, month, day);
562
565
}
563
566
 
564
567
/* Force all the datetime fields into range.  The parameters are both
569
572
                   int *hour, int *minute, int *second,
570
573
                   int *microsecond)
571
574
{
572
 
        normalize_pair(second, microsecond, 1000000);
573
 
        normalize_pair(minute, second, 60);
574
 
        normalize_pair(hour, minute, 60);
575
 
        normalize_pair(day, hour, 24);
576
 
        return normalize_date(year, month, day);
 
575
    normalize_pair(second, microsecond, 1000000);
 
576
    normalize_pair(minute, second, 60);
 
577
    normalize_pair(hour, minute, 60);
 
578
    normalize_pair(day, hour, 24);
 
579
    return normalize_date(year, month, day);
577
580
}
578
581
 
579
582
/* ---------------------------------------------------------------------------
600
603
static PyObject *
601
604
time_alloc(PyTypeObject *type, Py_ssize_t aware)
602
605
{
603
 
        PyObject *self;
 
606
    PyObject *self;
604
607
 
605
 
        self = (PyObject *)
606
 
                PyObject_MALLOC(aware ?
607
 
                                sizeof(PyDateTime_Time) :
608
 
                                sizeof(_PyDateTime_BaseTime));
609
 
        if (self == NULL)
610
 
                return (PyObject *)PyErr_NoMemory();
611
 
        PyObject_INIT(self, type);
612
 
        return self;
 
608
    self = (PyObject *)
 
609
        PyObject_MALLOC(aware ?
 
610
                        sizeof(PyDateTime_Time) :
 
611
                sizeof(_PyDateTime_BaseTime));
 
612
    if (self == NULL)
 
613
        return (PyObject *)PyErr_NoMemory();
 
614
    PyObject_INIT(self, type);
 
615
    return self;
613
616
}
614
617
 
615
618
static PyObject *
616
619
datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
617
620
{
618
 
        PyObject *self;
 
621
    PyObject *self;
619
622
 
620
 
        self = (PyObject *)
621
 
                PyObject_MALLOC(aware ?
622
 
                                sizeof(PyDateTime_DateTime) :
623
 
                                sizeof(_PyDateTime_BaseDateTime));
624
 
        if (self == NULL)
625
 
                return (PyObject *)PyErr_NoMemory();
626
 
        PyObject_INIT(self, type);
627
 
        return self;
 
623
    self = (PyObject *)
 
624
        PyObject_MALLOC(aware ?
 
625
                        sizeof(PyDateTime_DateTime) :
 
626
                sizeof(_PyDateTime_BaseDateTime));
 
627
    if (self == NULL)
 
628
        return (PyObject *)PyErr_NoMemory();
 
629
    PyObject_INIT(self, type);
 
630
    return self;
628
631
}
629
632
 
630
633
/* ---------------------------------------------------------------------------
636
639
static void
637
640
set_date_fields(PyDateTime_Date *self, int y, int m, int d)
638
641
{
639
 
        self->hashcode = -1;
640
 
        SET_YEAR(self, y);
641
 
        SET_MONTH(self, m);
642
 
        SET_DAY(self, d);
 
642
    self->hashcode = -1;
 
643
    SET_YEAR(self, y);
 
644
    SET_MONTH(self, m);
 
645
    SET_DAY(self, d);
643
646
}
644
647
 
645
648
/* ---------------------------------------------------------------------------
650
653
static PyObject *
651
654
new_date_ex(int year, int month, int day, PyTypeObject *type)
652
655
{
653
 
        PyDateTime_Date *self;
 
656
    PyDateTime_Date *self;
654
657
 
655
 
        self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
656
 
        if (self != NULL)
657
 
                set_date_fields(self, year, month, day);
658
 
        return (PyObject *) self;
 
658
    self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
 
659
    if (self != NULL)
 
660
        set_date_fields(self, year, month, day);
 
661
    return (PyObject *) self;
659
662
}
660
663
 
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)
663
666
 
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)
668
671
{
669
 
        PyDateTime_DateTime *self;
670
 
        char aware = tzinfo != Py_None;
 
672
    PyDateTime_DateTime *self;
 
673
    char aware = tzinfo != Py_None;
671
674
 
672
 
        self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
673
 
        if (self != NULL) {
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);
680
 
                if (aware) {
681
 
                        Py_INCREF(tzinfo);
682
 
                        self->tzinfo = tzinfo;
683
 
                }
684
 
        }
685
 
        return (PyObject *)self;
 
675
    self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
 
676
    if (self != NULL) {
 
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);
 
683
        if (aware) {
 
684
            Py_INCREF(tzinfo);
 
685
            self->tzinfo = tzinfo;
 
686
        }
 
687
    }
 
688
    return (PyObject *)self;
686
689
}
687
690
 
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)
691
694
 
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)
696
699
{
697
 
        PyDateTime_Time *self;
698
 
        char aware = tzinfo != Py_None;
 
700
    PyDateTime_Time *self;
 
701
    char aware = tzinfo != Py_None;
699
702
 
700
 
        self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
701
 
        if (self != NULL) {
702
 
                self->hastzinfo = aware;
703
 
                self->hashcode = -1;
704
 
                TIME_SET_HOUR(self, hour);
705
 
                TIME_SET_MINUTE(self, minute);
706
 
                TIME_SET_SECOND(self, second);
707
 
                TIME_SET_MICROSECOND(self, usecond);
708
 
                if (aware) {
709
 
                        Py_INCREF(tzinfo);
710
 
                        self->tzinfo = tzinfo;
711
 
                }
712
 
        }
713
 
        return (PyObject *)self;
 
703
    self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
 
704
    if (self != NULL) {
 
705
        self->hastzinfo = aware;
 
706
        self->hashcode = -1;
 
707
        TIME_SET_HOUR(self, hour);
 
708
        TIME_SET_MINUTE(self, minute);
 
709
        TIME_SET_SECOND(self, second);
 
710
        TIME_SET_MICROSECOND(self, usecond);
 
711
        if (aware) {
 
712
            Py_INCREF(tzinfo);
 
713
            self->tzinfo = tzinfo;
 
714
        }
 
715
    }
 
716
    return (PyObject *)self;
714
717
}
715
718
 
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)
718
721
 
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
724
727
 */
725
728
static PyObject *
726
729
new_delta_ex(int days, int seconds, int microseconds, int normalize,
727
 
             PyTypeObject *type)
 
730
             PyTypeObject *type)
728
731
{
729
 
        PyDateTime_Delta *self;
730
 
 
731
 
        if (normalize)
732
 
                normalize_d_s_us(&days, &seconds, &microseconds);
733
 
        assert(0 <= seconds && seconds < 24*3600);
734
 
        assert(0 <= microseconds && microseconds < 1000000);
735
 
 
736
 
        if (check_delta_day_range(days) < 0)
737
 
                return NULL;
738
 
 
739
 
        self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
740
 
        if (self != NULL) {
741
 
                self->hashcode = -1;
742
 
                SET_TD_DAYS(self, days);
743
 
                SET_TD_SECONDS(self, seconds);
744
 
                SET_TD_MICROSECONDS(self, microseconds);
745
 
        }
746
 
        return (PyObject *) self;
 
732
    PyDateTime_Delta *self;
 
733
 
 
734
    if (normalize)
 
735
        normalize_d_s_us(&days, &seconds, &microseconds);
 
736
    assert(0 <= seconds && seconds < 24*3600);
 
737
    assert(0 <= microseconds && microseconds < 1000000);
 
738
 
 
739
    if (check_delta_day_range(days) < 0)
 
740
        return NULL;
 
741
 
 
742
    self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
 
743
    if (self != NULL) {
 
744
        self->hashcode = -1;
 
745
        SET_TD_DAYS(self, days);
 
746
        SET_TD_SECONDS(self, seconds);
 
747
        SET_TD_MICROSECONDS(self, microseconds);
 
748
    }
 
749
    return (PyObject *) self;
747
750
}
748
751
 
749
 
#define new_delta(d, s, us, normalize)  \
750
 
        new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
 
752
#define new_delta(d, s, us, normalize)  \
 
753
    new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
751
754
 
752
755
/* ---------------------------------------------------------------------------
753
756
 * tzinfo helpers.
759
762
static int
760
763
check_tzinfo_subclass(PyObject *p)
761
764
{
762
 
        if (p == Py_None || PyTZInfo_Check(p))
763
 
                return 0;
764
 
        PyErr_Format(PyExc_TypeError,
765
 
                     "tzinfo argument must be None or of a tzinfo subclass, "
766
 
                     "not type '%s'",
767
 
                     Py_TYPE(p)->tp_name);
768
 
        return -1;
 
765
    if (p == Py_None || PyTZInfo_Check(p))
 
766
        return 0;
 
767
    PyErr_Format(PyExc_TypeError,
 
768
                 "tzinfo argument must be None or of a tzinfo subclass, "
 
769
                 "not type '%s'",
 
770
                 Py_TYPE(p)->tp_name);
 
771
    return -1;
769
772
}
770
773
 
771
774
/* Return tzinfo.methname(tzinfoarg), without any checking of results.
774
777
static PyObject *
775
778
call_tzinfo_method(PyObject *tzinfo, char *methname, PyObject *tzinfoarg)
776
779
{
777
 
        PyObject *result;
 
780
    PyObject *result;
778
781
 
779
 
        assert(tzinfo && methname && tzinfoarg);
780
 
        assert(check_tzinfo_subclass(tzinfo) >= 0);
781
 
        if (tzinfo == Py_None) {
782
 
                result = Py_None;
783
 
                Py_INCREF(result);
784
 
        }
785
 
        else
786
 
                result = PyObject_CallMethod(tzinfo, methname, "O", tzinfoarg);
787
 
        return result;
 
782
    assert(tzinfo && methname && tzinfoarg);
 
783
    assert(check_tzinfo_subclass(tzinfo) >= 0);
 
784
    if (tzinfo == Py_None) {
 
785
        result = Py_None;
 
786
        Py_INCREF(result);
 
787
    }
 
788
    else
 
789
        result = PyObject_CallMethod(tzinfo, methname, "O", tzinfoarg);
 
790
    return result;
788
791
}
789
792
 
790
793
/* If self has a tzinfo member, return a BORROWED reference to it.  Else
794
797
static PyObject *
795
798
get_tzinfo_member(PyObject *self)
796
799
{
797
 
        PyObject *tzinfo = NULL;
798
 
 
799
 
        if (PyDateTime_Check(self) && HASTZINFO(self))
800
 
                tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
801
 
        else if (PyTime_Check(self) && HASTZINFO(self))
802
 
                tzinfo = ((PyDateTime_Time *)self)->tzinfo;
803
 
 
804
 
        return tzinfo;
 
800
    PyObject *tzinfo = NULL;
 
801
 
 
802
    if (PyDateTime_Check(self) && HASTZINFO(self))
 
803
        tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
 
804
    else if (PyTime_Check(self) && HASTZINFO(self))
 
805
        tzinfo = ((PyDateTime_Time *)self)->tzinfo;
 
806
 
 
807
    return tzinfo;
805
808
}
806
809
 
807
810
/* Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the
814
817
 */
815
818
static int
816
819
call_utc_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg,
817
 
                       int *none)
 
820
                       int *none)
818
821
{
819
 
        PyObject *u;
820
 
        int result = -1;
821
 
 
822
 
        assert(tzinfo != NULL);
823
 
        assert(PyTZInfo_Check(tzinfo));
824
 
        assert(tzinfoarg != NULL);
825
 
 
826
 
        *none = 0;
827
 
        u = call_tzinfo_method(tzinfo, name, tzinfoarg);
828
 
        if (u == NULL)
829
 
                return -1;
830
 
 
831
 
        else if (u == Py_None) {
832
 
                result = 0;
833
 
                *none = 1;
834
 
        }
835
 
        else if (PyDelta_Check(u)) {
836
 
                const int days = GET_TD_DAYS(u);
837
 
                if (days < -1 || days > 0)
838
 
                        result = 24*60; /* trigger ValueError below */
839
 
                else {
840
 
                        /* next line can't overflow because we know days
841
 
                         * is -1 or 0 now
842
 
                         */
843
 
                        int ss = days * 24 * 3600 + GET_TD_SECONDS(u);
844
 
                        result = divmod(ss, 60, &ss);
845
 
                        if (ss || GET_TD_MICROSECONDS(u)) {
846
 
                                PyErr_Format(PyExc_ValueError,
847
 
                                             "tzinfo.%s() must return a "
848
 
                                             "whole number of minutes",
849
 
                                             name);
850
 
                                result = -1;
851
 
                        }
852
 
                }
853
 
        }
854
 
        else {
855
 
                PyErr_Format(PyExc_TypeError,
856
 
                             "tzinfo.%s() must return None or "
857
 
                             "timedelta, not '%s'",
858
 
                             name, Py_TYPE(u)->tp_name);
859
 
        }
860
 
 
861
 
        Py_DECREF(u);
862
 
        if (result < -1439 || result > 1439) {
863
 
                PyErr_Format(PyExc_ValueError,
864
 
                             "tzinfo.%s() returned %d; must be in "
865
 
                             "-1439 .. 1439",
866
 
                             name, result);
867
 
                result = -1;
868
 
        }
869
 
        return result;
 
822
    PyObject *u;
 
823
    int result = -1;
 
824
 
 
825
    assert(tzinfo != NULL);
 
826
    assert(PyTZInfo_Check(tzinfo));
 
827
    assert(tzinfoarg != NULL);
 
828
 
 
829
    *none = 0;
 
830
    u = call_tzinfo_method(tzinfo, name, tzinfoarg);
 
831
    if (u == NULL)
 
832
        return -1;
 
833
 
 
834
    else if (u == Py_None) {
 
835
        result = 0;
 
836
        *none = 1;
 
837
    }
 
838
    else if (PyDelta_Check(u)) {
 
839
        const int days = GET_TD_DAYS(u);
 
840
        if (days < -1 || days > 0)
 
841
            result = 24*60;             /* trigger ValueError below */
 
842
        else {
 
843
            /* next line can't overflow because we know days
 
844
             * is -1 or 0 now
 
845
             */
 
846
            int ss = days * 24 * 3600 + GET_TD_SECONDS(u);
 
847
            result = divmod(ss, 60, &ss);
 
848
            if (ss || GET_TD_MICROSECONDS(u)) {
 
849
                PyErr_Format(PyExc_ValueError,
 
850
                             "tzinfo.%s() must return a "
 
851
                             "whole number of minutes",
 
852
                             name);
 
853
                result = -1;
 
854
            }
 
855
        }
 
856
    }
 
857
    else {
 
858
        PyErr_Format(PyExc_TypeError,
 
859
                     "tzinfo.%s() must return None or "
 
860
                     "timedelta, not '%s'",
 
861
                     name, Py_TYPE(u)->tp_name);
 
862
    }
 
863
 
 
864
    Py_DECREF(u);
 
865
    if (result < -1439 || result > 1439) {
 
866
        PyErr_Format(PyExc_ValueError,
 
867
                     "tzinfo.%s() returned %d; must be in "
 
868
                     "-1439 .. 1439",
 
869
                     name, result);
 
870
        result = -1;
 
871
    }
 
872
    return result;
870
873
}
871
874
 
872
875
/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
880
883
static int
881
884
call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
882
885
{
883
 
        return call_utc_tzinfo_method(tzinfo, "utcoffset", tzinfoarg, none);
 
886
    return call_utc_tzinfo_method(tzinfo, "utcoffset", tzinfoarg, none);
884
887
}
885
888
 
886
889
/* Call tzinfo.name(tzinfoarg), and return the offset as a timedelta or None.
887
890
 */
888
891
static PyObject *
889
892
offset_as_timedelta(PyObject *tzinfo, char *name, PyObject *tzinfoarg) {
890
 
        PyObject *result;
 
893
    PyObject *result;
891
894
 
892
 
        assert(tzinfo && name && tzinfoarg);
893
 
        if (tzinfo == Py_None) {
894
 
                result = Py_None;
895
 
                Py_INCREF(result);
896
 
        }
897
 
        else {
898
 
                int none;
899
 
                int offset = call_utc_tzinfo_method(tzinfo, name, tzinfoarg,
900
 
                                                    &none);
901
 
                if (offset < 0 && PyErr_Occurred())
902
 
                        return NULL;
903
 
                if (none) {
904
 
                        result = Py_None;
905
 
                        Py_INCREF(result);
906
 
                }
907
 
                else
908
 
                        result = new_delta(0, offset * 60, 0, 1);
909
 
        }
910
 
        return result;
 
895
    assert(tzinfo && name && tzinfoarg);
 
896
    if (tzinfo == Py_None) {
 
897
        result = Py_None;
 
898
        Py_INCREF(result);
 
899
    }
 
900
    else {
 
901
        int none;
 
902
        int offset = call_utc_tzinfo_method(tzinfo, name, tzinfoarg,
 
903
                                            &none);
 
904
        if (offset < 0 && PyErr_Occurred())
 
905
            return NULL;
 
906
        if (none) {
 
907
            result = Py_None;
 
908
            Py_INCREF(result);
 
909
        }
 
910
        else
 
911
            result = new_delta(0, offset * 60, 0, 1);
 
912
    }
 
913
    return result;
911
914
}
912
915
 
913
916
/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
921
924
static int
922
925
call_dst(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
923
926
{
924
 
        return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none);
 
927
    return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none);
925
928
}
926
929
 
927
930
/* Call tzinfo.tzname(tzinfoarg), and return the result.  tzinfo must be
933
936
static PyObject *
934
937
call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
935
938
{
936
 
        PyObject *result;
937
 
 
938
 
        assert(tzinfo != NULL);
939
 
        assert(check_tzinfo_subclass(tzinfo) >= 0);
940
 
        assert(tzinfoarg != NULL);
941
 
 
942
 
        if (tzinfo == Py_None) {
943
 
                result = Py_None;
944
 
                Py_INCREF(result);
945
 
        }
946
 
        else
947
 
                result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
948
 
 
949
 
        if (result != NULL && result != Py_None) {
950
 
                if (!PyUnicode_Check(result)) {
951
 
                        PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
952
 
                                     "return None or a string, not '%s'",
953
 
                                     Py_TYPE(result)->tp_name);
954
 
                        Py_DECREF(result);
955
 
                        result = NULL;
956
 
                }
957
 
                else if (!PyUnicode_Check(result)) {
958
 
                        PyObject *temp = PyUnicode_FromObject(result);
959
 
                        Py_DECREF(result);
960
 
                        result = temp;
961
 
                }
962
 
        }
963
 
        return result;
 
939
    PyObject *result;
 
940
 
 
941
    assert(tzinfo != NULL);
 
942
    assert(check_tzinfo_subclass(tzinfo) >= 0);
 
943
    assert(tzinfoarg != NULL);
 
944
 
 
945
    if (tzinfo == Py_None) {
 
946
        result = Py_None;
 
947
        Py_INCREF(result);
 
948
    }
 
949
    else
 
950
        result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
 
951
 
 
952
    if (result != NULL && result != Py_None) {
 
953
        if (!PyUnicode_Check(result)) {
 
954
            PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
 
955
                         "return None or a string, not '%s'",
 
956
                         Py_TYPE(result)->tp_name);
 
957
            Py_DECREF(result);
 
958
            result = NULL;
 
959
        }
 
960
    }
 
961
    return result;
964
962
}
965
963
 
966
964
typedef enum {
967
 
              /* an exception has been set; the caller should pass it on */
968
 
              OFFSET_ERROR,
969
 
 
970
 
              /* type isn't date, datetime, or time subclass */
971
 
              OFFSET_UNKNOWN,
972
 
 
973
 
              /* date,
974
 
               * datetime with !hastzinfo
975
 
               * datetime with None tzinfo,
976
 
               * datetime where utcoffset() returns None
977
 
               * time with !hastzinfo
978
 
               * time with None tzinfo,
979
 
               * time where utcoffset() returns None
980
 
               */
981
 
              OFFSET_NAIVE,
982
 
 
983
 
              /* time or datetime where utcoffset() doesn't return None */
984
 
              OFFSET_AWARE
 
965
              /* an exception has been set; the caller should pass it on */
 
966
          OFFSET_ERROR,
 
967
 
 
968
          /* type isn't date, datetime, or time subclass */
 
969
          OFFSET_UNKNOWN,
 
970
 
 
971
          /* date,
 
972
           * datetime with !hastzinfo
 
973
           * datetime with None tzinfo,
 
974
           * datetime where utcoffset() returns None
 
975
           * time with !hastzinfo
 
976
           * time with None tzinfo,
 
977
           * time where utcoffset() returns None
 
978
           */
 
979
          OFFSET_NAIVE,
 
980
 
 
981
          /* time or datetime where utcoffset() doesn't return None */
 
982
          OFFSET_AWARE
985
983
} naivety;
986
984
 
987
985
/* Classify an object as to whether it's naive or offset-aware.  See
993
991
static naivety
994
992
classify_utcoffset(PyObject *op, PyObject *tzinfoarg, int *offset)
995
993
{
996
 
        int none;
997
 
        PyObject *tzinfo;
 
994
    int none;
 
995
    PyObject *tzinfo;
998
996
 
999
 
        assert(tzinfoarg != NULL);
1000
 
        *offset = 0;
1001
 
        tzinfo = get_tzinfo_member(op); /* NULL means no tzinfo, not error */
1002
 
        if (tzinfo == Py_None)
1003
 
                return OFFSET_NAIVE;
1004
 
        if (tzinfo == NULL) {
1005
 
                /* note that a datetime passes the PyDate_Check test */
1006
 
                return (PyTime_Check(op) || PyDate_Check(op)) ?
1007
 
                       OFFSET_NAIVE : OFFSET_UNKNOWN;
1008
 
        }
1009
 
        *offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1010
 
        if (*offset == -1 && PyErr_Occurred())
1011
 
                return OFFSET_ERROR;
1012
 
        return none ? OFFSET_NAIVE : OFFSET_AWARE;
 
997
    assert(tzinfoarg != NULL);
 
998
    *offset = 0;
 
999
    tzinfo = get_tzinfo_member(op);     /* NULL means no tzinfo, not error */
 
1000
    if (tzinfo == Py_None)
 
1001
        return OFFSET_NAIVE;
 
1002
    if (tzinfo == NULL) {
 
1003
        /* note that a datetime passes the PyDate_Check test */
 
1004
        return (PyTime_Check(op) || PyDate_Check(op)) ?
 
1005
               OFFSET_NAIVE : OFFSET_UNKNOWN;
 
1006
    }
 
1007
    *offset = call_utcoffset(tzinfo, tzinfoarg, &none);
 
1008
    if (*offset == -1 && PyErr_Occurred())
 
1009
        return OFFSET_ERROR;
 
1010
    return none ? OFFSET_NAIVE : OFFSET_AWARE;
1013
1011
}
1014
1012
 
1015
1013
/* Classify two objects as to whether they're naive or offset-aware.
1023
1021
 */
1024
1022
static int
1025
1023
classify_two_utcoffsets(PyObject *o1, int *offset1, naivety *n1,
1026
 
                        PyObject *tzinfoarg1,
1027
 
                        PyObject *o2, int *offset2, naivety *n2,
1028
 
                        PyObject *tzinfoarg2)
 
1024
                        PyObject *tzinfoarg1,
 
1025
                        PyObject *o2, int *offset2, naivety *n2,
 
1026
                        PyObject *tzinfoarg2)
1029
1027
{
1030
 
        if (get_tzinfo_member(o1) == get_tzinfo_member(o2)) {
1031
 
                *offset1 = *offset2 = 0;
1032
 
                *n1 = *n2 = OFFSET_NAIVE;
1033
 
        }
1034
 
        else {
1035
 
                *n1 = classify_utcoffset(o1, tzinfoarg1, offset1);
1036
 
                if (*n1 == OFFSET_ERROR)
1037
 
                        return -1;
1038
 
                *n2 = classify_utcoffset(o2, tzinfoarg2, offset2);
1039
 
                if (*n2 == OFFSET_ERROR)
1040
 
                        return -1;
1041
 
        }
1042
 
        return 0;
 
1028
    if (get_tzinfo_member(o1) == get_tzinfo_member(o2)) {
 
1029
        *offset1 = *offset2 = 0;
 
1030
        *n1 = *n2 = OFFSET_NAIVE;
 
1031
    }
 
1032
    else {
 
1033
        *n1 = classify_utcoffset(o1, tzinfoarg1, offset1);
 
1034
        if (*n1 == OFFSET_ERROR)
 
1035
            return -1;
 
1036
        *n2 = classify_utcoffset(o2, tzinfoarg2, offset2);
 
1037
        if (*n2 == OFFSET_ERROR)
 
1038
            return -1;
 
1039
    }
 
1040
    return 0;
1043
1041
}
1044
1042
 
1045
1043
/* repr is like "someclass(arg1, arg2)".  If tzinfo isn't None,
1050
1048
static PyObject *
1051
1049
append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1052
1050
{
1053
 
        PyObject *temp;
 
1051
    PyObject *temp;
1054
1052
 
1055
 
        assert(PyUnicode_Check(repr));
1056
 
        assert(tzinfo);
1057
 
        if (tzinfo == Py_None)
1058
 
                return repr;
1059
 
        /* Get rid of the trailing ')'. */
1060
 
        assert(PyUnicode_AS_UNICODE(repr)[PyUnicode_GET_SIZE(repr)-1] == ')');
1061
 
        temp = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(repr),
1062
 
                                          PyUnicode_GET_SIZE(repr) - 1);
1063
 
        Py_DECREF(repr);
1064
 
        if (temp == NULL)
1065
 
                return NULL;
1066
 
        repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1067
 
        Py_DECREF(temp);
1068
 
        return repr;
 
1053
    assert(PyUnicode_Check(repr));
 
1054
    assert(tzinfo);
 
1055
    if (tzinfo == Py_None)
 
1056
        return repr;
 
1057
    /* Get rid of the trailing ')'. */
 
1058
    assert(PyUnicode_AS_UNICODE(repr)[PyUnicode_GET_SIZE(repr)-1] == ')');
 
1059
    temp = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(repr),
 
1060
                                      PyUnicode_GET_SIZE(repr) - 1);
 
1061
    Py_DECREF(repr);
 
1062
    if (temp == NULL)
 
1063
        return NULL;
 
1064
    repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
 
1065
    Py_DECREF(temp);
 
1066
    return repr;
1069
1067
}
1070
1068
 
1071
1069
/* ---------------------------------------------------------------------------
1075
1073
static PyObject *
1076
1074
format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
1077
1075
{
1078
 
        static const char *DayNames[] = {
1079
 
                "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1080
 
        };
1081
 
        static const char *MonthNames[] = {
1082
 
                "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1083
 
                "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1084
 
        };
1085
 
 
1086
 
        int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
1087
 
 
1088
 
        return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1089
 
                                    DayNames[wday], MonthNames[GET_MONTH(date)-1],
1090
 
                                    GET_DAY(date), hours, minutes, seconds,
1091
 
                                    GET_YEAR(date));
 
1076
    static const char *DayNames[] = {
 
1077
        "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
 
1078
    };
 
1079
    static const char *MonthNames[] = {
 
1080
        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
 
1081
        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
 
1082
    };
 
1083
 
 
1084
    int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
 
1085
 
 
1086
    return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
 
1087
                                DayNames[wday], MonthNames[GET_MONTH(date)-1],
 
1088
                                GET_DAY(date), hours, minutes, seconds,
 
1089
                                GET_YEAR(date));
1092
1090
}
1093
1091
 
1094
1092
/* Add an hours & minutes UTC offset string to buf.  buf has no more than
1103
1101
 */
1104
1102
static int
1105
1103
format_utcoffset(char *buf, size_t buflen, const char *sep,
1106
 
                PyObject *tzinfo, PyObject *tzinfoarg)
 
1104
                PyObject *tzinfo, PyObject *tzinfoarg)
1107
1105
{
1108
 
        int offset;
1109
 
        int hours;
1110
 
        int minutes;
1111
 
        char sign;
1112
 
        int none;
1113
 
 
1114
 
        assert(buflen >= 1);
1115
 
 
1116
 
        offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1117
 
        if (offset == -1 && PyErr_Occurred())
1118
 
                return -1;
1119
 
        if (none) {
1120
 
                *buf = '\0';
1121
 
                return 0;
1122
 
        }
1123
 
        sign = '+';
1124
 
        if (offset < 0) {
1125
 
                sign = '-';
1126
 
                offset = - offset;
1127
 
        }
1128
 
        hours = divmod(offset, 60, &minutes);
1129
 
        PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1130
 
        return 0;
 
1106
    int offset;
 
1107
    int hours;
 
1108
    int minutes;
 
1109
    char sign;
 
1110
    int none;
 
1111
 
 
1112
    assert(buflen >= 1);
 
1113
 
 
1114
    offset = call_utcoffset(tzinfo, tzinfoarg, &none);
 
1115
    if (offset == -1 && PyErr_Occurred())
 
1116
        return -1;
 
1117
    if (none) {
 
1118
        *buf = '\0';
 
1119
        return 0;
 
1120
    }
 
1121
    sign = '+';
 
1122
    if (offset < 0) {
 
1123
        sign = '-';
 
1124
        offset = - offset;
 
1125
    }
 
1126
    hours = divmod(offset, 60, &minutes);
 
1127
    PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
 
1128
    return 0;
1131
1129
}
1132
1130
 
1133
1131
static PyObject *
1134
1132
make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1135
1133
{
1136
 
        PyObject *temp;
1137
 
        PyObject *tzinfo = get_tzinfo_member(object);
1138
 
        PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
1139
 
        if (Zreplacement == NULL)
1140
 
                return NULL;
1141
 
        if (tzinfo == Py_None || tzinfo == NULL)
1142
 
                return Zreplacement;
1143
 
 
1144
 
        assert(tzinfoarg != NULL);
1145
 
        temp = call_tzname(tzinfo, tzinfoarg);
1146
 
        if (temp == NULL)
1147
 
                goto Error;
1148
 
        if (temp == Py_None) {
1149
 
                Py_DECREF(temp);
1150
 
                return Zreplacement;
1151
 
        }
1152
 
 
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.
1157
 
         */
1158
 
        Py_DECREF(Zreplacement);
1159
 
        Zreplacement = PyObject_CallMethod(temp, "replace", "ss", "%", "%%");
1160
 
        Py_DECREF(temp);
1161
 
        if (Zreplacement == NULL)
1162
 
                return NULL;
1163
 
        if (!PyUnicode_Check(Zreplacement)) {
1164
 
                PyErr_SetString(PyExc_TypeError,
1165
 
                                "tzname.replace() did not return a string");
1166
 
                goto Error;
1167
 
        }
1168
 
        return Zreplacement;
 
1134
    PyObject *temp;
 
1135
    PyObject *tzinfo = get_tzinfo_member(object);
 
1136
    PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
 
1137
    if (Zreplacement == NULL)
 
1138
        return NULL;
 
1139
    if (tzinfo == Py_None || tzinfo == NULL)
 
1140
        return Zreplacement;
 
1141
 
 
1142
    assert(tzinfoarg != NULL);
 
1143
    temp = call_tzname(tzinfo, tzinfoarg);
 
1144
    if (temp == NULL)
 
1145
        goto Error;
 
1146
    if (temp == Py_None) {
 
1147
        Py_DECREF(temp);
 
1148
        return Zreplacement;
 
1149
    }
 
1150
 
 
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.
 
1155
     */
 
1156
    Py_DECREF(Zreplacement);
 
1157
    Zreplacement = PyObject_CallMethod(temp, "replace", "ss", "%", "%%");
 
1158
    Py_DECREF(temp);
 
1159
    if (Zreplacement == NULL)
 
1160
        return NULL;
 
1161
    if (!PyUnicode_Check(Zreplacement)) {
 
1162
        PyErr_SetString(PyExc_TypeError,
 
1163
                        "tzname.replace() did not return a string");
 
1164
        goto Error;
 
1165
    }
 
1166
    return Zreplacement;
1169
1167
 
1170
1168
  Error:
1171
 
        Py_DECREF(Zreplacement);
1172
 
        return NULL;
 
1169
    Py_DECREF(Zreplacement);
 
1170
    return NULL;
1173
1171
}
1174
1172
 
1175
1173
static PyObject *
1176
1174
make_freplacement(PyObject *object)
1177
1175
{
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));
1183
 
        else
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));
 
1181
    else
 
1182
        sprintf(freplacement, "%06d", 0);
1185
1183
 
1186
 
        return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
 
1184
    return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
1187
1185
}
1188
1186
 
1189
1187
/* I sure don't want to reproduce the strftime code from the time module,
1195
1193
 */
1196
1194
static PyObject *
1197
1195
wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
1198
 
              PyObject *tzinfoarg)
 
1196
              PyObject *tzinfoarg)
1199
1197
{
1200
 
        PyObject *result = NULL;        /* guilty until proved innocent */
1201
 
 
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 */
1205
 
 
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 */
1209
 
 
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 */
1215
 
 
1216
 
        const char *ptoappend;  /* ptr to string to append to output buffer */
1217
 
        Py_ssize_t ntoappend;   /* # of bytes to append to output buffer */
1218
 
 
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);
1223
 
        if (!pin)
1224
 
                return NULL;
1225
 
 
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.
1234
 
         */
1235
 
        {
1236
 
                long year;
1237
 
                PyObject *pyyear = PySequence_GetItem(timetuple, 0);
1238
 
                if (pyyear == NULL) return NULL;
1239
 
                assert(PyLong_Check(pyyear));
1240
 
                year = PyLong_AsLong(pyyear);
1241
 
                Py_DECREF(pyyear);
1242
 
                if (year < 1900) {
1243
 
                        PyErr_Format(PyExc_ValueError, "year=%ld is before "
1244
 
                                     "1900; the datetime strftime() "
1245
 
                                     "methods require year >= 1900",
1246
 
                                     year);
1247
 
                        return NULL;
1248
 
                }
1249
 
        }
1250
 
 
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.
1254
 
         */
1255
 
        if (flen > INT_MAX - 1) {
1256
 
                PyErr_NoMemory();
1257
 
                goto Done;
1258
 
        }
1259
 
 
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);
1264
 
        usednew = 0;
1265
 
 
1266
 
        while ((ch = *pin++) != '\0') {
1267
 
                if (ch != '%') {
1268
 
                        ptoappend = pin - 1;
1269
 
                        ntoappend = 1;
1270
 
                }
1271
 
                else if ((ch = *pin++) == '\0') {
1272
 
                        /* There's a lone trailing %; doesn't make sense. */
1273
 
                        PyErr_SetString(PyExc_ValueError, "strftime format "
1274
 
                                        "ends with raw %");
1275
 
                        goto Done;
1276
 
                }
1277
 
                /* A % has been seen and ch is the character after it. */
1278
 
                else if (ch == 'z') {
1279
 
                        if (zreplacement == NULL) {
1280
 
                                /* format utcoffset */
1281
 
                                char buf[100];
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,
1288
 
                                                             sizeof(buf),
1289
 
                                                             "",
1290
 
                                                             tzinfo,
1291
 
                                                             tzinfoarg) < 0)
1292
 
                                                goto Done;
1293
 
                                        Py_DECREF(zreplacement);
1294
 
                                        zreplacement =
1295
 
                                          PyBytes_FromStringAndSize(buf,
1296
 
                                                                   strlen(buf));
1297
 
                                        if (zreplacement == NULL)
1298
 
                                                goto Done;
1299
 
                                }
1300
 
                        }
1301
 
                        assert(zreplacement != NULL);
1302
 
                        ptoappend = PyBytes_AS_STRING(zreplacement);
1303
 
                        ntoappend = PyBytes_GET_SIZE(zreplacement);
1304
 
                }
1305
 
                else if (ch == 'Z') {
1306
 
                        /* format tzname */
1307
 
                        if (Zreplacement == NULL) {
1308
 
                                Zreplacement = make_Zreplacement(object,
1309
 
                                                                 tzinfoarg);
1310
 
                                if (Zreplacement == NULL)
1311
 
                                        goto Done;
1312
 
                        }
1313
 
                        assert(Zreplacement != NULL);
1314
 
                        assert(PyUnicode_Check(Zreplacement));
1315
 
                        ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
1316
 
                                                              &ntoappend);
1317
 
                        ntoappend = Py_SIZE(Zreplacement);
1318
 
                }
1319
 
                else if (ch == 'f') {
1320
 
                        /* format microseconds */
1321
 
                        if (freplacement == NULL) {
1322
 
                                freplacement = make_freplacement(object);
1323
 
                                if (freplacement == NULL)
1324
 
                                        goto Done;
1325
 
                        }
1326
 
                        assert(freplacement != NULL);
1327
 
                        assert(PyBytes_Check(freplacement));
1328
 
                        ptoappend = PyBytes_AS_STRING(freplacement);
1329
 
                        ntoappend = PyBytes_GET_SIZE(freplacement);
1330
 
                }
1331
 
                else {
1332
 
                        /* percent followed by neither z nor Z */
1333
 
                        ptoappend = pin - 2;
1334
 
                        ntoappend = 2;
1335
 
                }
1336
 
 
1337
 
                /* Append the ntoappend chars starting at ptoappend to
1338
 
                 * the new format.
1339
 
                 */
1340
 
                if (ntoappend == 0)
1341
 
                        continue;
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 */
1347
 
                                PyErr_NoMemory();
1348
 
                                goto Done;
1349
 
                        }
1350
 
                        if (_PyBytes_Resize(&newfmt, bigger) < 0)
1351
 
                                goto Done;
1352
 
                        totalnew = bigger;
1353
 
                        pnew = PyBytes_AsString(newfmt) + usednew;
1354
 
                }
1355
 
                memcpy(pnew, ptoappend, ntoappend);
1356
 
                pnew += ntoappend;
1357
 
                usednew += ntoappend;
1358
 
                assert(usednew <= totalnew);
1359
 
        }  /* end while() */
1360
 
 
1361
 
        if (_PyBytes_Resize(&newfmt, usednew) < 0)
1362
 
                goto Done;
1363
 
        {
1364
 
                PyObject *format;
1365
 
                PyObject *time = PyImport_ImportModuleNoBlock("time");
1366
 
                if (time == NULL)
1367
 
                        goto Done;
1368
 
                format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1369
 
                if (format != NULL) {
1370
 
                        result = PyObject_CallMethod(time, "strftime", "OO",
1371
 
                                                     format, timetuple);
1372
 
                        Py_DECREF(format);
1373
 
                }
1374
 
                Py_DECREF(time);
1375
 
        }
 
1198
    PyObject *result = NULL;            /* guilty until proved innocent */
 
1199
 
 
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 */
 
1203
 
 
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 */
 
1207
 
 
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 */
 
1213
 
 
1214
    const char *ptoappend;      /* ptr to string to append to output buffer */
 
1215
    Py_ssize_t ntoappend;       /* # of bytes to append to output buffer */
 
1216
 
 
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);
 
1221
    if (!pin)
 
1222
        return NULL;
 
1223
 
 
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.
 
1232
     */
 
1233
    {
 
1234
        long year;
 
1235
        PyObject *pyyear = PySequence_GetItem(timetuple, 0);
 
1236
        if (pyyear == NULL) return NULL;
 
1237
        assert(PyLong_Check(pyyear));
 
1238
        year = PyLong_AsLong(pyyear);
 
1239
        Py_DECREF(pyyear);
 
1240
        if (year < 1900) {
 
1241
            PyErr_Format(PyExc_ValueError, "year=%ld is before "
 
1242
                         "1900; the datetime strftime() "
 
1243
                         "methods require year >= 1900",
 
1244
                         year);
 
1245
            return NULL;
 
1246
        }
 
1247
    }
 
1248
 
 
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.
 
1252
     */
 
1253
    if (flen > INT_MAX - 1) {
 
1254
        PyErr_NoMemory();
 
1255
        goto Done;
 
1256
    }
 
1257
 
 
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);
 
1262
    usednew = 0;
 
1263
 
 
1264
    while ((ch = *pin++) != '\0') {
 
1265
        if (ch != '%') {
 
1266
            ptoappend = pin - 1;
 
1267
            ntoappend = 1;
 
1268
        }
 
1269
        else if ((ch = *pin++) == '\0') {
 
1270
            /* There's a lone trailing %; doesn't make sense. */
 
1271
            PyErr_SetString(PyExc_ValueError, "strftime format "
 
1272
                            "ends with raw %");
 
1273
            goto Done;
 
1274
        }
 
1275
        /* A % has been seen and ch is the character after it. */
 
1276
        else if (ch == 'z') {
 
1277
            if (zreplacement == NULL) {
 
1278
                /* format utcoffset */
 
1279
                char buf[100];
 
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,
 
1286
                                         sizeof(buf),
 
1287
                                         "",
 
1288
                                         tzinfo,
 
1289
                                         tzinfoarg) < 0)
 
1290
                        goto Done;
 
1291
                    Py_DECREF(zreplacement);
 
1292
                    zreplacement =
 
1293
                      PyBytes_FromStringAndSize(buf,
 
1294
                                               strlen(buf));
 
1295
                    if (zreplacement == NULL)
 
1296
                        goto Done;
 
1297
                }
 
1298
            }
 
1299
            assert(zreplacement != NULL);
 
1300
            ptoappend = PyBytes_AS_STRING(zreplacement);
 
1301
            ntoappend = PyBytes_GET_SIZE(zreplacement);
 
1302
        }
 
1303
        else if (ch == 'Z') {
 
1304
            /* format tzname */
 
1305
            if (Zreplacement == NULL) {
 
1306
                Zreplacement = make_Zreplacement(object,
 
1307
                                                 tzinfoarg);
 
1308
                if (Zreplacement == NULL)
 
1309
                    goto Done;
 
1310
            }
 
1311
            assert(Zreplacement != NULL);
 
1312
            assert(PyUnicode_Check(Zreplacement));
 
1313
            ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
 
1314
                                                  &ntoappend);
 
1315
            ntoappend = Py_SIZE(Zreplacement);
 
1316
        }
 
1317
        else if (ch == 'f') {
 
1318
            /* format microseconds */
 
1319
            if (freplacement == NULL) {
 
1320
                freplacement = make_freplacement(object);
 
1321
                if (freplacement == NULL)
 
1322
                    goto Done;
 
1323
            }
 
1324
            assert(freplacement != NULL);
 
1325
            assert(PyBytes_Check(freplacement));
 
1326
            ptoappend = PyBytes_AS_STRING(freplacement);
 
1327
            ntoappend = PyBytes_GET_SIZE(freplacement);
 
1328
        }
 
1329
        else {
 
1330
            /* percent followed by neither z nor Z */
 
1331
            ptoappend = pin - 2;
 
1332
            ntoappend = 2;
 
1333
        }
 
1334
 
 
1335
        /* Append the ntoappend chars starting at ptoappend to
 
1336
         * the new format.
 
1337
         */
 
1338
        if (ntoappend == 0)
 
1339
            continue;
 
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 */
 
1345
                PyErr_NoMemory();
 
1346
                goto Done;
 
1347
            }
 
1348
            if (_PyBytes_Resize(&newfmt, bigger) < 0)
 
1349
                goto Done;
 
1350
            totalnew = bigger;
 
1351
            pnew = PyBytes_AsString(newfmt) + usednew;
 
1352
        }
 
1353
        memcpy(pnew, ptoappend, ntoappend);
 
1354
        pnew += ntoappend;
 
1355
        usednew += ntoappend;
 
1356
        assert(usednew <= totalnew);
 
1357
    }  /* end while() */
 
1358
 
 
1359
    if (_PyBytes_Resize(&newfmt, usednew) < 0)
 
1360
        goto Done;
 
1361
    {
 
1362
        PyObject *format;
 
1363
        PyObject *time = PyImport_ImportModuleNoBlock("time");
 
1364
        if (time == NULL)
 
1365
            goto Done;
 
1366
        format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
 
1367
        if (format != NULL) {
 
1368
            result = PyObject_CallMethod(time, "strftime", "OO",
 
1369
                                         format, timetuple);
 
1370
            Py_DECREF(format);
 
1371
        }
 
1372
        Py_DECREF(time);
 
1373
    }
1376
1374
 Done:
1377
 
        Py_XDECREF(freplacement);
1378
 
        Py_XDECREF(zreplacement);
1379
 
        Py_XDECREF(Zreplacement);
1380
 
        Py_XDECREF(newfmt);
1381
 
        return result;
 
1375
    Py_XDECREF(freplacement);
 
1376
    Py_XDECREF(zreplacement);
 
1377
    Py_XDECREF(Zreplacement);
 
1378
    Py_XDECREF(newfmt);
 
1379
    return result;
1382
1380
}
1383
1381
 
1384
1382
/* ---------------------------------------------------------------------------
1390
1388
static PyObject *
1391
1389
time_time(void)
1392
1390
{
1393
 
        PyObject *result = NULL;
1394
 
        PyObject *time = PyImport_ImportModuleNoBlock("time");
 
1391
    PyObject *result = NULL;
 
1392
    PyObject *time = PyImport_ImportModuleNoBlock("time");
1395
1393
 
1396
 
        if (time != NULL) {
1397
 
                result = PyObject_CallMethod(time, "time", "()");
1398
 
                Py_DECREF(time);
1399
 
        }
1400
 
        return result;
 
1394
    if (time != NULL) {
 
1395
        result = PyObject_CallMethod(time, "time", "()");
 
1396
        Py_DECREF(time);
 
1397
    }
 
1398
    return result;
1401
1399
}
1402
1400
 
1403
1401
/* Build a time.struct_time.  The weekday and day number are automatically
1406
1404
static PyObject *
1407
1405
build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1408
1406
{
1409
 
        PyObject *time;
1410
 
        PyObject *result = NULL;
 
1407
    PyObject *time;
 
1408
    PyObject *result = NULL;
1411
1409
 
1412
 
        time = PyImport_ImportModuleNoBlock("time");
1413
 
        if (time != NULL) {
1414
 
                result = PyObject_CallMethod(time, "struct_time",
1415
 
                                             "((iiiiiiiii))",
1416
 
                                             y, m, d,
1417
 
                                             hh, mm, ss,
1418
 
                                             weekday(y, m, d),
1419
 
                                             days_before_month(y, m) + d,
1420
 
                                             dstflag);
1421
 
                Py_DECREF(time);
1422
 
        }
1423
 
        return result;
 
1410
    time = PyImport_ImportModuleNoBlock("time");
 
1411
    if (time != NULL) {
 
1412
        result = PyObject_CallMethod(time, "struct_time",
 
1413
                                     "((iiiiiiiii))",
 
1414
                                     y, m, d,
 
1415
                                     hh, mm, ss,
 
1416
                                     weekday(y, m, d),
 
1417
                                     days_before_month(y, m) + d,
 
1418
                                     dstflag);
 
1419
        Py_DECREF(time);
 
1420
    }
 
1421
    return result;
1424
1422
}
1425
1423
 
1426
1424
/* ---------------------------------------------------------------------------
1434
1432
static PyObject *
1435
1433
diff_to_bool(int diff, int op)
1436
1434
{
1437
 
        PyObject *result;
1438
 
        int istrue;
 
1435
    PyObject *result;
 
1436
    int istrue;
1439
1437
 
1440
 
        switch (op) {
1441
 
                case Py_EQ: istrue = diff == 0; break;
1442
 
                case Py_NE: istrue = diff != 0; break;
1443
 
                case Py_LE: istrue = diff <= 0; break;
1444
 
                case Py_GE: istrue = diff >= 0; break;
1445
 
                case Py_LT: istrue = diff < 0; break;
1446
 
                case Py_GT: istrue = diff > 0; break;
1447
 
                default:
1448
 
                        assert(! "op unknown");
1449
 
                        istrue = 0; /* To shut up compiler */
1450
 
        }
1451
 
        result = istrue ? Py_True : Py_False;
1452
 
        Py_INCREF(result);
1453
 
        return result;
 
1438
    switch (op) {
 
1439
        case Py_EQ: istrue = diff == 0; break;
 
1440
        case Py_NE: istrue = diff != 0; break;
 
1441
        case Py_LE: istrue = diff <= 0; break;
 
1442
        case Py_GE: istrue = diff >= 0; break;
 
1443
        case Py_LT: istrue = diff < 0; break;
 
1444
        case Py_GT: istrue = diff > 0; break;
 
1445
        default:
 
1446
            assert(! "op unknown");
 
1447
            istrue = 0; /* To shut up compiler */
 
1448
    }
 
1449
    result = istrue ? Py_True : Py_False;
 
1450
    Py_INCREF(result);
 
1451
    return result;
1454
1452
}
1455
1453
 
1456
1454
/* Raises a "can't compare" TypeError and returns NULL. */
1457
1455
static PyObject *
1458
1456
cmperror(PyObject *a, PyObject *b)
1459
1457
{
1460
 
        PyErr_Format(PyExc_TypeError,
1461
 
                     "can't compare %s to %s",
1462
 
                     Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1463
 
        return NULL;
 
1458
    PyErr_Format(PyExc_TypeError,
 
1459
                 "can't compare %s to %s",
 
1460
                 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
 
1461
    return NULL;
1464
1462
}
1465
1463
 
1466
1464
/* ---------------------------------------------------------------------------
1468
1466
 */
1469
1467
 
1470
1468
/* Conversion factors. */
1471
 
static PyObject *us_per_us = NULL;      /* 1 */
1472
 
static PyObject *us_per_ms = NULL;      /* 1000 */
1473
 
static PyObject *us_per_second = NULL;  /* 1000000 */
1474
 
static PyObject *us_per_minute = NULL;  /* 1e6 * 60 as Python int */
1475
 
static PyObject *us_per_hour = NULL;    /* 1e6 * 3600 as Python long */
1476
 
static PyObject *us_per_day = NULL;     /* 1e6 * 3600 * 24 as Python long */
1477
 
static PyObject *us_per_week = NULL;    /* 1e6*3600*24*7 as Python long */
 
1469
static PyObject *us_per_us = NULL;      /* 1 */
 
1470
static PyObject *us_per_ms = NULL;      /* 1000 */
 
1471
static PyObject *us_per_second = NULL;  /* 1000000 */
 
1472
static PyObject *us_per_minute = NULL;  /* 1e6 * 60 as Python int */
 
1473
static PyObject *us_per_hour = NULL;    /* 1e6 * 3600 as Python long */
 
1474
static PyObject *us_per_day = NULL;     /* 1e6 * 3600 * 24 as Python long */
 
1475
static PyObject *us_per_week = NULL;    /* 1e6*3600*24*7 as Python long */
1478
1476
static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1479
1477
 
1480
1478
/* ---------------------------------------------------------------------------
1486
1484
 */
1487
1485
 
1488
1486
/* Convert a timedelta to a number of us,
1489
 
 *      (24*3600*self.days + self.seconds)*1000000 + self.microseconds
 
1487
 *      (24*3600*self.days + self.seconds)*1000000 + self.microseconds
1490
1488
 * as a Python int or long.
1491
1489
 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1492
1490
 * due to ubiquitous overflow possibilities.
1494
1492
static PyObject *
1495
1493
delta_to_microseconds(PyDateTime_Delta *self)
1496
1494
{
1497
 
        PyObject *x1 = NULL;
1498
 
        PyObject *x2 = NULL;
1499
 
        PyObject *x3 = NULL;
1500
 
        PyObject *result = NULL;
1501
 
 
1502
 
        x1 = PyLong_FromLong(GET_TD_DAYS(self));
1503
 
        if (x1 == NULL)
1504
 
                goto Done;
1505
 
        x2 = PyNumber_Multiply(x1, seconds_per_day);    /* days in seconds */
1506
 
        if (x2 == NULL)
1507
 
                goto Done;
1508
 
        Py_DECREF(x1);
1509
 
        x1 = NULL;
1510
 
 
1511
 
        /* x2 has days in seconds */
1512
 
        x1 = PyLong_FromLong(GET_TD_SECONDS(self));     /* seconds */
1513
 
        if (x1 == NULL)
1514
 
                goto Done;
1515
 
        x3 = PyNumber_Add(x1, x2);      /* days and seconds in seconds */
1516
 
        if (x3 == NULL)
1517
 
                goto Done;
1518
 
        Py_DECREF(x1);
1519
 
        Py_DECREF(x2);
1520
 
        x1 = x2 = NULL;
1521
 
 
1522
 
        /* x3 has days+seconds in seconds */
1523
 
        x1 = PyNumber_Multiply(x3, us_per_second);      /* us */
1524
 
        if (x1 == NULL)
1525
 
                goto Done;
1526
 
        Py_DECREF(x3);
1527
 
        x3 = NULL;
1528
 
 
1529
 
        /* x1 has days+seconds in us */
1530
 
        x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1531
 
        if (x2 == NULL)
1532
 
                goto Done;
1533
 
        result = PyNumber_Add(x1, x2);
 
1495
    PyObject *x1 = NULL;
 
1496
    PyObject *x2 = NULL;
 
1497
    PyObject *x3 = NULL;
 
1498
    PyObject *result = NULL;
 
1499
 
 
1500
    x1 = PyLong_FromLong(GET_TD_DAYS(self));
 
1501
    if (x1 == NULL)
 
1502
        goto Done;
 
1503
    x2 = PyNumber_Multiply(x1, seconds_per_day);        /* days in seconds */
 
1504
    if (x2 == NULL)
 
1505
        goto Done;
 
1506
    Py_DECREF(x1);
 
1507
    x1 = NULL;
 
1508
 
 
1509
    /* x2 has days in seconds */
 
1510
    x1 = PyLong_FromLong(GET_TD_SECONDS(self));         /* seconds */
 
1511
    if (x1 == NULL)
 
1512
        goto Done;
 
1513
    x3 = PyNumber_Add(x1, x2);          /* days and seconds in seconds */
 
1514
    if (x3 == NULL)
 
1515
        goto Done;
 
1516
    Py_DECREF(x1);
 
1517
    Py_DECREF(x2);
 
1518
    x1 = x2 = NULL;
 
1519
 
 
1520
    /* x3 has days+seconds in seconds */
 
1521
    x1 = PyNumber_Multiply(x3, us_per_second);          /* us */
 
1522
    if (x1 == NULL)
 
1523
        goto Done;
 
1524
    Py_DECREF(x3);
 
1525
    x3 = NULL;
 
1526
 
 
1527
    /* x1 has days+seconds in us */
 
1528
    x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
 
1529
    if (x2 == NULL)
 
1530
        goto Done;
 
1531
    result = PyNumber_Add(x1, x2);
1534
1532
 
1535
1533
Done:
1536
 
        Py_XDECREF(x1);
1537
 
        Py_XDECREF(x2);
1538
 
        Py_XDECREF(x3);
1539
 
        return result;
 
1534
    Py_XDECREF(x1);
 
1535
    Py_XDECREF(x2);
 
1536
    Py_XDECREF(x3);
 
1537
    return result;
1540
1538
}
1541
1539
 
1542
1540
/* Convert a number of us (as a Python int or long) to a timedelta.
1544
1542
static PyObject *
1545
1543
microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
1546
1544
{
1547
 
        int us;
1548
 
        int s;
1549
 
        int d;
1550
 
        long temp;
1551
 
 
1552
 
        PyObject *tuple = NULL;
1553
 
        PyObject *num = NULL;
1554
 
        PyObject *result = NULL;
1555
 
 
1556
 
        tuple = PyNumber_Divmod(pyus, us_per_second);
1557
 
        if (tuple == NULL)
1558
 
                goto Done;
1559
 
 
1560
 
        num = PyTuple_GetItem(tuple, 1);        /* us */
1561
 
        if (num == NULL)
1562
 
                goto Done;
1563
 
        temp = PyLong_AsLong(num);
1564
 
        num = NULL;
1565
 
        if (temp == -1 && PyErr_Occurred())
1566
 
                goto Done;
1567
 
        assert(0 <= temp && temp < 1000000);
1568
 
        us = (int)temp;
1569
 
        if (us < 0) {
1570
 
                /* The divisor was positive, so this must be an error. */
1571
 
                assert(PyErr_Occurred());
1572
 
                goto Done;
1573
 
        }
1574
 
 
1575
 
        num = PyTuple_GetItem(tuple, 0);        /* leftover seconds */
1576
 
        if (num == NULL)
1577
 
                goto Done;
1578
 
        Py_INCREF(num);
1579
 
        Py_DECREF(tuple);
1580
 
 
1581
 
        tuple = PyNumber_Divmod(num, seconds_per_day);
1582
 
        if (tuple == NULL)
1583
 
                goto Done;
1584
 
        Py_DECREF(num);
1585
 
 
1586
 
        num = PyTuple_GetItem(tuple, 1);        /* seconds */
1587
 
        if (num == NULL)
1588
 
                goto Done;
1589
 
        temp = PyLong_AsLong(num);
1590
 
        num = NULL;
1591
 
        if (temp == -1 && PyErr_Occurred())
1592
 
                goto Done;
1593
 
        assert(0 <= temp && temp < 24*3600);
1594
 
        s = (int)temp;
1595
 
 
1596
 
        if (s < 0) {
1597
 
                /* The divisor was positive, so this must be an error. */
1598
 
                assert(PyErr_Occurred());
1599
 
                goto Done;
1600
 
        }
1601
 
 
1602
 
        num = PyTuple_GetItem(tuple, 0);        /* leftover days */
1603
 
        if (num == NULL)
1604
 
                goto Done;
1605
 
        Py_INCREF(num);
1606
 
        temp = PyLong_AsLong(num);
1607
 
        if (temp == -1 && PyErr_Occurred())
1608
 
                goto Done;
1609
 
        d = (int)temp;
1610
 
        if ((long)d != temp) {
1611
 
                PyErr_SetString(PyExc_OverflowError, "normalized days too "
1612
 
                                "large to fit in a C int");
1613
 
                goto Done;
1614
 
        }
1615
 
        result = new_delta_ex(d, s, us, 0, type);
 
1545
    int us;
 
1546
    int s;
 
1547
    int d;
 
1548
    long temp;
 
1549
 
 
1550
    PyObject *tuple = NULL;
 
1551
    PyObject *num = NULL;
 
1552
    PyObject *result = NULL;
 
1553
 
 
1554
    tuple = PyNumber_Divmod(pyus, us_per_second);
 
1555
    if (tuple == NULL)
 
1556
        goto Done;
 
1557
 
 
1558
    num = PyTuple_GetItem(tuple, 1);            /* us */
 
1559
    if (num == NULL)
 
1560
        goto Done;
 
1561
    temp = PyLong_AsLong(num);
 
1562
    num = NULL;
 
1563
    if (temp == -1 && PyErr_Occurred())
 
1564
        goto Done;
 
1565
    assert(0 <= temp && temp < 1000000);
 
1566
    us = (int)temp;
 
1567
    if (us < 0) {
 
1568
        /* The divisor was positive, so this must be an error. */
 
1569
        assert(PyErr_Occurred());
 
1570
        goto Done;
 
1571
    }
 
1572
 
 
1573
    num = PyTuple_GetItem(tuple, 0);            /* leftover seconds */
 
1574
    if (num == NULL)
 
1575
        goto Done;
 
1576
    Py_INCREF(num);
 
1577
    Py_DECREF(tuple);
 
1578
 
 
1579
    tuple = PyNumber_Divmod(num, seconds_per_day);
 
1580
    if (tuple == NULL)
 
1581
        goto Done;
 
1582
    Py_DECREF(num);
 
1583
 
 
1584
    num = PyTuple_GetItem(tuple, 1);            /* seconds */
 
1585
    if (num == NULL)
 
1586
        goto Done;
 
1587
    temp = PyLong_AsLong(num);
 
1588
    num = NULL;
 
1589
    if (temp == -1 && PyErr_Occurred())
 
1590
        goto Done;
 
1591
    assert(0 <= temp && temp < 24*3600);
 
1592
    s = (int)temp;
 
1593
 
 
1594
    if (s < 0) {
 
1595
        /* The divisor was positive, so this must be an error. */
 
1596
        assert(PyErr_Occurred());
 
1597
        goto Done;
 
1598
    }
 
1599
 
 
1600
    num = PyTuple_GetItem(tuple, 0);            /* leftover days */
 
1601
    if (num == NULL)
 
1602
        goto Done;
 
1603
    Py_INCREF(num);
 
1604
    temp = PyLong_AsLong(num);
 
1605
    if (temp == -1 && PyErr_Occurred())
 
1606
        goto Done;
 
1607
    d = (int)temp;
 
1608
    if ((long)d != temp) {
 
1609
        PyErr_SetString(PyExc_OverflowError, "normalized days too "
 
1610
                        "large to fit in a C int");
 
1611
        goto Done;
 
1612
    }
 
1613
    result = new_delta_ex(d, s, us, 0, type);
1616
1614
 
1617
1615
Done:
1618
 
        Py_XDECREF(tuple);
1619
 
        Py_XDECREF(num);
1620
 
        return result;
 
1616
    Py_XDECREF(tuple);
 
1617
    Py_XDECREF(num);
 
1618
    return result;
1621
1619
}
1622
1620
 
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)
1625
1623
 
1626
1624
static PyObject *
1627
1625
multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1628
1626
{
1629
 
        PyObject *pyus_in;
1630
 
        PyObject *pyus_out;
1631
 
        PyObject *result;
1632
 
 
1633
 
        pyus_in = delta_to_microseconds(delta);
1634
 
        if (pyus_in == NULL)
1635
 
                return NULL;
1636
 
 
1637
 
        pyus_out = PyNumber_Multiply(pyus_in, intobj);
1638
 
        Py_DECREF(pyus_in);
1639
 
        if (pyus_out == NULL)
1640
 
                return NULL;
1641
 
 
1642
 
        result = microseconds_to_delta(pyus_out);
1643
 
        Py_DECREF(pyus_out);
1644
 
        return result;
 
1627
    PyObject *pyus_in;
 
1628
    PyObject *pyus_out;
 
1629
    PyObject *result;
 
1630
 
 
1631
    pyus_in = delta_to_microseconds(delta);
 
1632
    if (pyus_in == NULL)
 
1633
        return NULL;
 
1634
 
 
1635
    pyus_out = PyNumber_Multiply(pyus_in, intobj);
 
1636
    Py_DECREF(pyus_in);
 
1637
    if (pyus_out == NULL)
 
1638
        return NULL;
 
1639
 
 
1640
    result = microseconds_to_delta(pyus_out);
 
1641
    Py_DECREF(pyus_out);
 
1642
    return result;
1645
1643
}
1646
1644
 
1647
1645
static PyObject *
1648
1646
divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1649
1647
{
1650
 
        PyObject *pyus_in;
1651
 
        PyObject *pyus_out;
1652
 
        PyObject *result;
1653
 
 
1654
 
        pyus_in = delta_to_microseconds(delta);
1655
 
        if (pyus_in == NULL)
1656
 
                return NULL;
1657
 
 
1658
 
        pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1659
 
        Py_DECREF(pyus_in);
1660
 
        if (pyus_out == NULL)
1661
 
                return NULL;
1662
 
 
1663
 
        result = microseconds_to_delta(pyus_out);
1664
 
        Py_DECREF(pyus_out);
1665
 
        return result;
 
1648
    PyObject *pyus_in;
 
1649
    PyObject *pyus_out;
 
1650
    PyObject *result;
 
1651
 
 
1652
    pyus_in = delta_to_microseconds(delta);
 
1653
    if (pyus_in == NULL)
 
1654
        return NULL;
 
1655
 
 
1656
    pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
 
1657
    Py_DECREF(pyus_in);
 
1658
    if (pyus_out == NULL)
 
1659
        return NULL;
 
1660
 
 
1661
    result = microseconds_to_delta(pyus_out);
 
1662
    Py_DECREF(pyus_out);
 
1663
    return result;
1666
1664
}
1667
1665
 
1668
1666
static PyObject *
1669
1667
delta_add(PyObject *left, PyObject *right)
1670
1668
{
1671
 
        PyObject *result = Py_NotImplemented;
1672
 
 
1673
 
        if (PyDelta_Check(left) && PyDelta_Check(right)) {
1674
 
                /* delta + delta */
1675
 
                /* The C-level additions can't overflow because of the
1676
 
                 * invariant bounds.
1677
 
                 */
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);
1683
 
        }
1684
 
 
1685
 
        if (result == Py_NotImplemented)
1686
 
                Py_INCREF(result);
1687
 
        return result;
 
1669
    PyObject *result = Py_NotImplemented;
 
1670
 
 
1671
    if (PyDelta_Check(left) && PyDelta_Check(right)) {
 
1672
        /* delta + delta */
 
1673
        /* The C-level additions can't overflow because of the
 
1674
         * invariant bounds.
 
1675
         */
 
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);
 
1681
    }
 
1682
 
 
1683
    if (result == Py_NotImplemented)
 
1684
        Py_INCREF(result);
 
1685
    return result;
1688
1686
}
1689
1687
 
1690
1688
static PyObject *
1691
1689
delta_negative(PyDateTime_Delta *self)
1692
1690
{
1693
 
        return new_delta(-GET_TD_DAYS(self),
1694
 
                         -GET_TD_SECONDS(self),
1695
 
                         -GET_TD_MICROSECONDS(self),
1696
 
                         1);
 
1691
    return new_delta(-GET_TD_DAYS(self),
 
1692
                     -GET_TD_SECONDS(self),
 
1693
                     -GET_TD_MICROSECONDS(self),
 
1694
                     1);
1697
1695
}
1698
1696
 
1699
1697
static PyObject *
1700
1698
delta_positive(PyDateTime_Delta *self)
1701
1699
{
1702
 
        /* Could optimize this (by returning self) if this isn't a
1703
 
         * subclass -- but who uses unary + ?  Approximately nobody.
1704
 
         */
1705
 
        return new_delta(GET_TD_DAYS(self),
1706
 
                         GET_TD_SECONDS(self),
1707
 
                         GET_TD_MICROSECONDS(self),
1708
 
                         0);
 
1700
    /* Could optimize this (by returning self) if this isn't a
 
1701
     * subclass -- but who uses unary + ?  Approximately nobody.
 
1702
     */
 
1703
    return new_delta(GET_TD_DAYS(self),
 
1704
                     GET_TD_SECONDS(self),
 
1705
                     GET_TD_MICROSECONDS(self),
 
1706
                     0);
1709
1707
}
1710
1708
 
1711
1709
static PyObject *
1712
1710
delta_abs(PyDateTime_Delta *self)
1713
1711
{
1714
 
        PyObject *result;
1715
 
 
1716
 
        assert(GET_TD_MICROSECONDS(self) >= 0);
1717
 
        assert(GET_TD_SECONDS(self) >= 0);
1718
 
 
1719
 
        if (GET_TD_DAYS(self) < 0)
1720
 
                result = delta_negative(self);
1721
 
        else
1722
 
                result = delta_positive(self);
1723
 
 
1724
 
        return result;
 
1712
    PyObject *result;
 
1713
 
 
1714
    assert(GET_TD_MICROSECONDS(self) >= 0);
 
1715
    assert(GET_TD_SECONDS(self) >= 0);
 
1716
 
 
1717
    if (GET_TD_DAYS(self) < 0)
 
1718
        result = delta_negative(self);
 
1719
    else
 
1720
        result = delta_positive(self);
 
1721
 
 
1722
    return result;
1725
1723
}
1726
1724
 
1727
1725
static PyObject *
1728
1726
delta_subtract(PyObject *left, PyObject *right)
1729
1727
{
1730
 
        PyObject *result = Py_NotImplemented;
1731
 
 
1732
 
        if (PyDelta_Check(left) && PyDelta_Check(right)) {
1733
 
                /* delta - delta */
1734
 
                PyObject *minus_right = PyNumber_Negative(right);
1735
 
                if (minus_right) {
1736
 
                        result = delta_add(left, minus_right);
1737
 
                        Py_DECREF(minus_right);
1738
 
                }
1739
 
                else
1740
 
                        result = NULL;
1741
 
        }
1742
 
 
1743
 
        if (result == Py_NotImplemented)
1744
 
                Py_INCREF(result);
1745
 
        return result;
 
1728
    PyObject *result = Py_NotImplemented;
 
1729
 
 
1730
    if (PyDelta_Check(left) && PyDelta_Check(right)) {
 
1731
        /* delta - delta */
 
1732
        PyObject *minus_right = PyNumber_Negative(right);
 
1733
        if (minus_right) {
 
1734
            result = delta_add(left, minus_right);
 
1735
            Py_DECREF(minus_right);
 
1736
        }
 
1737
        else
 
1738
            result = NULL;
 
1739
    }
 
1740
 
 
1741
    if (result == Py_NotImplemented)
 
1742
        Py_INCREF(result);
 
1743
    return result;
1746
1744
}
1747
1745
 
1748
1746
static PyObject *
1749
1747
delta_richcompare(PyObject *self, PyObject *other, int op)
1750
1748
{
1751
 
        if (PyDelta_Check(other)) {
1752
 
                int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1753
 
                if (diff == 0) {
1754
 
                        diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1755
 
                        if (diff == 0)
1756
 
                                diff = GET_TD_MICROSECONDS(self) -
1757
 
                                       GET_TD_MICROSECONDS(other);
1758
 
                }
1759
 
                return diff_to_bool(diff, op);
1760
 
        }
1761
 
        else {
1762
 
                Py_INCREF(Py_NotImplemented);
1763
 
                return Py_NotImplemented;
1764
 
        }
 
1749
    if (PyDelta_Check(other)) {
 
1750
        int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
 
1751
        if (diff == 0) {
 
1752
            diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
 
1753
            if (diff == 0)
 
1754
                diff = GET_TD_MICROSECONDS(self) -
 
1755
                       GET_TD_MICROSECONDS(other);
 
1756
        }
 
1757
        return diff_to_bool(diff, op);
 
1758
    }
 
1759
    else {
 
1760
        Py_INCREF(Py_NotImplemented);
 
1761
        return Py_NotImplemented;
 
1762
    }
1765
1763
}
1766
1764
 
1767
1765
static PyObject *delta_getstate(PyDateTime_Delta *self);
1769
1767
static long
1770
1768
delta_hash(PyDateTime_Delta *self)
1771
1769
{
1772
 
        if (self->hashcode == -1) {
1773
 
                PyObject *temp = delta_getstate(self);
1774
 
                if (temp != NULL) {
1775
 
                        self->hashcode = PyObject_Hash(temp);
1776
 
                        Py_DECREF(temp);
1777
 
                }
1778
 
        }
1779
 
        return self->hashcode;
 
1770
    if (self->hashcode == -1) {
 
1771
        PyObject *temp = delta_getstate(self);
 
1772
        if (temp != NULL) {
 
1773
            self->hashcode = PyObject_Hash(temp);
 
1774
            Py_DECREF(temp);
 
1775
        }
 
1776
    }
 
1777
    return self->hashcode;
1780
1778
}
1781
1779
 
1782
1780
static PyObject *
1783
1781
delta_multiply(PyObject *left, PyObject *right)
1784
1782
{
1785
 
        PyObject *result = Py_NotImplemented;
1786
 
 
1787
 
        if (PyDelta_Check(left)) {
1788
 
                /* delta * ??? */
1789
 
                if (PyLong_Check(right))
1790
 
                        result = multiply_int_timedelta(right,
1791
 
                                        (PyDateTime_Delta *) left);
1792
 
        }
1793
 
        else if (PyLong_Check(left))
1794
 
                result = multiply_int_timedelta(left,
1795
 
                                                (PyDateTime_Delta *) right);
1796
 
 
1797
 
        if (result == Py_NotImplemented)
1798
 
                Py_INCREF(result);
1799
 
        return result;
 
1783
    PyObject *result = Py_NotImplemented;
 
1784
 
 
1785
    if (PyDelta_Check(left)) {
 
1786
        /* delta * ??? */
 
1787
        if (PyLong_Check(right))
 
1788
            result = multiply_int_timedelta(right,
 
1789
                            (PyDateTime_Delta *) left);
 
1790
    }
 
1791
    else if (PyLong_Check(left))
 
1792
        result = multiply_int_timedelta(left,
 
1793
                                        (PyDateTime_Delta *) right);
 
1794
 
 
1795
    if (result == Py_NotImplemented)
 
1796
        Py_INCREF(result);
 
1797
    return result;
1800
1798
}
1801
1799
 
1802
1800
static PyObject *
1803
1801
delta_divide(PyObject *left, PyObject *right)
1804
1802
{
1805
 
        PyObject *result = Py_NotImplemented;
1806
 
 
1807
 
        if (PyDelta_Check(left)) {
1808
 
                /* delta * ??? */
1809
 
                if (PyLong_Check(right))
1810
 
                        result = divide_timedelta_int(
1811
 
                                        (PyDateTime_Delta *)left,
1812
 
                                        right);
1813
 
        }
1814
 
 
1815
 
        if (result == Py_NotImplemented)
1816
 
                Py_INCREF(result);
1817
 
        return result;
 
1803
    PyObject *result = Py_NotImplemented;
 
1804
 
 
1805
    if (PyDelta_Check(left)) {
 
1806
        /* delta * ??? */
 
1807
        if (PyLong_Check(right))
 
1808
            result = divide_timedelta_int(
 
1809
                            (PyDateTime_Delta *)left,
 
1810
                            right);
 
1811
    }
 
1812
 
 
1813
    if (result == Py_NotImplemented)
 
1814
        Py_INCREF(result);
 
1815
    return result;
1818
1816
}
1819
1817
 
1820
1818
/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1830
1828
accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1831
1829
      double *leftover)
1832
1830
{
1833
 
        PyObject *prod;
1834
 
        PyObject *sum;
1835
 
 
1836
 
        assert(num != NULL);
1837
 
 
1838
 
        if (PyLong_Check(num)) {
1839
 
                prod = PyNumber_Multiply(num, factor);
1840
 
                if (prod == NULL)
1841
 
                        return NULL;
1842
 
                sum = PyNumber_Add(sofar, prod);
1843
 
                Py_DECREF(prod);
1844
 
                return sum;
1845
 
        }
1846
 
 
1847
 
        if (PyFloat_Check(num)) {
1848
 
                double dnum;
1849
 
                double fracpart;
1850
 
                double intpart;
1851
 
                PyObject *x;
1852
 
                PyObject *y;
1853
 
 
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.
1861
 
                 */
1862
 
                dnum = PyFloat_AsDouble(num);
1863
 
                if (dnum == -1.0 && PyErr_Occurred())
1864
 
                        return NULL;
1865
 
                fracpart = modf(dnum, &intpart);
1866
 
                x = PyLong_FromDouble(intpart);
1867
 
                if (x == NULL)
1868
 
                        return NULL;
1869
 
 
1870
 
                prod = PyNumber_Multiply(x, factor);
1871
 
                Py_DECREF(x);
1872
 
                if (prod == NULL)
1873
 
                        return NULL;
1874
 
 
1875
 
                sum = PyNumber_Add(sofar, prod);
1876
 
                Py_DECREF(prod);
1877
 
                if (sum == NULL)
1878
 
                        return NULL;
1879
 
 
1880
 
                if (fracpart == 0.0)
1881
 
                        return sum;
1882
 
                /* So far we've lost no information.  Dealing with the
1883
 
                 * fractional part requires float arithmetic, and may
1884
 
                 * lose a little info.
1885
 
                 */
1886
 
                assert(PyLong_Check(factor));
1887
 
                dnum = PyLong_AsDouble(factor);
1888
 
 
1889
 
                dnum *= fracpart;
1890
 
                fracpart = modf(dnum, &intpart);
1891
 
                x = PyLong_FromDouble(intpart);
1892
 
                if (x == NULL) {
1893
 
                        Py_DECREF(sum);
1894
 
                        return NULL;
1895
 
                }
1896
 
 
1897
 
                y = PyNumber_Add(sum, x);
1898
 
                Py_DECREF(sum);
1899
 
                Py_DECREF(x);
1900
 
                *leftover += fracpart;
1901
 
                return y;
1902
 
        }
1903
 
 
1904
 
        PyErr_Format(PyExc_TypeError,
1905
 
                     "unsupported type for timedelta %s component: %s",
1906
 
                     tag, Py_TYPE(num)->tp_name);
1907
 
        return NULL;
 
1831
    PyObject *prod;
 
1832
    PyObject *sum;
 
1833
 
 
1834
    assert(num != NULL);
 
1835
 
 
1836
    if (PyLong_Check(num)) {
 
1837
        prod = PyNumber_Multiply(num, factor);
 
1838
        if (prod == NULL)
 
1839
            return NULL;
 
1840
        sum = PyNumber_Add(sofar, prod);
 
1841
        Py_DECREF(prod);
 
1842
        return sum;
 
1843
    }
 
1844
 
 
1845
    if (PyFloat_Check(num)) {
 
1846
        double dnum;
 
1847
        double fracpart;
 
1848
        double intpart;
 
1849
        PyObject *x;
 
1850
        PyObject *y;
 
1851
 
 
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.
 
1859
         */
 
1860
        dnum = PyFloat_AsDouble(num);
 
1861
        if (dnum == -1.0 && PyErr_Occurred())
 
1862
            return NULL;
 
1863
        fracpart = modf(dnum, &intpart);
 
1864
        x = PyLong_FromDouble(intpart);
 
1865
        if (x == NULL)
 
1866
            return NULL;
 
1867
 
 
1868
        prod = PyNumber_Multiply(x, factor);
 
1869
        Py_DECREF(x);
 
1870
        if (prod == NULL)
 
1871
            return NULL;
 
1872
 
 
1873
        sum = PyNumber_Add(sofar, prod);
 
1874
        Py_DECREF(prod);
 
1875
        if (sum == NULL)
 
1876
            return NULL;
 
1877
 
 
1878
        if (fracpart == 0.0)
 
1879
            return sum;
 
1880
        /* So far we've lost no information.  Dealing with the
 
1881
         * fractional part requires float arithmetic, and may
 
1882
         * lose a little info.
 
1883
         */
 
1884
        assert(PyLong_Check(factor));
 
1885
        dnum = PyLong_AsDouble(factor);
 
1886
 
 
1887
        dnum *= fracpart;
 
1888
        fracpart = modf(dnum, &intpart);
 
1889
        x = PyLong_FromDouble(intpart);
 
1890
        if (x == NULL) {
 
1891
            Py_DECREF(sum);
 
1892
            return NULL;
 
1893
        }
 
1894
 
 
1895
        y = PyNumber_Add(sum, x);
 
1896
        Py_DECREF(sum);
 
1897
        Py_DECREF(x);
 
1898
        *leftover += fracpart;
 
1899
        return y;
 
1900
    }
 
1901
 
 
1902
    PyErr_Format(PyExc_TypeError,
 
1903
                 "unsupported type for timedelta %s component: %s",
 
1904
                 tag, Py_TYPE(num)->tp_name);
 
1905
    return NULL;
1908
1906
}
1909
1907
 
1910
1908
static PyObject *
1911
1909
delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1912
1910
{
1913
 
        PyObject *self = NULL;
1914
 
 
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;
1923
 
 
1924
 
        PyObject *x = NULL;     /* running sum of microseconds */
1925
 
        PyObject *y = NULL;     /* temp sum of microseconds */
1926
 
        double leftover_us = 0.0;
1927
 
 
1928
 
        static char *keywords[] = {
1929
 
                "days", "seconds", "microseconds", "milliseconds",
1930
 
                "minutes", "hours", "weeks", NULL
1931
 
        };
1932
 
 
1933
 
        if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1934
 
                                        keywords,
1935
 
                                        &day, &second, &us,
1936
 
                                        &ms, &minute, &hour, &week) == 0)
1937
 
                goto Done;
1938
 
 
1939
 
        x = PyLong_FromLong(0);
1940
 
        if (x == NULL)
1941
 
                goto Done;
1942
 
 
1943
 
#define CLEANUP         \
1944
 
        Py_DECREF(x);   \
1945
 
        x = y;          \
1946
 
        if (x == NULL)  \
1947
 
                goto Done
1948
 
 
1949
 
        if (us) {
1950
 
                y = accum("microseconds", x, us, us_per_us, &leftover_us);
1951
 
                CLEANUP;
1952
 
        }
1953
 
        if (ms) {
1954
 
                y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1955
 
                CLEANUP;
1956
 
        }
1957
 
        if (second) {
1958
 
                y = accum("seconds", x, second, us_per_second, &leftover_us);
1959
 
                CLEANUP;
1960
 
        }
1961
 
        if (minute) {
1962
 
                y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1963
 
                CLEANUP;
1964
 
        }
1965
 
        if (hour) {
1966
 
                y = accum("hours", x, hour, us_per_hour, &leftover_us);
1967
 
                CLEANUP;
1968
 
        }
1969
 
        if (day) {
1970
 
                y = accum("days", x, day, us_per_day, &leftover_us);
1971
 
                CLEANUP;
1972
 
        }
1973
 
        if (week) {
1974
 
                y = accum("weeks", x, week, us_per_week, &leftover_us);
1975
 
                CLEANUP;
1976
 
        }
1977
 
        if (leftover_us) {
1978
 
                /* Round to nearest whole # of us, and add into x. */
1979
 
                PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
1980
 
                if (temp == NULL) {
1981
 
                        Py_DECREF(x);
1982
 
                        goto Done;
1983
 
                }
1984
 
                y = PyNumber_Add(x, temp);
1985
 
                Py_DECREF(temp);
1986
 
                CLEANUP;
1987
 
        }
1988
 
 
1989
 
        self = microseconds_to_delta_ex(x, type);
1990
 
        Py_DECREF(x);
 
1911
    PyObject *self = NULL;
 
1912
 
 
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;
 
1921
 
 
1922
    PyObject *x = NULL;         /* running sum of microseconds */
 
1923
    PyObject *y = NULL;         /* temp sum of microseconds */
 
1924
    double leftover_us = 0.0;
 
1925
 
 
1926
    static char *keywords[] = {
 
1927
        "days", "seconds", "microseconds", "milliseconds",
 
1928
        "minutes", "hours", "weeks", NULL
 
1929
    };
 
1930
 
 
1931
    if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
 
1932
                                    keywords,
 
1933
                                    &day, &second, &us,
 
1934
                                    &ms, &minute, &hour, &week) == 0)
 
1935
        goto Done;
 
1936
 
 
1937
    x = PyLong_FromLong(0);
 
1938
    if (x == NULL)
 
1939
        goto Done;
 
1940
 
 
1941
#define CLEANUP         \
 
1942
    Py_DECREF(x);       \
 
1943
    x = y;              \
 
1944
    if (x == NULL)      \
 
1945
        goto Done
 
1946
 
 
1947
    if (us) {
 
1948
        y = accum("microseconds", x, us, us_per_us, &leftover_us);
 
1949
        CLEANUP;
 
1950
    }
 
1951
    if (ms) {
 
1952
        y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
 
1953
        CLEANUP;
 
1954
    }
 
1955
    if (second) {
 
1956
        y = accum("seconds", x, second, us_per_second, &leftover_us);
 
1957
        CLEANUP;
 
1958
    }
 
1959
    if (minute) {
 
1960
        y = accum("minutes", x, minute, us_per_minute, &leftover_us);
 
1961
        CLEANUP;
 
1962
    }
 
1963
    if (hour) {
 
1964
        y = accum("hours", x, hour, us_per_hour, &leftover_us);
 
1965
        CLEANUP;
 
1966
    }
 
1967
    if (day) {
 
1968
        y = accum("days", x, day, us_per_day, &leftover_us);
 
1969
        CLEANUP;
 
1970
    }
 
1971
    if (week) {
 
1972
        y = accum("weeks", x, week, us_per_week, &leftover_us);
 
1973
        CLEANUP;
 
1974
    }
 
1975
    if (leftover_us) {
 
1976
        /* Round to nearest whole # of us, and add into x. */
 
1977
        PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
 
1978
        if (temp == NULL) {
 
1979
            Py_DECREF(x);
 
1980
            goto Done;
 
1981
        }
 
1982
        y = PyNumber_Add(x, temp);
 
1983
        Py_DECREF(temp);
 
1984
        CLEANUP;
 
1985
    }
 
1986
 
 
1987
    self = microseconds_to_delta_ex(x, type);
 
1988
    Py_DECREF(x);
1991
1989
Done:
1992
 
        return self;
 
1990
    return self;
1993
1991
 
1994
1992
#undef CLEANUP
1995
1993
}
1997
1995
static int
1998
1996
delta_bool(PyDateTime_Delta *self)
1999
1997
{
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);
2003
2001
}
2004
2002
 
2005
2003
static PyObject *
2006
2004
delta_repr(PyDateTime_Delta *self)
2007
2005
{
2008
 
        if (GET_TD_MICROSECONDS(self) != 0)
2009
 
                return PyUnicode_FromFormat("%s(%d, %d, %d)",
2010
 
                                            Py_TYPE(self)->tp_name,
2011
 
                                            GET_TD_DAYS(self),
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,
2017
 
                                            GET_TD_DAYS(self),
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,
 
2009
                                    GET_TD_DAYS(self),
 
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,
 
2015
                                    GET_TD_DAYS(self),
 
2016
                                    GET_TD_SECONDS(self));
2019
2017
 
2020
 
        return PyUnicode_FromFormat("%s(%d)",
2021
 
                                    Py_TYPE(self)->tp_name,
2022
 
                                    GET_TD_DAYS(self));
 
2018
    return PyUnicode_FromFormat("%s(%d)",
 
2019
                                Py_TYPE(self)->tp_name,
 
2020
                                GET_TD_DAYS(self));
2023
2021
}
2024
2022
 
2025
2023
static PyObject *
2026
2024
delta_str(PyDateTime_Delta *self)
2027
2025
{
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);
2033
2031
 
2034
 
        if (days) {
2035
 
                if (us)
2036
 
                        return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2037
 
                                                    days, (days == 1 || days == -1) ? "" : "s",
2038
 
                                                    hours, minutes, seconds, us);
2039
 
                else
2040
 
                        return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2041
 
                                                    days, (days == 1 || days == -1) ? "" : "s",
2042
 
                                                    hours, minutes, seconds);
2043
 
        } else {
2044
 
                if (us)
2045
 
                        return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2046
 
                                                    hours, minutes, seconds, us);
2047
 
                else
2048
 
                        return PyUnicode_FromFormat("%d:%02d:%02d",
2049
 
                                                    hours, minutes, seconds);
2050
 
        }
 
2032
    if (days) {
 
2033
        if (us)
 
2034
            return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
 
2035
                                        days, (days == 1 || days == -1) ? "" : "s",
 
2036
                                        hours, minutes, seconds, us);
 
2037
        else
 
2038
            return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
 
2039
                                        days, (days == 1 || days == -1) ? "" : "s",
 
2040
                                        hours, minutes, seconds);
 
2041
    } else {
 
2042
        if (us)
 
2043
            return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
 
2044
                                        hours, minutes, seconds, us);
 
2045
        else
 
2046
            return PyUnicode_FromFormat("%d:%02d:%02d",
 
2047
                                        hours, minutes, seconds);
 
2048
    }
2051
2049
 
2052
2050
}
2053
2051
 
2057
2055
static PyObject *
2058
2056
delta_getstate(PyDateTime_Delta *self)
2059
2057
{
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));
2063
2061
}
2064
2062
 
2065
2063
static PyObject *
2066
2064
delta_reduce(PyDateTime_Delta* self)
2067
2065
{
2068
 
        return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
 
2066
    return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
2069
2067
}
2070
2068
 
2071
2069
#define OFFSET(field)  offsetof(PyDateTime_Delta, field)
2072
2070
 
2073
2071
static PyMemberDef delta_members[] = {
2074
2072
 
2075
 
        {"days",         T_INT, OFFSET(days),         READONLY,
2076
 
         PyDoc_STR("Number of days.")},
2077
 
 
2078
 
        {"seconds",      T_INT, OFFSET(seconds),      READONLY,
2079
 
         PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
2080
 
 
2081
 
        {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2082
 
         PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2083
 
        {NULL}
 
2073
    {"days",         T_INT, OFFSET(days),         READONLY,
 
2074
     PyDoc_STR("Number of days.")},
 
2075
 
 
2076
    {"seconds",      T_INT, OFFSET(seconds),      READONLY,
 
2077
     PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
 
2078
 
 
2079
    {"microseconds", T_INT, OFFSET(microseconds), READONLY,
 
2080
     PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
 
2081
    {NULL}
2084
2082
};
2085
2083
 
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)")},
2089
2087
 
2090
 
        {NULL,  NULL},
 
2088
    {NULL,      NULL},
2091
2089
};
2092
2090
 
2093
2091
static char delta_doc[] =
2094
2092
PyDoc_STR("Difference between two datetime values.");
2095
2093
 
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 */
2101
 
        0,                                      /* nb_divmod */
2102
 
        0,                                      /* nb_power */
2103
 
        (unaryfunc)delta_negative,              /* nb_negative */
2104
 
        (unaryfunc)delta_positive,              /* nb_positive */
2105
 
        (unaryfunc)delta_abs,                   /* nb_absolute */
2106
 
        (inquiry)delta_bool,                    /* nb_bool */
2107
 
        0,                                      /*nb_invert*/
2108
 
        0,                                      /*nb_lshift*/
2109
 
        0,                                      /*nb_rshift*/
2110
 
        0,                                      /*nb_and*/
2111
 
        0,                                      /*nb_xor*/
2112
 
        0,                                      /*nb_or*/
2113
 
        0,                                      /*nb_int*/
2114
 
        0,                                      /*nb_reserved*/
2115
 
        0,                                      /*nb_float*/
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 */
 
2099
    0,                                          /* nb_divmod */
 
2100
    0,                                          /* nb_power */
 
2101
    (unaryfunc)delta_negative,                  /* nb_negative */
 
2102
    (unaryfunc)delta_positive,                  /* nb_positive */
 
2103
    (unaryfunc)delta_abs,                       /* nb_absolute */
 
2104
    (inquiry)delta_bool,                        /* nb_bool */
 
2105
    0,                                          /*nb_invert*/
 
2106
    0,                                          /*nb_lshift*/
 
2107
    0,                                          /*nb_rshift*/
 
2108
    0,                                          /*nb_and*/
 
2109
    0,                                          /*nb_xor*/
 
2110
    0,                                          /*nb_or*/
 
2111
    0,                                          /*nb_int*/
 
2112
    0,                                          /*nb_reserved*/
 
2113
    0,                                          /*nb_float*/
 
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 */
2130
2128
};
2131
2129
 
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 */
2137
 
        0,                                              /* tp_dealloc */
2138
 
        0,                                              /* tp_print */
2139
 
        0,                                              /* tp_getattr */
2140
 
        0,                                              /* tp_setattr */
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 */
2147
 
        0,                                              /* tp_call */
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 */
2155
 
        0,                                              /* tp_clear */
2156
 
        delta_richcompare,                              /* tp_richcompare */
2157
 
        0,                                              /* tp_weaklistoffset */
2158
 
        0,                                              /* tp_iter */
2159
 
        0,                                              /* tp_iternext */
2160
 
        delta_methods,                                  /* tp_methods */
2161
 
        delta_members,                                  /* tp_members */
2162
 
        0,                                              /* tp_getset */
2163
 
        0,                                              /* tp_base */
2164
 
        0,                                              /* tp_dict */
2165
 
        0,                                              /* tp_descr_get */
2166
 
        0,                                              /* tp_descr_set */
2167
 
        0,                                              /* tp_dictoffset */
2168
 
        0,                                              /* tp_init */
2169
 
        0,                                              /* tp_alloc */
2170
 
        delta_new,                                      /* tp_new */
2171
 
        0,                                              /* tp_free */
 
2131
    PyVarObject_HEAD_INIT(NULL, 0)
 
2132
    "datetime.timedelta",                               /* tp_name */
 
2133
    sizeof(PyDateTime_Delta),                           /* tp_basicsize */
 
2134
    0,                                                  /* tp_itemsize */
 
2135
    0,                                                  /* tp_dealloc */
 
2136
    0,                                                  /* tp_print */
 
2137
    0,                                                  /* tp_getattr */
 
2138
    0,                                                  /* tp_setattr */
 
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 */
 
2145
    0,                                                  /* tp_call */
 
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 */
 
2153
    0,                                                  /* tp_clear */
 
2154
    delta_richcompare,                                  /* tp_richcompare */
 
2155
    0,                                                  /* tp_weaklistoffset */
 
2156
    0,                                                  /* tp_iter */
 
2157
    0,                                                  /* tp_iternext */
 
2158
    delta_methods,                                      /* tp_methods */
 
2159
    delta_members,                                      /* tp_members */
 
2160
    0,                                                  /* tp_getset */
 
2161
    0,                                                  /* tp_base */
 
2162
    0,                                                  /* tp_dict */
 
2163
    0,                                                  /* tp_descr_get */
 
2164
    0,                                                  /* tp_descr_set */
 
2165
    0,                                                  /* tp_dictoffset */
 
2166
    0,                                                  /* tp_init */
 
2167
    0,                                                  /* tp_alloc */
 
2168
    delta_new,                                          /* tp_new */
 
2169
    0,                                                  /* tp_free */
2172
2170
};
2173
2171
 
2174
2172
/*
2180
2178
static PyObject *
2181
2179
date_year(PyDateTime_Date *self, void *unused)
2182
2180
{
2183
 
        return PyLong_FromLong(GET_YEAR(self));
 
2181
    return PyLong_FromLong(GET_YEAR(self));
2184
2182
}
2185
2183
 
2186
2184
static PyObject *
2187
2185
date_month(PyDateTime_Date *self, void *unused)
2188
2186
{
2189
 
        return PyLong_FromLong(GET_MONTH(self));
 
2187
    return PyLong_FromLong(GET_MONTH(self));
2190
2188
}
2191
2189
 
2192
2190
static PyObject *
2193
2191
date_day(PyDateTime_Date *self, void *unused)
2194
2192
{
2195
 
        return PyLong_FromLong(GET_DAY(self));
 
2193
    return PyLong_FromLong(GET_DAY(self));
2196
2194
}
2197
2195
 
2198
2196
static PyGetSetDef date_getset[] = {
2199
 
        {"year",        (getter)date_year},
2200
 
        {"month",       (getter)date_month},
2201
 
        {"day",         (getter)date_day},
2202
 
        {NULL}
 
2197
    {"year",        (getter)date_year},
 
2198
    {"month",       (getter)date_month},
 
2199
    {"day",         (getter)date_day},
 
2200
    {NULL}
2203
2201
};
2204
2202
 
2205
2203
/* Constructors. */
2209
2207
static PyObject *
2210
2208
date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2211
2209
{
2212
 
        PyObject *self = NULL;
2213
 
        PyObject *state;
2214
 
        int year;
2215
 
        int month;
2216
 
        int day;
2217
 
 
2218
 
        /* Check for invocation from pickle with __getstate__ state */
2219
 
        if (PyTuple_GET_SIZE(args) == 1 &&
2220
 
            PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2221
 
            PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2222
 
            MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2223
 
        {
2224
 
                PyDateTime_Date *me;
2225
 
 
2226
 
                me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2227
 
                if (me != NULL) {
2228
 
                        char *pdata = PyBytes_AS_STRING(state);
2229
 
                        memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2230
 
                        me->hashcode = -1;
2231
 
                }
2232
 
                return (PyObject *)me;
2233
 
        }
2234
 
 
2235
 
        if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2236
 
                                        &year, &month, &day)) {
2237
 
                if (check_date_args(year, month, day) < 0)
2238
 
                        return NULL;
2239
 
                self = new_date_ex(year, month, day, type);
2240
 
        }
2241
 
        return self;
 
2210
    PyObject *self = NULL;
 
2211
    PyObject *state;
 
2212
    int year;
 
2213
    int month;
 
2214
    int day;
 
2215
 
 
2216
    /* Check for invocation from pickle with __getstate__ state */
 
2217
    if (PyTuple_GET_SIZE(args) == 1 &&
 
2218
        PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
 
2219
        PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
 
2220
        MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
 
2221
    {
 
2222
        PyDateTime_Date *me;
 
2223
 
 
2224
        me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
 
2225
        if (me != NULL) {
 
2226
            char *pdata = PyBytes_AS_STRING(state);
 
2227
            memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
 
2228
            me->hashcode = -1;
 
2229
        }
 
2230
        return (PyObject *)me;
 
2231
    }
 
2232
 
 
2233
    if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
 
2234
                                    &year, &month, &day)) {
 
2235
        if (check_date_args(year, month, day) < 0)
 
2236
            return NULL;
 
2237
        self = new_date_ex(year, month, day, type);
 
2238
    }
 
2239
    return self;
2242
2240
}
2243
2241
 
2244
2242
/* Return new date from localtime(t). */
2245
2243
static PyObject *
2246
2244
date_local_from_time_t(PyObject *cls, double ts)
2247
2245
{
2248
 
        struct tm *tm;
2249
 
        time_t t;
2250
 
        PyObject *result = NULL;
 
2246
    struct tm *tm;
 
2247
    time_t t;
 
2248
    PyObject *result = NULL;
2251
2249
 
2252
 
        t = _PyTime_DoubleToTimet(ts);
2253
 
        if (t == (time_t)-1 && PyErr_Occurred())
2254
 
                return NULL;
2255
 
        tm = localtime(&t);
2256
 
        if (tm)
2257
 
                result = PyObject_CallFunction(cls, "iii",
2258
 
                                               tm->tm_year + 1900,
2259
 
                                               tm->tm_mon + 1,
2260
 
                                               tm->tm_mday);
2261
 
        else
2262
 
                PyErr_SetString(PyExc_ValueError,
2263
 
                                "timestamp out of range for "
2264
 
                                "platform localtime() function");
2265
 
        return result;
 
2250
    t = _PyTime_DoubleToTimet(ts);
 
2251
    if (t == (time_t)-1 && PyErr_Occurred())
 
2252
        return NULL;
 
2253
    tm = localtime(&t);
 
2254
    if (tm)
 
2255
        result = PyObject_CallFunction(cls, "iii",
 
2256
                                       tm->tm_year + 1900,
 
2257
                                       tm->tm_mon + 1,
 
2258
                                       tm->tm_mday);
 
2259
    else
 
2260
        PyErr_SetString(PyExc_ValueError,
 
2261
                        "timestamp out of range for "
 
2262
                        "platform localtime() function");
 
2263
    return result;
2266
2264
}
2267
2265
 
2268
2266
/* Return new date from current time.
2273
2271
static PyObject *
2274
2272
date_today(PyObject *cls, PyObject *dummy)
2275
2273
{
2276
 
        PyObject *time;
2277
 
        PyObject *result;
2278
 
 
2279
 
        time = time_time();
2280
 
        if (time == NULL)
2281
 
                return NULL;
2282
 
 
2283
 
        /* Note well:  today() is a class method, so this may not call
2284
 
         * date.fromtimestamp.  For example, it may call
2285
 
         * datetime.fromtimestamp.  That's why we need all the accuracy
2286
 
         * time.time() delivers; if someone were gonzo about optimization,
2287
 
         * date.today() could get away with plain C time().
2288
 
         */
2289
 
        result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2290
 
        Py_DECREF(time);
2291
 
        return result;
 
2274
    PyObject *time;
 
2275
    PyObject *result;
 
2276
 
 
2277
    time = time_time();
 
2278
    if (time == NULL)
 
2279
        return NULL;
 
2280
 
 
2281
    /* Note well:  today() is a class method, so this may not call
 
2282
     * date.fromtimestamp.  For example, it may call
 
2283
     * datetime.fromtimestamp.  That's why we need all the accuracy
 
2284
     * time.time() delivers; if someone were gonzo about optimization,
 
2285
     * date.today() could get away with plain C time().
 
2286
     */
 
2287
    result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
 
2288
    Py_DECREF(time);
 
2289
    return result;
2292
2290
}
2293
2291
 
2294
2292
/* Return new date from given timestamp (Python timestamp -- a double). */
2295
2293
static PyObject *
2296
2294
date_fromtimestamp(PyObject *cls, PyObject *args)
2297
2295
{
2298
 
        double timestamp;
2299
 
        PyObject *result = NULL;
 
2296
    double timestamp;
 
2297
    PyObject *result = NULL;
2300
2298
 
2301
 
        if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2302
 
                result = date_local_from_time_t(cls, timestamp);
2303
 
        return result;
 
2299
    if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
 
2300
        result = date_local_from_time_t(cls, timestamp);
 
2301
    return result;
2304
2302
}
2305
2303
 
2306
2304
/* Return new date from proleptic Gregorian ordinal.  Raises ValueError if
2309
2307
static PyObject *
2310
2308
date_fromordinal(PyObject *cls, PyObject *args)
2311
2309
{
2312
 
        PyObject *result = NULL;
2313
 
        int ordinal;
2314
 
 
2315
 
        if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2316
 
                int year;
2317
 
                int month;
2318
 
                int day;
2319
 
 
2320
 
                if (ordinal < 1)
2321
 
                        PyErr_SetString(PyExc_ValueError, "ordinal must be "
2322
 
                                                          ">= 1");
2323
 
                else {
2324
 
                        ord_to_ymd(ordinal, &year, &month, &day);
2325
 
                        result = PyObject_CallFunction(cls, "iii",
2326
 
                                                       year, month, day);
2327
 
                }
2328
 
        }
2329
 
        return result;
 
2310
    PyObject *result = NULL;
 
2311
    int ordinal;
 
2312
 
 
2313
    if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
 
2314
        int year;
 
2315
        int month;
 
2316
        int day;
 
2317
 
 
2318
        if (ordinal < 1)
 
2319
            PyErr_SetString(PyExc_ValueError, "ordinal must be "
 
2320
                                              ">= 1");
 
2321
        else {
 
2322
            ord_to_ymd(ordinal, &year, &month, &day);
 
2323
            result = PyObject_CallFunction(cls, "iii",
 
2324
                                           year, month, day);
 
2325
        }
 
2326
    }
 
2327
    return result;
2330
2328
}
2331
2329
 
2332
2330
/*
2339
2337
static PyObject *
2340
2338
add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2341
2339
{
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);
2348
2346
 
2349
 
        if (normalize_date(&year, &month, &day) >= 0)
2350
 
                result = new_date(year, month, day);
2351
 
        return result;
 
2347
    if (normalize_date(&year, &month, &day) >= 0)
 
2348
        result = new_date(year, month, day);
 
2349
    return result;
2352
2350
}
2353
2351
 
2354
2352
static PyObject *
2355
2353
date_add(PyObject *left, PyObject *right)
2356
2354
{
2357
 
        if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2358
 
                Py_INCREF(Py_NotImplemented);
2359
 
                return Py_NotImplemented;
2360
 
        }
2361
 
        if (PyDate_Check(left)) {
2362
 
                /* date + ??? */
2363
 
                if (PyDelta_Check(right))
2364
 
                        /* date + delta */
2365
 
                        return add_date_timedelta((PyDateTime_Date *) left,
2366
 
                                                  (PyDateTime_Delta *) right,
2367
 
                                                  0);
2368
 
        }
2369
 
        else {
2370
 
                /* ??? + date
2371
 
                 * 'right' must be one of us, or we wouldn't have been called
2372
 
                 */
2373
 
                if (PyDelta_Check(left))
2374
 
                        /* delta + date */
2375
 
                        return add_date_timedelta((PyDateTime_Date *) right,
2376
 
                                                  (PyDateTime_Delta *) left,
2377
 
                                                  0);
2378
 
        }
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;
 
2358
    }
 
2359
    if (PyDate_Check(left)) {
 
2360
        /* date + ??? */
 
2361
        if (PyDelta_Check(right))
 
2362
            /* date + delta */
 
2363
            return add_date_timedelta((PyDateTime_Date *) left,
 
2364
                                      (PyDateTime_Delta *) right,
 
2365
                                      0);
 
2366
    }
 
2367
    else {
 
2368
        /* ??? + date
 
2369
         * 'right' must be one of us, or we wouldn't have been called
 
2370
         */
 
2371
        if (PyDelta_Check(left))
 
2372
            /* delta + date */
 
2373
            return add_date_timedelta((PyDateTime_Date *) right,
 
2374
                                      (PyDateTime_Delta *) left,
 
2375
                                      0);
 
2376
    }
 
2377
    Py_INCREF(Py_NotImplemented);
 
2378
    return Py_NotImplemented;
2381
2379
}
2382
2380
 
2383
2381
static PyObject *
2384
2382
date_subtract(PyObject *left, PyObject *right)
2385
2383
{
2386
 
        if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2387
 
                Py_INCREF(Py_NotImplemented);
2388
 
                return Py_NotImplemented;
2389
 
        }
2390
 
        if (PyDate_Check(left)) {
2391
 
                if (PyDate_Check(right)) {
2392
 
                        /* date - date */
2393
 
                        int left_ord = ymd_to_ord(GET_YEAR(left),
2394
 
                                                  GET_MONTH(left),
2395
 
                                                  GET_DAY(left));
2396
 
                        int right_ord = ymd_to_ord(GET_YEAR(right),
2397
 
                                                   GET_MONTH(right),
2398
 
                                                   GET_DAY(right));
2399
 
                        return new_delta(left_ord - right_ord, 0, 0, 0);
2400
 
                }
2401
 
                if (PyDelta_Check(right)) {
2402
 
                        /* date - delta */
2403
 
                        return add_date_timedelta((PyDateTime_Date *) left,
2404
 
                                                  (PyDateTime_Delta *) right,
2405
 
                                                  1);
2406
 
                }
2407
 
        }
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;
 
2387
    }
 
2388
    if (PyDate_Check(left)) {
 
2389
        if (PyDate_Check(right)) {
 
2390
            /* date - date */
 
2391
            int left_ord = ymd_to_ord(GET_YEAR(left),
 
2392
                                      GET_MONTH(left),
 
2393
                                      GET_DAY(left));
 
2394
            int right_ord = ymd_to_ord(GET_YEAR(right),
 
2395
                                       GET_MONTH(right),
 
2396
                                       GET_DAY(right));
 
2397
            return new_delta(left_ord - right_ord, 0, 0, 0);
 
2398
        }
 
2399
        if (PyDelta_Check(right)) {
 
2400
            /* date - delta */
 
2401
            return add_date_timedelta((PyDateTime_Date *) left,
 
2402
                                      (PyDateTime_Delta *) right,
 
2403
                                      1);
 
2404
        }
 
2405
    }
 
2406
    Py_INCREF(Py_NotImplemented);
 
2407
    return Py_NotImplemented;
2410
2408
}
2411
2409
 
2412
2410
 
2415
2413
static PyObject *
2416
2414
date_repr(PyDateTime_Date *self)
2417
2415
{
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));
2421
2419
}
2422
2420
 
2423
2421
static PyObject *
2424
2422
date_isoformat(PyDateTime_Date *self)
2425
2423
{
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));
2428
2426
}
2429
2427
 
2430
2428
/* str() calls the appropriate isoformat() method. */
2431
2429
static PyObject *
2432
2430
date_str(PyDateTime_Date *self)
2433
2431
{
2434
 
        return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
 
2432
    return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
2435
2433
}
2436
2434
 
2437
2435
 
2438
2436
static PyObject *
2439
2437
date_ctime(PyDateTime_Date *self)
2440
2438
{
2441
 
        return format_ctime(self, 0, 0, 0);
 
2439
    return format_ctime(self, 0, 0, 0);
2442
2440
}
2443
2441
 
2444
2442
static PyObject *
2445
2443
date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2446
2444
{
2447
 
        /* This method can be inherited, and needs to call the
2448
 
         * timetuple() method appropriate to self's class.
2449
 
         */
2450
 
        PyObject *result;
2451
 
        PyObject *tuple;
2452
 
        PyObject *format;
2453
 
        static char *keywords[] = {"format", NULL};
2454
 
 
2455
 
        if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2456
 
                                          &format))
2457
 
                return NULL;
2458
 
 
2459
 
        tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2460
 
        if (tuple == NULL)
2461
 
                return NULL;
2462
 
        result = wrap_strftime((PyObject *)self, format, tuple,
2463
 
                               (PyObject *)self);
2464
 
        Py_DECREF(tuple);
2465
 
        return result;
 
2445
    /* This method can be inherited, and needs to call the
 
2446
     * timetuple() method appropriate to self's class.
 
2447
     */
 
2448
    PyObject *result;
 
2449
    PyObject *tuple;
 
2450
    PyObject *format;
 
2451
    static char *keywords[] = {"format", NULL};
 
2452
 
 
2453
    if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
 
2454
                                      &format))
 
2455
        return NULL;
 
2456
 
 
2457
    tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
 
2458
    if (tuple == NULL)
 
2459
        return NULL;
 
2460
    result = wrap_strftime((PyObject *)self, format, tuple,
 
2461
                           (PyObject *)self);
 
2462
    Py_DECREF(tuple);
 
2463
    return result;
2466
2464
}
2467
2465
 
2468
2466
static PyObject *
2469
2467
date_format(PyDateTime_Date *self, PyObject *args)
2470
2468
{
2471
 
        PyObject *format;
2472
 
 
2473
 
        if (!PyArg_ParseTuple(args, "U:__format__", &format))
2474
 
                return NULL;
2475
 
 
2476
 
        /* if the format is zero length, return str(self) */
2477
 
        if (PyUnicode_GetSize(format) == 0)
2478
 
                return PyObject_Str((PyObject *)self);
2479
 
 
2480
 
        return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
 
2469
    PyObject *format;
 
2470
 
 
2471
    if (!PyArg_ParseTuple(args, "U:__format__", &format))
 
2472
        return NULL;
 
2473
 
 
2474
    /* if the format is zero length, return str(self) */
 
2475
    if (PyUnicode_GetSize(format) == 0)
 
2476
        return PyObject_Str((PyObject *)self);
 
2477
 
 
2478
    return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
2481
2479
}
2482
2480
 
2483
2481
/* ISO methods. */
2485
2483
static PyObject *
2486
2484
date_isoweekday(PyDateTime_Date *self)
2487
2485
{
2488
 
        int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
 
2486
    int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2489
2487
 
2490
 
        return PyLong_FromLong(dow + 1);
 
2488
    return PyLong_FromLong(dow + 1);
2491
2489
}
2492
2490
 
2493
2491
static PyObject *
2494
2492
date_isocalendar(PyDateTime_Date *self)
2495
2493
{
2496
 
        int  year         = GET_YEAR(self);
2497
 
        int  week1_monday = iso_week1_monday(year);
2498
 
        int today         = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2499
 
        int  week;
2500
 
        int  day;
 
2494
    int  year         = GET_YEAR(self);
 
2495
    int  week1_monday = iso_week1_monday(year);
 
2496
    int today         = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
 
2497
    int  week;
 
2498
    int  day;
2501
2499
 
2502
 
        week = divmod(today - week1_monday, 7, &day);
2503
 
        if (week < 0) {
2504
 
                --year;
2505
 
                week1_monday = iso_week1_monday(year);
2506
 
                week = divmod(today - week1_monday, 7, &day);
2507
 
        }
2508
 
        else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2509
 
                ++year;
2510
 
                week = 0;
2511
 
        }
2512
 
        return Py_BuildValue("iii", year, week + 1, day + 1);
 
2500
    week = divmod(today - week1_monday, 7, &day);
 
2501
    if (week < 0) {
 
2502
        --year;
 
2503
        week1_monday = iso_week1_monday(year);
 
2504
        week = divmod(today - week1_monday, 7, &day);
 
2505
    }
 
2506
    else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
 
2507
        ++year;
 
2508
        week = 0;
 
2509
    }
 
2510
    return Py_BuildValue("iii", year, week + 1, day + 1);
2513
2511
}
2514
2512
 
2515
2513
/* Miscellaneous methods. */
2517
2515
static PyObject *
2518
2516
date_richcompare(PyObject *self, PyObject *other, int op)
2519
2517
{
2520
 
        if (PyDate_Check(other)) {
2521
 
                int diff = memcmp(((PyDateTime_Date *)self)->data,
2522
 
                                  ((PyDateTime_Date *)other)->data,
2523
 
                                  _PyDateTime_DATE_DATASIZE);
2524
 
                return diff_to_bool(diff, op);
2525
 
        }
2526
 
        else {
2527
 
                Py_INCREF(Py_NotImplemented);
2528
 
                return Py_NotImplemented;
2529
 
        }
 
2518
    if (PyDate_Check(other)) {
 
2519
        int diff = memcmp(((PyDateTime_Date *)self)->data,
 
2520
                          ((PyDateTime_Date *)other)->data,
 
2521
                          _PyDateTime_DATE_DATASIZE);
 
2522
        return diff_to_bool(diff, op);
 
2523
    }
 
2524
    else {
 
2525
        Py_INCREF(Py_NotImplemented);
 
2526
        return Py_NotImplemented;
 
2527
    }
2530
2528
}
2531
2529
 
2532
2530
static PyObject *
2533
2531
date_timetuple(PyDateTime_Date *self)
2534
2532
{
2535
 
        return build_struct_time(GET_YEAR(self),
2536
 
                                 GET_MONTH(self),
2537
 
                                 GET_DAY(self),
2538
 
                                 0, 0, 0, -1);
 
2533
    return build_struct_time(GET_YEAR(self),
 
2534
                             GET_MONTH(self),
 
2535
                             GET_DAY(self),
 
2536
                             0, 0, 0, -1);
2539
2537
}
2540
2538
 
2541
2539
static PyObject *
2542
2540
date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2543
2541
{
2544
 
        PyObject *clone;
2545
 
        PyObject *tuple;
2546
 
        int year = GET_YEAR(self);
2547
 
        int month = GET_MONTH(self);
2548
 
        int day = GET_DAY(self);
 
2542
    PyObject *clone;
 
2543
    PyObject *tuple;
 
2544
    int year = GET_YEAR(self);
 
2545
    int month = GET_MONTH(self);
 
2546
    int day = GET_DAY(self);
2549
2547
 
2550
 
        if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2551
 
                                          &year, &month, &day))
2552
 
                return NULL;
2553
 
        tuple = Py_BuildValue("iii", year, month, day);
2554
 
        if (tuple == NULL)
2555
 
                return NULL;
2556
 
        clone = date_new(Py_TYPE(self), tuple, NULL);
2557
 
        Py_DECREF(tuple);
2558
 
        return clone;
 
2548
    if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
 
2549
                                      &year, &month, &day))
 
2550
        return NULL;
 
2551
    tuple = Py_BuildValue("iii", year, month, day);
 
2552
    if (tuple == NULL)
 
2553
        return NULL;
 
2554
    clone = date_new(Py_TYPE(self), tuple, NULL);
 
2555
    Py_DECREF(tuple);
 
2556
    return clone;
2559
2557
}
2560
2558
 
2561
2559
/*
2562
 
        Borrowed from stringobject.c, originally it was string_hash()
 
2560
    Borrowed from stringobject.c, originally it was string_hash()
2563
2561
*/
2564
2562
static long
2565
2563
generic_hash(unsigned char *data, int len)
2566
2564
{
2567
 
        register unsigned char *p;
2568
 
        register long x;
2569
 
 
2570
 
        p = (unsigned char *) data;
2571
 
        x = *p << 7;
2572
 
        while (--len >= 0)
2573
 
                x = (1000003*x) ^ *p++;
2574
 
        x ^= len;
2575
 
        if (x == -1)
2576
 
                x = -2;
2577
 
 
2578
 
        return x;
 
2565
    register unsigned char *p;
 
2566
    register long x;
 
2567
 
 
2568
    p = (unsigned char *) data;
 
2569
    x = *p << 7;
 
2570
    while (--len >= 0)
 
2571
        x = (1000003*x) ^ *p++;
 
2572
    x ^= len;
 
2573
    if (x == -1)
 
2574
        x = -2;
 
2575
 
 
2576
    return x;
2579
2577
}
2580
2578
 
2581
2579
 
2584
2582
static long
2585
2583
date_hash(PyDateTime_Date *self)
2586
2584
{
2587
 
        if (self->hashcode == -1)
2588
 
                self->hashcode = generic_hash(
2589
 
                        (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
 
2585
    if (self->hashcode == -1)
 
2586
        self->hashcode = generic_hash(
 
2587
            (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
2590
2588
 
2591
 
        return self->hashcode;
 
2589
    return self->hashcode;
2592
2590
}
2593
2591
 
2594
2592
static PyObject *
2595
2593
date_toordinal(PyDateTime_Date *self)
2596
2594
{
2597
 
        return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2598
 
                                         GET_DAY(self)));
 
2595
    return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
 
2596
                                     GET_DAY(self)));
2599
2597
}
2600
2598
 
2601
2599
static PyObject *
2602
2600
date_weekday(PyDateTime_Date *self)
2603
2601
{
2604
 
        int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
 
2602
    int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2605
2603
 
2606
 
        return PyLong_FromLong(dow);
 
2604
    return PyLong_FromLong(dow);
2607
2605
}
2608
2606
 
2609
2607
/* Pickle support, a simple use of __reduce__. */
2612
2610
static PyObject *
2613
2611
date_getstate(PyDateTime_Date *self)
2614
2612
{
2615
 
        PyObject* field;
2616
 
        field = PyBytes_FromStringAndSize((char*)self->data,
2617
 
                                           _PyDateTime_DATE_DATASIZE);
2618
 
        return Py_BuildValue("(N)", field);
 
2613
    PyObject* field;
 
2614
    field = PyBytes_FromStringAndSize((char*)self->data,
 
2615
                                       _PyDateTime_DATE_DATASIZE);
 
2616
    return Py_BuildValue("(N)", field);
2619
2617
}
2620
2618
 
2621
2619
static PyObject *
2622
2620
date_reduce(PyDateTime_Date *self, PyObject *arg)
2623
2621
{
2624
 
        return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
 
2622
    return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
2625
2623
}
2626
2624
 
2627
2625
static PyMethodDef date_methods[] = {
2628
2626
 
2629
 
        /* Class methods: */
2630
 
 
2631
 
        {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2632
 
                                                           METH_CLASS,
2633
 
         PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2634
 
                   "time.time()).")},
2635
 
 
2636
 
        {"fromordinal", (PyCFunction)date_fromordinal,  METH_VARARGS |
2637
 
                                                        METH_CLASS,
2638
 
         PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2639
 
                   "ordinal.")},
2640
 
 
2641
 
        {"today",         (PyCFunction)date_today,   METH_NOARGS | METH_CLASS,
2642
 
         PyDoc_STR("Current date or datetime:  same as "
2643
 
                   "self.__class__.fromtimestamp(time.time()).")},
2644
 
 
2645
 
        /* Instance methods: */
2646
 
 
2647
 
        {"ctime",       (PyCFunction)date_ctime,        METH_NOARGS,
2648
 
         PyDoc_STR("Return ctime() style string.")},
2649
 
 
2650
 
        {"strftime",    (PyCFunction)date_strftime,     METH_VARARGS | METH_KEYWORDS,
2651
 
         PyDoc_STR("format -> strftime() style string.")},
2652
 
 
2653
 
        {"__format__",  (PyCFunction)date_format,       METH_VARARGS,
2654
 
         PyDoc_STR("Formats self with strftime.")},
2655
 
 
2656
 
        {"timetuple",   (PyCFunction)date_timetuple,    METH_NOARGS,
2657
 
         PyDoc_STR("Return time tuple, compatible with time.localtime().")},
2658
 
 
2659
 
        {"isocalendar", (PyCFunction)date_isocalendar,  METH_NOARGS,
2660
 
         PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2661
 
                   "weekday.")},
2662
 
 
2663
 
        {"isoformat",   (PyCFunction)date_isoformat,    METH_NOARGS,
2664
 
         PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
2665
 
 
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")},
2669
 
 
2670
 
        {"toordinal",   (PyCFunction)date_toordinal,    METH_NOARGS,
2671
 
         PyDoc_STR("Return proleptic Gregorian ordinal.  January 1 of year "
2672
 
                   "1 is day 1.")},
2673
 
 
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")},
2677
 
 
2678
 
        {"replace",     (PyCFunction)date_replace,      METH_VARARGS | METH_KEYWORDS,
2679
 
         PyDoc_STR("Return date with new specified fields.")},
2680
 
 
2681
 
        {"__reduce__", (PyCFunction)date_reduce,        METH_NOARGS,
2682
 
         PyDoc_STR("__reduce__() -> (cls, state)")},
2683
 
 
2684
 
        {NULL,  NULL}
 
2627
    /* Class methods: */
 
2628
 
 
2629
    {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
 
2630
                                                       METH_CLASS,
 
2631
     PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
 
2632
               "time.time()).")},
 
2633
 
 
2634
    {"fromordinal", (PyCFunction)date_fromordinal,      METH_VARARGS |
 
2635
                                                    METH_CLASS,
 
2636
     PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
 
2637
               "ordinal.")},
 
2638
 
 
2639
    {"today",         (PyCFunction)date_today,   METH_NOARGS | METH_CLASS,
 
2640
     PyDoc_STR("Current date or datetime:  same as "
 
2641
               "self.__class__.fromtimestamp(time.time()).")},
 
2642
 
 
2643
    /* Instance methods: */
 
2644
 
 
2645
    {"ctime",       (PyCFunction)date_ctime,        METH_NOARGS,
 
2646
     PyDoc_STR("Return ctime() style string.")},
 
2647
 
 
2648
    {"strftime",        (PyCFunction)date_strftime,     METH_VARARGS | METH_KEYWORDS,
 
2649
     PyDoc_STR("format -> strftime() style string.")},
 
2650
 
 
2651
    {"__format__",      (PyCFunction)date_format,       METH_VARARGS,
 
2652
     PyDoc_STR("Formats self with strftime.")},
 
2653
 
 
2654
    {"timetuple",   (PyCFunction)date_timetuple,    METH_NOARGS,
 
2655
     PyDoc_STR("Return time tuple, compatible with time.localtime().")},
 
2656
 
 
2657
    {"isocalendar", (PyCFunction)date_isocalendar,  METH_NOARGS,
 
2658
     PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
 
2659
               "weekday.")},
 
2660
 
 
2661
    {"isoformat",   (PyCFunction)date_isoformat,        METH_NOARGS,
 
2662
     PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
 
2663
 
 
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")},
 
2667
 
 
2668
    {"toordinal",   (PyCFunction)date_toordinal,    METH_NOARGS,
 
2669
     PyDoc_STR("Return proleptic Gregorian ordinal.  January 1 of year "
 
2670
               "1 is day 1.")},
 
2671
 
 
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")},
 
2675
 
 
2676
    {"replace",     (PyCFunction)date_replace,      METH_VARARGS | METH_KEYWORDS,
 
2677
     PyDoc_STR("Return date with new specified fields.")},
 
2678
 
 
2679
    {"__reduce__", (PyCFunction)date_reduce,        METH_NOARGS,
 
2680
     PyDoc_STR("__reduce__() -> (cls, state)")},
 
2681
 
 
2682
    {NULL,      NULL}
2685
2683
};
2686
2684
 
2687
2685
static char date_doc[] =
2688
2686
PyDoc_STR("date(year, month, day) --> date object");
2689
2687
 
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 */
2695
 
        0,                                              /* nb_divmod */
2696
 
        0,                                              /* nb_power */
2697
 
        0,                                              /* nb_negative */
2698
 
        0,                                              /* nb_positive */
2699
 
        0,                                              /* nb_absolute */
2700
 
        0,                                              /* nb_bool */
 
2689
    date_add,                                           /* nb_add */
 
2690
    date_subtract,                                      /* nb_subtract */
 
2691
    0,                                                  /* nb_multiply */
 
2692
    0,                                                  /* nb_remainder */
 
2693
    0,                                                  /* nb_divmod */
 
2694
    0,                                                  /* nb_power */
 
2695
    0,                                                  /* nb_negative */
 
2696
    0,                                                  /* nb_positive */
 
2697
    0,                                                  /* nb_absolute */
 
2698
    0,                                                  /* nb_bool */
2701
2699
};
2702
2700
 
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 */
2708
 
        0,                                              /* tp_dealloc */
2709
 
        0,                                              /* tp_print */
2710
 
        0,                                              /* tp_getattr */
2711
 
        0,                                              /* tp_setattr */
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 */
2718
 
        0,                                              /* tp_call */
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 */
2726
 
        0,                                              /* tp_clear */
2727
 
        date_richcompare,                               /* tp_richcompare */
2728
 
        0,                                              /* tp_weaklistoffset */
2729
 
        0,                                              /* tp_iter */
2730
 
        0,                                              /* tp_iternext */
2731
 
        date_methods,                                   /* tp_methods */
2732
 
        0,                                              /* tp_members */
2733
 
        date_getset,                                    /* tp_getset */
2734
 
        0,                                              /* tp_base */
2735
 
        0,                                              /* tp_dict */
2736
 
        0,                                              /* tp_descr_get */
2737
 
        0,                                              /* tp_descr_set */
2738
 
        0,                                              /* tp_dictoffset */
2739
 
        0,                                              /* tp_init */
2740
 
        0,                                              /* tp_alloc */
2741
 
        date_new,                                       /* tp_new */
2742
 
        0,                                              /* tp_free */
 
2702
    PyVarObject_HEAD_INIT(NULL, 0)
 
2703
    "datetime.date",                                    /* tp_name */
 
2704
    sizeof(PyDateTime_Date),                            /* tp_basicsize */
 
2705
    0,                                                  /* tp_itemsize */
 
2706
    0,                                                  /* tp_dealloc */
 
2707
    0,                                                  /* tp_print */
 
2708
    0,                                                  /* tp_getattr */
 
2709
    0,                                                  /* tp_setattr */
 
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 */
 
2716
    0,                                                  /* tp_call */
 
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 */
 
2724
    0,                                                  /* tp_clear */
 
2725
    date_richcompare,                                   /* tp_richcompare */
 
2726
    0,                                                  /* tp_weaklistoffset */
 
2727
    0,                                                  /* tp_iter */
 
2728
    0,                                                  /* tp_iternext */
 
2729
    date_methods,                                       /* tp_methods */
 
2730
    0,                                                  /* tp_members */
 
2731
    date_getset,                                        /* tp_getset */
 
2732
    0,                                                  /* tp_base */
 
2733
    0,                                                  /* tp_dict */
 
2734
    0,                                                  /* tp_descr_get */
 
2735
    0,                                                  /* tp_descr_set */
 
2736
    0,                                                  /* tp_dictoffset */
 
2737
    0,                                                  /* tp_init */
 
2738
    0,                                                  /* tp_alloc */
 
2739
    date_new,                                           /* tp_new */
 
2740
    0,                                                  /* tp_free */
2743
2741
};
2744
2742
 
2745
2743
/*
2762
2760
static PyObject *
2763
2761
tzinfo_nogo(const char* methodname)
2764
2762
{
2765
 
        PyErr_Format(PyExc_NotImplementedError,
2766
 
                     "a tzinfo subclass must implement %s()",
2767
 
                     methodname);
2768
 
        return NULL;
 
2763
    PyErr_Format(PyExc_NotImplementedError,
 
2764
                 "a tzinfo subclass must implement %s()",
 
2765
                 methodname);
 
2766
    return NULL;
2769
2767
}
2770
2768
 
2771
2769
/* Methods.  A subclass must implement these. */
2773
2771
static PyObject *
2774
2772
tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2775
2773
{
2776
 
        return tzinfo_nogo("tzname");
 
2774
    return tzinfo_nogo("tzname");
2777
2775
}
2778
2776
 
2779
2777
static PyObject *
2780
2778
tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2781
2779
{
2782
 
        return tzinfo_nogo("utcoffset");
 
2780
    return tzinfo_nogo("utcoffset");
2783
2781
}
2784
2782
 
2785
2783
static PyObject *
2786
2784
tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2787
2785
{
2788
 
        return tzinfo_nogo("dst");
 
2786
    return tzinfo_nogo("dst");
2789
2787
}
2790
2788
 
2791
2789
static PyObject *
2792
2790
tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
2793
2791
{
2794
 
        int y, m, d, hh, mm, ss, us;
2795
 
 
2796
 
        PyObject *result;
2797
 
        int off, dst;
2798
 
        int none;
2799
 
        int delta;
2800
 
 
2801
 
        if (! PyDateTime_Check(dt)) {
2802
 
                PyErr_SetString(PyExc_TypeError,
2803
 
                                "fromutc: argument must be a datetime");
2804
 
                return NULL;
2805
 
        }
2806
 
        if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
2807
 
                PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2808
 
                                "is not self");
2809
 
                return NULL;
2810
 
        }
2811
 
 
2812
 
        off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
2813
 
        if (off == -1 && PyErr_Occurred())
2814
 
                return NULL;
2815
 
        if (none) {
2816
 
                PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2817
 
                                "utcoffset() result required");
2818
 
                return NULL;
2819
 
        }
2820
 
 
2821
 
        dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
2822
 
        if (dst == -1 && PyErr_Occurred())
2823
 
                return NULL;
2824
 
        if (none) {
2825
 
                PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2826
 
                                "dst() result required");
2827
 
                return NULL;
2828
 
        }
2829
 
 
2830
 
        y = GET_YEAR(dt);
2831
 
        m = GET_MONTH(dt);
2832
 
        d = GET_DAY(dt);
2833
 
        hh = DATE_GET_HOUR(dt);
2834
 
        mm = DATE_GET_MINUTE(dt);
2835
 
        ss = DATE_GET_SECOND(dt);
2836
 
        us = DATE_GET_MICROSECOND(dt);
2837
 
 
2838
 
        delta = off - dst;
2839
 
        mm += delta;
2840
 
        if ((mm < 0 || mm >= 60) &&
2841
 
            normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2842
 
                return NULL;
2843
 
        result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2844
 
        if (result == NULL)
2845
 
                return result;
2846
 
 
2847
 
        dst = call_dst(dt->tzinfo, result, &none);
2848
 
        if (dst == -1 && PyErr_Occurred())
2849
 
                goto Fail;
2850
 
        if (none)
2851
 
                goto Inconsistent;
2852
 
        if (dst == 0)
2853
 
                return result;
2854
 
 
2855
 
        mm += dst;
2856
 
        if ((mm < 0 || mm >= 60) &&
2857
 
            normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2858
 
                goto Fail;
2859
 
        Py_DECREF(result);
2860
 
        result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2861
 
        return result;
 
2792
    int y, m, d, hh, mm, ss, us;
 
2793
 
 
2794
    PyObject *result;
 
2795
    int off, dst;
 
2796
    int none;
 
2797
    int delta;
 
2798
 
 
2799
    if (! PyDateTime_Check(dt)) {
 
2800
        PyErr_SetString(PyExc_TypeError,
 
2801
                        "fromutc: argument must be a datetime");
 
2802
        return NULL;
 
2803
    }
 
2804
    if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
 
2805
        PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
 
2806
                        "is not self");
 
2807
        return NULL;
 
2808
    }
 
2809
 
 
2810
    off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
 
2811
    if (off == -1 && PyErr_Occurred())
 
2812
        return NULL;
 
2813
    if (none) {
 
2814
        PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
 
2815
                        "utcoffset() result required");
 
2816
        return NULL;
 
2817
    }
 
2818
 
 
2819
    dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
 
2820
    if (dst == -1 && PyErr_Occurred())
 
2821
        return NULL;
 
2822
    if (none) {
 
2823
        PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
 
2824
                        "dst() result required");
 
2825
        return NULL;
 
2826
    }
 
2827
 
 
2828
    y = GET_YEAR(dt);
 
2829
    m = GET_MONTH(dt);
 
2830
    d = GET_DAY(dt);
 
2831
    hh = DATE_GET_HOUR(dt);
 
2832
    mm = DATE_GET_MINUTE(dt);
 
2833
    ss = DATE_GET_SECOND(dt);
 
2834
    us = DATE_GET_MICROSECOND(dt);
 
2835
 
 
2836
    delta = off - dst;
 
2837
    mm += delta;
 
2838
    if ((mm < 0 || mm >= 60) &&
 
2839
        normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
 
2840
        return NULL;
 
2841
    result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
 
2842
    if (result == NULL)
 
2843
        return result;
 
2844
 
 
2845
    dst = call_dst(dt->tzinfo, result, &none);
 
2846
    if (dst == -1 && PyErr_Occurred())
 
2847
        goto Fail;
 
2848
    if (none)
 
2849
        goto Inconsistent;
 
2850
    if (dst == 0)
 
2851
        return result;
 
2852
 
 
2853
    mm += dst;
 
2854
    if ((mm < 0 || mm >= 60) &&
 
2855
        normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
 
2856
        goto Fail;
 
2857
    Py_DECREF(result);
 
2858
    result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
 
2859
    return result;
2862
2860
 
2863
2861
Inconsistent:
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");
2866
2864
 
2867
 
        /* fall thru to failure */
 
2865
    /* fall thru to failure */
2868
2866
Fail:
2869
 
        Py_DECREF(result);
2870
 
        return NULL;
 
2867
    Py_DECREF(result);
 
2868
    return NULL;
2871
2869
}
2872
2870
 
2873
2871
/*
2878
2876
static PyObject *
2879
2877
tzinfo_reduce(PyObject *self)
2880
2878
{
2881
 
        PyObject *args, *state, *tmp;
2882
 
        PyObject *getinitargs, *getstate;
2883
 
 
2884
 
        tmp = PyTuple_New(0);
2885
 
        if (tmp == NULL)
2886
 
                return NULL;
2887
 
 
2888
 
        getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
2889
 
        if (getinitargs != NULL) {
2890
 
                args = PyObject_CallObject(getinitargs, tmp);
2891
 
                Py_DECREF(getinitargs);
2892
 
                if (args == NULL) {
2893
 
                        Py_DECREF(tmp);
2894
 
                        return NULL;
2895
 
                }
2896
 
        }
2897
 
        else {
2898
 
                PyErr_Clear();
2899
 
                args = tmp;
2900
 
                Py_INCREF(args);
2901
 
        }
2902
 
 
2903
 
        getstate = PyObject_GetAttrString(self, "__getstate__");
2904
 
        if (getstate != NULL) {
2905
 
                state = PyObject_CallObject(getstate, tmp);
2906
 
                Py_DECREF(getstate);
2907
 
                if (state == NULL) {
2908
 
                        Py_DECREF(args);
2909
 
                        Py_DECREF(tmp);
2910
 
                        return NULL;
2911
 
                }
2912
 
        }
2913
 
        else {
2914
 
                PyObject **dictptr;
2915
 
                PyErr_Clear();
2916
 
                state = Py_None;
2917
 
                dictptr = _PyObject_GetDictPtr(self);
2918
 
                if (dictptr && *dictptr && PyDict_Size(*dictptr))
2919
 
                        state = *dictptr;
2920
 
                Py_INCREF(state);
2921
 
        }
2922
 
 
2923
 
        Py_DECREF(tmp);
2924
 
 
2925
 
        if (state == Py_None) {
2926
 
                Py_DECREF(state);
2927
 
                return Py_BuildValue("(ON)", Py_TYPE(self), args);
2928
 
        }
2929
 
        else
2930
 
                return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
 
2879
    PyObject *args, *state, *tmp;
 
2880
    PyObject *getinitargs, *getstate;
 
2881
 
 
2882
    tmp = PyTuple_New(0);
 
2883
    if (tmp == NULL)
 
2884
        return NULL;
 
2885
 
 
2886
    getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
 
2887
    if (getinitargs != NULL) {
 
2888
        args = PyObject_CallObject(getinitargs, tmp);
 
2889
        Py_DECREF(getinitargs);
 
2890
        if (args == NULL) {
 
2891
            Py_DECREF(tmp);
 
2892
            return NULL;
 
2893
        }
 
2894
    }
 
2895
    else {
 
2896
        PyErr_Clear();
 
2897
        args = tmp;
 
2898
        Py_INCREF(args);
 
2899
    }
 
2900
 
 
2901
    getstate = PyObject_GetAttrString(self, "__getstate__");
 
2902
    if (getstate != NULL) {
 
2903
        state = PyObject_CallObject(getstate, tmp);
 
2904
        Py_DECREF(getstate);
 
2905
        if (state == NULL) {
 
2906
            Py_DECREF(args);
 
2907
            Py_DECREF(tmp);
 
2908
            return NULL;
 
2909
        }
 
2910
    }
 
2911
    else {
 
2912
        PyObject **dictptr;
 
2913
        PyErr_Clear();
 
2914
        state = Py_None;
 
2915
        dictptr = _PyObject_GetDictPtr(self);
 
2916
        if (dictptr && *dictptr && PyDict_Size(*dictptr))
 
2917
            state = *dictptr;
 
2918
        Py_INCREF(state);
 
2919
    }
 
2920
 
 
2921
    Py_DECREF(tmp);
 
2922
 
 
2923
    if (state == Py_None) {
 
2924
        Py_DECREF(state);
 
2925
        return Py_BuildValue("(ON)", Py_TYPE(self), args);
 
2926
    }
 
2927
    else
 
2928
        return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
2931
2929
}
2932
2930
 
2933
2931
static PyMethodDef tzinfo_methods[] = {
2934
2932
 
2935
 
        {"tzname",      (PyCFunction)tzinfo_tzname,             METH_O,
2936
 
         PyDoc_STR("datetime -> string name of time zone.")},
2937
 
 
2938
 
        {"utcoffset",   (PyCFunction)tzinfo_utcoffset,          METH_O,
2939
 
         PyDoc_STR("datetime -> minutes east of UTC (negative for "
2940
 
                   "west of UTC).")},
2941
 
 
2942
 
        {"dst",         (PyCFunction)tzinfo_dst,                METH_O,
2943
 
         PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
2944
 
 
2945
 
        {"fromutc",     (PyCFunction)tzinfo_fromutc,            METH_O,
2946
 
         PyDoc_STR("datetime in UTC -> datetime in local time.")},
2947
 
 
2948
 
        {"__reduce__",  (PyCFunction)tzinfo_reduce,             METH_NOARGS,
2949
 
         PyDoc_STR("-> (cls, state)")},
2950
 
 
2951
 
        {NULL, NULL}
 
2933
    {"tzname",          (PyCFunction)tzinfo_tzname,             METH_O,
 
2934
     PyDoc_STR("datetime -> string name of time zone.")},
 
2935
 
 
2936
    {"utcoffset",       (PyCFunction)tzinfo_utcoffset,          METH_O,
 
2937
     PyDoc_STR("datetime -> minutes east of UTC (negative for "
 
2938
               "west of UTC).")},
 
2939
 
 
2940
    {"dst",             (PyCFunction)tzinfo_dst,                METH_O,
 
2941
     PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
 
2942
 
 
2943
    {"fromutc",         (PyCFunction)tzinfo_fromutc,            METH_O,
 
2944
     PyDoc_STR("datetime in UTC -> datetime in local time.")},
 
2945
 
 
2946
    {"__reduce__",  (PyCFunction)tzinfo_reduce,             METH_NOARGS,
 
2947
     PyDoc_STR("-> (cls, state)")},
 
2948
 
 
2949
    {NULL, NULL}
2952
2950
};
2953
2951
 
2954
2952
static char tzinfo_doc[] =
2955
2953
PyDoc_STR("Abstract base class for time zone info objects.");
2956
2954
 
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 */
2962
 
        0,                                      /* tp_dealloc */
2963
 
        0,                                      /* tp_print */
2964
 
        0,                                      /* tp_getattr */
2965
 
        0,                                      /* tp_setattr */
2966
 
        0,                                      /* tp_reserved */
2967
 
        0,                                      /* tp_repr */
2968
 
        0,                                      /* tp_as_number */
2969
 
        0,                                      /* tp_as_sequence */
2970
 
        0,                                      /* tp_as_mapping */
2971
 
        0,                                      /* tp_hash */
2972
 
        0,                                      /* tp_call */
2973
 
        0,                                      /* tp_str */
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 */
2980
 
        0,                                      /* tp_clear */
2981
 
        0,                                      /* tp_richcompare */
2982
 
        0,                                      /* tp_weaklistoffset */
2983
 
        0,                                      /* tp_iter */
2984
 
        0,                                      /* tp_iternext */
2985
 
        tzinfo_methods,                         /* tp_methods */
2986
 
        0,                                      /* tp_members */
2987
 
        0,                                      /* tp_getset */
2988
 
        0,                                      /* tp_base */
2989
 
        0,                                      /* tp_dict */
2990
 
        0,                                      /* tp_descr_get */
2991
 
        0,                                      /* tp_descr_set */
2992
 
        0,                                      /* tp_dictoffset */
2993
 
        0,                                      /* tp_init */
2994
 
        0,                                      /* tp_alloc */
2995
 
        PyType_GenericNew,                      /* tp_new */
2996
 
        0,                                      /* tp_free */
 
2956
    PyVarObject_HEAD_INIT(NULL, 0)
 
2957
    "datetime.tzinfo",                          /* tp_name */
 
2958
    sizeof(PyDateTime_TZInfo),                  /* tp_basicsize */
 
2959
    0,                                          /* tp_itemsize */
 
2960
    0,                                          /* tp_dealloc */
 
2961
    0,                                          /* tp_print */
 
2962
    0,                                          /* tp_getattr */
 
2963
    0,                                          /* tp_setattr */
 
2964
    0,                                          /* tp_reserved */
 
2965
    0,                                          /* tp_repr */
 
2966
    0,                                          /* tp_as_number */
 
2967
    0,                                          /* tp_as_sequence */
 
2968
    0,                                          /* tp_as_mapping */
 
2969
    0,                                          /* tp_hash */
 
2970
    0,                                          /* tp_call */
 
2971
    0,                                          /* tp_str */
 
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 */
 
2978
    0,                                          /* tp_clear */
 
2979
    0,                                          /* tp_richcompare */
 
2980
    0,                                          /* tp_weaklistoffset */
 
2981
    0,                                          /* tp_iter */
 
2982
    0,                                          /* tp_iternext */
 
2983
    tzinfo_methods,                             /* tp_methods */
 
2984
    0,                                          /* tp_members */
 
2985
    0,                                          /* tp_getset */
 
2986
    0,                                          /* tp_base */
 
2987
    0,                                          /* tp_dict */
 
2988
    0,                                          /* tp_descr_get */
 
2989
    0,                                          /* tp_descr_set */
 
2990
    0,                                          /* tp_dictoffset */
 
2991
    0,                                          /* tp_init */
 
2992
    0,                                          /* tp_alloc */
 
2993
    PyType_GenericNew,                          /* tp_new */
 
2994
    0,                                          /* tp_free */
2997
2995
};
2998
2996
 
2999
2997
/*
3006
3004
static PyObject *
3007
3005
time_hour(PyDateTime_Time *self, void *unused)
3008
3006
{
3009
 
        return PyLong_FromLong(TIME_GET_HOUR(self));
 
3007
    return PyLong_FromLong(TIME_GET_HOUR(self));
3010
3008
}
3011
3009
 
3012
3010
static PyObject *
3013
3011
time_minute(PyDateTime_Time *self, void *unused)
3014
3012
{
3015
 
        return PyLong_FromLong(TIME_GET_MINUTE(self));
 
3013
    return PyLong_FromLong(TIME_GET_MINUTE(self));
3016
3014
}
3017
3015
 
3018
3016
/* The name time_second conflicted with some platform header file. */
3019
3017
static PyObject *
3020
3018
py_time_second(PyDateTime_Time *self, void *unused)
3021
3019
{
3022
 
        return PyLong_FromLong(TIME_GET_SECOND(self));
 
3020
    return PyLong_FromLong(TIME_GET_SECOND(self));
3023
3021
}
3024
3022
 
3025
3023
static PyObject *
3026
3024
time_microsecond(PyDateTime_Time *self, void *unused)
3027
3025
{
3028
 
        return PyLong_FromLong(TIME_GET_MICROSECOND(self));
 
3026
    return PyLong_FromLong(TIME_GET_MICROSECOND(self));
3029
3027
}
3030
3028
 
3031
3029
static PyObject *
3032
3030
time_tzinfo(PyDateTime_Time *self, void *unused)
3033
3031
{
3034
 
        PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3035
 
        Py_INCREF(result);
3036
 
        return result;
 
3032
    PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
 
3033
    Py_INCREF(result);
 
3034
    return result;
3037
3035
}
3038
3036
 
3039
3037
static PyGetSetDef time_getset[] = {
3040
 
        {"hour",        (getter)time_hour},
3041
 
        {"minute",      (getter)time_minute},
3042
 
        {"second",      (getter)py_time_second},
3043
 
        {"microsecond", (getter)time_microsecond},
3044
 
        {"tzinfo",      (getter)time_tzinfo},
3045
 
        {NULL}
 
3038
    {"hour",        (getter)time_hour},
 
3039
    {"minute",      (getter)time_minute},
 
3040
    {"second",      (getter)py_time_second},
 
3041
    {"microsecond", (getter)time_microsecond},
 
3042
    {"tzinfo",          (getter)time_tzinfo},
 
3043
    {NULL}
3046
3044
};
3047
3045
 
3048
3046
/*
3050
3048
 */
3051
3049
 
3052
3050
static char *time_kws[] = {"hour", "minute", "second", "microsecond",
3053
 
                           "tzinfo", NULL};
 
3051
                           "tzinfo", NULL};
3054
3052
 
3055
3053
static PyObject *
3056
3054
time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3057
3055
{
3058
 
        PyObject *self = NULL;
3059
 
        PyObject *state;
3060
 
        int hour = 0;
3061
 
        int minute = 0;
3062
 
        int second = 0;
3063
 
        int usecond = 0;
3064
 
        PyObject *tzinfo = Py_None;
3065
 
 
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)
3072
 
        {
3073
 
                PyDateTime_Time *me;
3074
 
                char aware;
3075
 
 
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");
3081
 
                                return NULL;
3082
 
                        }
3083
 
                }
3084
 
                aware = (char)(tzinfo != Py_None);
3085
 
                me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3086
 
                if (me != NULL) {
3087
 
                        char *pdata = PyBytes_AS_STRING(state);
3088
 
 
3089
 
                        memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3090
 
                        me->hashcode = -1;
3091
 
                        me->hastzinfo = aware;
3092
 
                        if (aware) {
3093
 
                                Py_INCREF(tzinfo);
3094
 
                                me->tzinfo = tzinfo;
3095
 
                        }
3096
 
                }
3097
 
                return (PyObject *)me;
3098
 
        }
3099
 
 
3100
 
        if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3101
 
                                        &hour, &minute, &second, &usecond,
3102
 
                                        &tzinfo)) {
3103
 
                if (check_time_args(hour, minute, second, usecond) < 0)
3104
 
                        return NULL;
3105
 
                if (check_tzinfo_subclass(tzinfo) < 0)
3106
 
                        return NULL;
3107
 
                self = new_time_ex(hour, minute, second, usecond, tzinfo,
3108
 
                                   type);
3109
 
        }
3110
 
        return self;
 
3056
    PyObject *self = NULL;
 
3057
    PyObject *state;
 
3058
    int hour = 0;
 
3059
    int minute = 0;
 
3060
    int second = 0;
 
3061
    int usecond = 0;
 
3062
    PyObject *tzinfo = Py_None;
 
3063
 
 
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)
 
3070
    {
 
3071
        PyDateTime_Time *me;
 
3072
        char aware;
 
3073
 
 
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");
 
3079
                return NULL;
 
3080
            }
 
3081
        }
 
3082
        aware = (char)(tzinfo != Py_None);
 
3083
        me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
 
3084
        if (me != NULL) {
 
3085
            char *pdata = PyBytes_AS_STRING(state);
 
3086
 
 
3087
            memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
 
3088
            me->hashcode = -1;
 
3089
            me->hastzinfo = aware;
 
3090
            if (aware) {
 
3091
                Py_INCREF(tzinfo);
 
3092
                me->tzinfo = tzinfo;
 
3093
            }
 
3094
        }
 
3095
        return (PyObject *)me;
 
3096
    }
 
3097
 
 
3098
    if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
 
3099
                                    &hour, &minute, &second, &usecond,
 
3100
                                    &tzinfo)) {
 
3101
        if (check_time_args(hour, minute, second, usecond) < 0)
 
3102
            return NULL;
 
3103
        if (check_tzinfo_subclass(tzinfo) < 0)
 
3104
            return NULL;
 
3105
        self = new_time_ex(hour, minute, second, usecond, tzinfo,
 
3106
                           type);
 
3107
    }
 
3108
    return self;
3111
3109
}
3112
3110
 
3113
3111
/*
3117
3115
static void
3118
3116
time_dealloc(PyDateTime_Time *self)
3119
3117
{
3120
 
        if (HASTZINFO(self)) {
3121
 
                Py_XDECREF(self->tzinfo);
3122
 
        }
3123
 
        Py_TYPE(self)->tp_free((PyObject *)self);
 
3118
    if (HASTZINFO(self)) {
 
3119
        Py_XDECREF(self->tzinfo);
 
3120
    }
 
3121
    Py_TYPE(self)->tp_free((PyObject *)self);
3124
3122
}
3125
3123
 
3126
3124
/*
3130
3128
/* These are all METH_NOARGS, so don't need to check the arglist. */
3131
3129
static PyObject *
3132
3130
time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
3133
 
        return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3134
 
                                   "utcoffset", Py_None);
 
3131
    return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
 
3132
                               "utcoffset", Py_None);
3135
3133
}
3136
3134
 
3137
3135
static PyObject *
3138
3136
time_dst(PyDateTime_Time *self, PyObject *unused) {
3139
 
        return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3140
 
                                   "dst", Py_None);
 
3137
    return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
 
3138
                               "dst", Py_None);
3141
3139
}
3142
3140
 
3143
3141
static PyObject *
3144
3142
time_tzname(PyDateTime_Time *self, PyObject *unused) {
3145
 
        return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3146
 
                           Py_None);
 
3143
    return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
 
3144
                       Py_None);
3147
3145
}
3148
3146
 
3149
3147
/*
3153
3151
static PyObject *
3154
3152
time_repr(PyDateTime_Time *self)
3155
3153
{
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;
3162
3160
 
3163
 
        if (us)
3164
 
                result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3165
 
                                              type_name, h, m, s, us);
3166
 
        else if (s)
3167
 
                result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3168
 
                                              type_name, h, m, s);
3169
 
        else
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);
3173
 
        return result;
 
3161
    if (us)
 
3162
        result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
 
3163
                                      type_name, h, m, s, us);
 
3164
    else if (s)
 
3165
        result = PyUnicode_FromFormat("%s(%d, %d, %d)",
 
3166
                                      type_name, h, m, s);
 
3167
    else
 
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);
 
3171
    return result;
3174
3172
}
3175
3173
 
3176
3174
static PyObject *
3177
3175
time_str(PyDateTime_Time *self)
3178
3176
{
3179
 
        return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
 
3177
    return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
3180
3178
}
3181
3179
 
3182
3180
static PyObject *
3183
3181
time_isoformat(PyDateTime_Time *self, PyObject *unused)
3184
3182
{
3185
 
        char buf[100];
3186
 
        PyObject *result;
3187
 
        int us = TIME_GET_MICROSECOND(self);;
3188
 
 
3189
 
        if (us)
3190
 
                result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d",
3191
 
                                              TIME_GET_HOUR(self),
3192
 
                                              TIME_GET_MINUTE(self),
3193
 
                                              TIME_GET_SECOND(self),
3194
 
                                              us);
3195
 
        else
3196
 
                result = PyUnicode_FromFormat("%02d:%02d:%02d",
3197
 
                                              TIME_GET_HOUR(self),
3198
 
                                              TIME_GET_MINUTE(self),
3199
 
                                              TIME_GET_SECOND(self));
3200
 
 
3201
 
        if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
3202
 
                return result;
3203
 
 
3204
 
        /* We need to append the UTC offset. */
3205
 
        if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3206
 
                             Py_None) < 0) {
3207
 
                Py_DECREF(result);
3208
 
                return NULL;
3209
 
        }
3210
 
        PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3211
 
        return result;
 
3183
    char buf[100];
 
3184
    PyObject *result;
 
3185
    int us = TIME_GET_MICROSECOND(self);;
 
3186
 
 
3187
    if (us)
 
3188
        result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d",
 
3189
                                      TIME_GET_HOUR(self),
 
3190
                                      TIME_GET_MINUTE(self),
 
3191
                                      TIME_GET_SECOND(self),
 
3192
                                      us);
 
3193
    else
 
3194
        result = PyUnicode_FromFormat("%02d:%02d:%02d",
 
3195
                                      TIME_GET_HOUR(self),
 
3196
                                      TIME_GET_MINUTE(self),
 
3197
                                      TIME_GET_SECOND(self));
 
3198
 
 
3199
    if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
 
3200
        return result;
 
3201
 
 
3202
    /* We need to append the UTC offset. */
 
3203
    if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
 
3204
                         Py_None) < 0) {
 
3205
        Py_DECREF(result);
 
3206
        return NULL;
 
3207
    }
 
3208
    PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
 
3209
    return result;
3212
3210
}
3213
3211
 
3214
3212
static PyObject *
3215
3213
time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3216
3214
{
3217
 
        PyObject *result;
3218
 
        PyObject *tuple;
3219
 
        PyObject *format;
3220
 
        static char *keywords[] = {"format", NULL};
3221
 
 
3222
 
        if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3223
 
                                          &format))
3224
 
                return NULL;
3225
 
 
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.
3229
 
         */
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 */
3236
 
        if (tuple == NULL)
3237
 
                return NULL;
3238
 
        assert(PyTuple_Size(tuple) == 9);
3239
 
        result = wrap_strftime((PyObject *)self, format, tuple,
3240
 
                               Py_None);
3241
 
        Py_DECREF(tuple);
3242
 
        return result;
 
3215
    PyObject *result;
 
3216
    PyObject *tuple;
 
3217
    PyObject *format;
 
3218
    static char *keywords[] = {"format", NULL};
 
3219
 
 
3220
    if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
 
3221
                                      &format))
 
3222
        return NULL;
 
3223
 
 
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.
 
3227
     */
 
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 */
 
3234
    if (tuple == NULL)
 
3235
        return NULL;
 
3236
    assert(PyTuple_Size(tuple) == 9);
 
3237
    result = wrap_strftime((PyObject *)self, format, tuple,
 
3238
                           Py_None);
 
3239
    Py_DECREF(tuple);
 
3240
    return result;
3243
3241
}
3244
3242
 
3245
3243
/*
3249
3247
static PyObject *
3250
3248
time_richcompare(PyObject *self, PyObject *other, int op)
3251
3249
{
3252
 
        int diff;
3253
 
        naivety n1, n2;
3254
 
        int offset1, offset2;
3255
 
 
3256
 
        if (! PyTime_Check(other)) {
3257
 
                Py_INCREF(Py_NotImplemented);
3258
 
                return Py_NotImplemented;
3259
 
        }
3260
 
        if (classify_two_utcoffsets(self, &offset1, &n1, Py_None,
3261
 
                                    other, &offset2, &n2, Py_None) < 0)
3262
 
                return NULL;
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.
3267
 
         */
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);
3273
 
        }
3274
 
 
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).
3279
 
                 */
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;
3287
 
                if (diff == 0)
3288
 
                        diff = TIME_GET_MICROSECOND(self) -
3289
 
                               TIME_GET_MICROSECOND(other);
3290
 
                return diff_to_bool(diff, op);
3291
 
        }
3292
 
 
3293
 
        assert(n1 != n2);
3294
 
        PyErr_SetString(PyExc_TypeError,
3295
 
                        "can't compare offset-naive and "
3296
 
                        "offset-aware times");
3297
 
        return NULL;
 
3250
    int diff;
 
3251
    naivety n1, n2;
 
3252
    int offset1, offset2;
 
3253
 
 
3254
    if (! PyTime_Check(other)) {
 
3255
        Py_INCREF(Py_NotImplemented);
 
3256
        return Py_NotImplemented;
 
3257
    }
 
3258
    if (classify_two_utcoffsets(self, &offset1, &n1, Py_None,
 
3259
                                other, &offset2, &n2, Py_None) < 0)
 
3260
        return NULL;
 
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.
 
3265
     */
 
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);
 
3271
    }
 
3272
 
 
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).
 
3277
         */
 
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;
 
3285
        if (diff == 0)
 
3286
            diff = TIME_GET_MICROSECOND(self) -
 
3287
                   TIME_GET_MICROSECOND(other);
 
3288
        return diff_to_bool(diff, op);
 
3289
    }
 
3290
 
 
3291
    assert(n1 != n2);
 
3292
    PyErr_SetString(PyExc_TypeError,
 
3293
                    "can't compare offset-naive and "
 
3294
                    "offset-aware times");
 
3295
    return NULL;
3298
3296
}
3299
3297
 
3300
3298
static long
3301
3299
time_hash(PyDateTime_Time *self)
3302
3300
{
3303
 
        if (self->hashcode == -1) {
3304
 
                naivety n;
3305
 
                int offset;
3306
 
                PyObject *temp;
3307
 
 
3308
 
                n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3309
 
                assert(n != OFFSET_UNKNOWN);
3310
 
                if (n == OFFSET_ERROR)
3311
 
                        return -1;
3312
 
 
3313
 
                /* Reduce this to a hash of another object. */
3314
 
                if (offset == 0) {
3315
 
                        self->hashcode = generic_hash(
3316
 
                                (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
3317
 
                        return self->hashcode;
3318
 
                }
3319
 
                else {
3320
 
                        int hour;
3321
 
                        int minute;
3322
 
 
3323
 
                        assert(n == OFFSET_AWARE);
3324
 
                        assert(HASTZINFO(self));
3325
 
                        hour = divmod(TIME_GET_HOUR(self) * 60 +
3326
 
                                        TIME_GET_MINUTE(self) - offset,
3327
 
                                      60,
3328
 
                                      &minute);
3329
 
                        if (0 <= hour && hour < 24)
3330
 
                                temp = new_time(hour, minute,
3331
 
                                                TIME_GET_SECOND(self),
3332
 
                                                TIME_GET_MICROSECOND(self),
3333
 
                                                Py_None);
3334
 
                        else
3335
 
                                temp = Py_BuildValue("iiii",
3336
 
                                           hour, minute,
3337
 
                                           TIME_GET_SECOND(self),
3338
 
                                           TIME_GET_MICROSECOND(self));
3339
 
                }
3340
 
                if (temp != NULL) {
3341
 
                        self->hashcode = PyObject_Hash(temp);
3342
 
                        Py_DECREF(temp);
3343
 
                }
3344
 
        }
3345
 
        return self->hashcode;
 
3301
    if (self->hashcode == -1) {
 
3302
        naivety n;
 
3303
        int offset;
 
3304
        PyObject *temp;
 
3305
 
 
3306
        n = classify_utcoffset((PyObject *)self, Py_None, &offset);
 
3307
        assert(n != OFFSET_UNKNOWN);
 
3308
        if (n == OFFSET_ERROR)
 
3309
            return -1;
 
3310
 
 
3311
        /* Reduce this to a hash of another object. */
 
3312
        if (offset == 0) {
 
3313
            self->hashcode = generic_hash(
 
3314
                (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
 
3315
            return self->hashcode;
 
3316
        }
 
3317
        else {
 
3318
            int hour;
 
3319
            int minute;
 
3320
 
 
3321
            assert(n == OFFSET_AWARE);
 
3322
            assert(HASTZINFO(self));
 
3323
            hour = divmod(TIME_GET_HOUR(self) * 60 +
 
3324
                            TIME_GET_MINUTE(self) - offset,
 
3325
                          60,
 
3326
                          &minute);
 
3327
            if (0 <= hour && hour < 24)
 
3328
                temp = new_time(hour, minute,
 
3329
                                TIME_GET_SECOND(self),
 
3330
                                TIME_GET_MICROSECOND(self),
 
3331
                                Py_None);
 
3332
            else
 
3333
                temp = Py_BuildValue("iiii",
 
3334
                           hour, minute,
 
3335
                           TIME_GET_SECOND(self),
 
3336
                           TIME_GET_MICROSECOND(self));
 
3337
        }
 
3338
        if (temp != NULL) {
 
3339
            self->hashcode = PyObject_Hash(temp);
 
3340
            Py_DECREF(temp);
 
3341
        }
 
3342
    }
 
3343
    return self->hashcode;
3346
3344
}
3347
3345
 
3348
3346
static PyObject *
3349
3347
time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3350
3348
{
3351
 
        PyObject *clone;
3352
 
        PyObject *tuple;
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;
 
3349
    PyObject *clone;
 
3350
    PyObject *tuple;
 
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;
3358
3356
 
3359
 
        if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3360
 
                                          time_kws,
3361
 
                                          &hh, &mm, &ss, &us, &tzinfo))
3362
 
                return NULL;
3363
 
        tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3364
 
        if (tuple == NULL)
3365
 
                return NULL;
3366
 
        clone = time_new(Py_TYPE(self), tuple, NULL);
3367
 
        Py_DECREF(tuple);
3368
 
        return clone;
 
3357
    if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
 
3358
                                      time_kws,
 
3359
                                      &hh, &mm, &ss, &us, &tzinfo))
 
3360
        return NULL;
 
3361
    tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
 
3362
    if (tuple == NULL)
 
3363
        return NULL;
 
3364
    clone = time_new(Py_TYPE(self), tuple, NULL);
 
3365
    Py_DECREF(tuple);
 
3366
    return clone;
3369
3367
}
3370
3368
 
3371
3369
static int
3372
3370
time_bool(PyDateTime_Time *self)
3373
3371
{
3374
 
        int offset;
3375
 
        int none;
 
3372
    int offset;
 
3373
    int none;
3376
3374
 
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.
3380
 
                 */
3381
 
                return 1;
3382
 
        }
3383
 
        offset = 0;
3384
 
        if (HASTZINFO(self) && self->tzinfo != Py_None) {
3385
 
                offset = call_utcoffset(self->tzinfo, Py_None, &none);
3386
 
                if (offset == -1 && PyErr_Occurred())
3387
 
                        return -1;
3388
 
        }
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.
 
3378
         */
 
3379
        return 1;
 
3380
    }
 
3381
    offset = 0;
 
3382
    if (HASTZINFO(self) && self->tzinfo != Py_None) {
 
3383
        offset = call_utcoffset(self->tzinfo, Py_None, &none);
 
3384
        if (offset == -1 && PyErr_Occurred())
 
3385
            return -1;
 
3386
    }
 
3387
    return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
3390
3388
}
3391
3389
 
3392
3390
/* Pickle support, a simple use of __reduce__. */
3399
3397
static PyObject *
3400
3398
time_getstate(PyDateTime_Time *self)
3401
3399
{
3402
 
        PyObject *basestate;
3403
 
        PyObject *result = NULL;
 
3400
    PyObject *basestate;
 
3401
    PyObject *result = NULL;
3404
3402
 
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);
3410
 
                else
3411
 
                        result = PyTuple_Pack(2, basestate, self->tzinfo);
3412
 
                Py_DECREF(basestate);
3413
 
        }
3414
 
        return result;
 
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);
 
3408
        else
 
3409
            result = PyTuple_Pack(2, basestate, self->tzinfo);
 
3410
        Py_DECREF(basestate);
 
3411
    }
 
3412
    return result;
3415
3413
}
3416
3414
 
3417
3415
static PyObject *
3418
3416
time_reduce(PyDateTime_Time *self, PyObject *arg)
3419
3417
{
3420
 
        return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
 
3418
    return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
3421
3419
}
3422
3420
 
3423
3421
static PyMethodDef time_methods[] = {
3424
3422
 
3425
 
        {"isoformat",   (PyCFunction)time_isoformat,    METH_NOARGS,
3426
 
         PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3427
 
                   "[+HH:MM].")},
3428
 
 
3429
 
        {"strftime",    (PyCFunction)time_strftime,     METH_VARARGS | METH_KEYWORDS,
3430
 
         PyDoc_STR("format -> strftime() style string.")},
3431
 
 
3432
 
        {"__format__",  (PyCFunction)date_format,       METH_VARARGS,
3433
 
         PyDoc_STR("Formats self with strftime.")},
3434
 
 
3435
 
        {"utcoffset",   (PyCFunction)time_utcoffset,    METH_NOARGS,
3436
 
         PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
3437
 
 
3438
 
        {"tzname",      (PyCFunction)time_tzname,       METH_NOARGS,
3439
 
         PyDoc_STR("Return self.tzinfo.tzname(self).")},
3440
 
 
3441
 
        {"dst",         (PyCFunction)time_dst,          METH_NOARGS,
3442
 
         PyDoc_STR("Return self.tzinfo.dst(self).")},
3443
 
 
3444
 
        {"replace",     (PyCFunction)time_replace,      METH_VARARGS | METH_KEYWORDS,
3445
 
         PyDoc_STR("Return time with new specified fields.")},
3446
 
 
3447
 
        {"__reduce__", (PyCFunction)time_reduce,        METH_NOARGS,
3448
 
         PyDoc_STR("__reduce__() -> (cls, state)")},
3449
 
 
3450
 
        {NULL,  NULL}
 
3423
    {"isoformat",   (PyCFunction)time_isoformat,        METH_NOARGS,
 
3424
     PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
 
3425
               "[+HH:MM].")},
 
3426
 
 
3427
    {"strftime",        (PyCFunction)time_strftime,     METH_VARARGS | METH_KEYWORDS,
 
3428
     PyDoc_STR("format -> strftime() style string.")},
 
3429
 
 
3430
    {"__format__",      (PyCFunction)date_format,       METH_VARARGS,
 
3431
     PyDoc_STR("Formats self with strftime.")},
 
3432
 
 
3433
    {"utcoffset",       (PyCFunction)time_utcoffset,    METH_NOARGS,
 
3434
     PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
 
3435
 
 
3436
    {"tzname",          (PyCFunction)time_tzname,       METH_NOARGS,
 
3437
     PyDoc_STR("Return self.tzinfo.tzname(self).")},
 
3438
 
 
3439
    {"dst",             (PyCFunction)time_dst,          METH_NOARGS,
 
3440
     PyDoc_STR("Return self.tzinfo.dst(self).")},
 
3441
 
 
3442
    {"replace",     (PyCFunction)time_replace,          METH_VARARGS | METH_KEYWORDS,
 
3443
     PyDoc_STR("Return time with new specified fields.")},
 
3444
 
 
3445
    {"__reduce__", (PyCFunction)time_reduce,        METH_NOARGS,
 
3446
     PyDoc_STR("__reduce__() -> (cls, state)")},
 
3447
 
 
3448
    {NULL,      NULL}
3451
3449
};
3452
3450
 
3453
3451
static char time_doc[] =
3457
3455
a tzinfo subclass. The remaining arguments may be ints or longs.\n");
3458
3456
 
3459
3457
static PyNumberMethods time_as_number = {
3460
 
        0,                                      /* nb_add */
3461
 
        0,                                      /* nb_subtract */
3462
 
        0,                                      /* nb_multiply */
3463
 
        0,                                      /* nb_remainder */
3464
 
        0,                                      /* nb_divmod */
3465
 
        0,                                      /* nb_power */
3466
 
        0,                                      /* nb_negative */
3467
 
        0,                                      /* nb_positive */
3468
 
        0,                                      /* nb_absolute */
3469
 
        (inquiry)time_bool,                     /* nb_bool */
 
3458
    0,                                          /* nb_add */
 
3459
    0,                                          /* nb_subtract */
 
3460
    0,                                          /* nb_multiply */
 
3461
    0,                                          /* nb_remainder */
 
3462
    0,                                          /* nb_divmod */
 
3463
    0,                                          /* nb_power */
 
3464
    0,                                          /* nb_negative */
 
3465
    0,                                          /* nb_positive */
 
3466
    0,                                          /* nb_absolute */
 
3467
    (inquiry)time_bool,                         /* nb_bool */
3470
3468
};
3471
3469
 
3472
3470
static PyTypeObject PyDateTime_TimeType = {
3473
 
        PyVarObject_HEAD_INIT(NULL, 0)
3474
 
        "datetime.time",                        /* tp_name */
3475
 
        sizeof(PyDateTime_Time),                /* tp_basicsize */
3476
 
        0,                                      /* tp_itemsize */
3477
 
        (destructor)time_dealloc,               /* tp_dealloc */
3478
 
        0,                                      /* tp_print */
3479
 
        0,                                      /* tp_getattr */
3480
 
        0,                                      /* tp_setattr */
3481
 
        0,                                      /* tp_reserved */
3482
 
        (reprfunc)time_repr,                    /* tp_repr */
3483
 
        &time_as_number,                        /* tp_as_number */
3484
 
        0,                                      /* tp_as_sequence */
3485
 
        0,                                      /* tp_as_mapping */
3486
 
        (hashfunc)time_hash,                    /* tp_hash */
3487
 
        0,                                      /* tp_call */
3488
 
        (reprfunc)time_str,                     /* tp_str */
3489
 
        PyObject_GenericGetAttr,                /* tp_getattro */
3490
 
        0,                                      /* tp_setattro */
3491
 
        0,                                      /* tp_as_buffer */
3492
 
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3493
 
        time_doc,                               /* tp_doc */
3494
 
        0,                                      /* tp_traverse */
3495
 
        0,                                      /* tp_clear */
3496
 
        time_richcompare,                       /* tp_richcompare */
3497
 
        0,                                      /* tp_weaklistoffset */
3498
 
        0,                                      /* tp_iter */
3499
 
        0,                                      /* tp_iternext */
3500
 
        time_methods,                           /* tp_methods */
3501
 
        0,                                      /* tp_members */
3502
 
        time_getset,                            /* tp_getset */
3503
 
        0,                                      /* tp_base */
3504
 
        0,                                      /* tp_dict */
3505
 
        0,                                      /* tp_descr_get */
3506
 
        0,                                      /* tp_descr_set */
3507
 
        0,                                      /* tp_dictoffset */
3508
 
        0,                                      /* tp_init */
3509
 
        time_alloc,                             /* tp_alloc */
3510
 
        time_new,                               /* tp_new */
3511
 
        0,                                      /* tp_free */
 
3471
    PyVarObject_HEAD_INIT(NULL, 0)
 
3472
    "datetime.time",                            /* tp_name */
 
3473
    sizeof(PyDateTime_Time),                    /* tp_basicsize */
 
3474
    0,                                          /* tp_itemsize */
 
3475
    (destructor)time_dealloc,                   /* tp_dealloc */
 
3476
    0,                                          /* tp_print */
 
3477
    0,                                          /* tp_getattr */
 
3478
    0,                                          /* tp_setattr */
 
3479
    0,                                          /* tp_reserved */
 
3480
    (reprfunc)time_repr,                        /* tp_repr */
 
3481
    &time_as_number,                            /* tp_as_number */
 
3482
    0,                                          /* tp_as_sequence */
 
3483
    0,                                          /* tp_as_mapping */
 
3484
    (hashfunc)time_hash,                        /* tp_hash */
 
3485
    0,                                          /* tp_call */
 
3486
    (reprfunc)time_str,                         /* tp_str */
 
3487
    PyObject_GenericGetAttr,                    /* tp_getattro */
 
3488
    0,                                          /* tp_setattro */
 
3489
    0,                                          /* tp_as_buffer */
 
3490
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
 
3491
    time_doc,                                   /* tp_doc */
 
3492
    0,                                          /* tp_traverse */
 
3493
    0,                                          /* tp_clear */
 
3494
    time_richcompare,                           /* tp_richcompare */
 
3495
    0,                                          /* tp_weaklistoffset */
 
3496
    0,                                          /* tp_iter */
 
3497
    0,                                          /* tp_iternext */
 
3498
    time_methods,                               /* tp_methods */
 
3499
    0,                                          /* tp_members */
 
3500
    time_getset,                                /* tp_getset */
 
3501
    0,                                          /* tp_base */
 
3502
    0,                                          /* tp_dict */
 
3503
    0,                                          /* tp_descr_get */
 
3504
    0,                                          /* tp_descr_set */
 
3505
    0,                                          /* tp_dictoffset */
 
3506
    0,                                          /* tp_init */
 
3507
    time_alloc,                                 /* tp_alloc */
 
3508
    time_new,                                   /* tp_new */
 
3509
    0,                                          /* tp_free */
3512
3510
};
3513
3511
 
3514
3512
/*
3522
3520
static PyObject *
3523
3521
datetime_hour(PyDateTime_DateTime *self, void *unused)
3524
3522
{
3525
 
        return PyLong_FromLong(DATE_GET_HOUR(self));
 
3523
    return PyLong_FromLong(DATE_GET_HOUR(self));
3526
3524
}
3527
3525
 
3528
3526
static PyObject *
3529
3527
datetime_minute(PyDateTime_DateTime *self, void *unused)
3530
3528
{
3531
 
        return PyLong_FromLong(DATE_GET_MINUTE(self));
 
3529
    return PyLong_FromLong(DATE_GET_MINUTE(self));
3532
3530
}
3533
3531
 
3534
3532
static PyObject *
3535
3533
datetime_second(PyDateTime_DateTime *self, void *unused)
3536
3534
{
3537
 
        return PyLong_FromLong(DATE_GET_SECOND(self));
 
3535
    return PyLong_FromLong(DATE_GET_SECOND(self));
3538
3536
}
3539
3537
 
3540
3538
static PyObject *
3541
3539
datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3542
3540
{
3543
 
        return PyLong_FromLong(DATE_GET_MICROSECOND(self));
 
3541
    return PyLong_FromLong(DATE_GET_MICROSECOND(self));
3544
3542
}
3545
3543
 
3546
3544
static PyObject *
3547
3545
datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3548
3546
{
3549
 
        PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3550
 
        Py_INCREF(result);
3551
 
        return result;
 
3547
    PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
 
3548
    Py_INCREF(result);
 
3549
    return result;
3552
3550
}
3553
3551
 
3554
3552
static PyGetSetDef datetime_getset[] = {
3555
 
        {"hour",        (getter)datetime_hour},
3556
 
        {"minute",      (getter)datetime_minute},
3557
 
        {"second",      (getter)datetime_second},
3558
 
        {"microsecond", (getter)datetime_microsecond},
3559
 
        {"tzinfo",      (getter)datetime_tzinfo},
3560
 
        {NULL}
 
3553
    {"hour",        (getter)datetime_hour},
 
3554
    {"minute",      (getter)datetime_minute},
 
3555
    {"second",      (getter)datetime_second},
 
3556
    {"microsecond", (getter)datetime_microsecond},
 
3557
    {"tzinfo",          (getter)datetime_tzinfo},
 
3558
    {NULL}
3561
3559
};
3562
3560
 
3563
3561
/*
3565
3563
 */
3566
3564
 
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
3570
3568
};
3571
3569
 
3572
3570
static PyObject *
3573
3571
datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3574
3572
{
3575
 
        PyObject *self = NULL;
3576
 
        PyObject *state;
3577
 
        int year;
3578
 
        int month;
3579
 
        int day;
3580
 
        int hour = 0;
3581
 
        int minute = 0;
3582
 
        int second = 0;
3583
 
        int usecond = 0;
3584
 
        PyObject *tzinfo = Py_None;
3585
 
 
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]))
3592
 
        {
3593
 
                PyDateTime_DateTime *me;
3594
 
                char aware;
3595
 
 
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");
3601
 
                                return NULL;
3602
 
                        }
3603
 
                }
3604
 
                aware = (char)(tzinfo != Py_None);
3605
 
                me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
3606
 
                if (me != NULL) {
3607
 
                        char *pdata = PyBytes_AS_STRING(state);
3608
 
 
3609
 
                        memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
3610
 
                        me->hashcode = -1;
3611
 
                        me->hastzinfo = aware;
3612
 
                        if (aware) {
3613
 
                                Py_INCREF(tzinfo);
3614
 
                                me->tzinfo = tzinfo;
3615
 
                        }
3616
 
                }
3617
 
                return (PyObject *)me;
3618
 
        }
3619
 
 
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)
3624
 
                        return NULL;
3625
 
                if (check_time_args(hour, minute, second, usecond) < 0)
3626
 
                        return NULL;
3627
 
                if (check_tzinfo_subclass(tzinfo) < 0)
3628
 
                        return NULL;
3629
 
                self = new_datetime_ex(year, month, day,
3630
 
                                        hour, minute, second, usecond,
3631
 
                                        tzinfo, type);
3632
 
        }
3633
 
        return self;
 
3573
    PyObject *self = NULL;
 
3574
    PyObject *state;
 
3575
    int year;
 
3576
    int month;
 
3577
    int day;
 
3578
    int hour = 0;
 
3579
    int minute = 0;
 
3580
    int second = 0;
 
3581
    int usecond = 0;
 
3582
    PyObject *tzinfo = Py_None;
 
3583
 
 
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]))
 
3590
    {
 
3591
        PyDateTime_DateTime *me;
 
3592
        char aware;
 
3593
 
 
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");
 
3599
                return NULL;
 
3600
            }
 
3601
        }
 
3602
        aware = (char)(tzinfo != Py_None);
 
3603
        me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
 
3604
        if (me != NULL) {
 
3605
            char *pdata = PyBytes_AS_STRING(state);
 
3606
 
 
3607
            memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
 
3608
            me->hashcode = -1;
 
3609
            me->hastzinfo = aware;
 
3610
            if (aware) {
 
3611
                Py_INCREF(tzinfo);
 
3612
                me->tzinfo = tzinfo;
 
3613
            }
 
3614
        }
 
3615
        return (PyObject *)me;
 
3616
    }
 
3617
 
 
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)
 
3622
            return NULL;
 
3623
        if (check_time_args(hour, minute, second, usecond) < 0)
 
3624
            return NULL;
 
3625
        if (check_tzinfo_subclass(tzinfo) < 0)
 
3626
            return NULL;
 
3627
        self = new_datetime_ex(year, month, day,
 
3628
                                hour, minute, second, usecond,
 
3629
                                tzinfo, type);
 
3630
    }
 
3631
    return self;
3634
3632
}
3635
3633
 
3636
3634
/* TM_FUNC is the shared type of localtime() and gmtime(). */
3642
3640
 */
3643
3641
static PyObject *
3644
3642
datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
3645
 
                           PyObject *tzinfo)
 
3643
                           PyObject *tzinfo)
3646
3644
{
3647
 
        struct tm *tm;
3648
 
        PyObject *result = NULL;
 
3645
    struct tm *tm;
 
3646
    PyObject *result = NULL;
3649
3647
 
3650
 
        tm = f(&timet);
3651
 
        if (tm) {
3652
 
                /* The platform localtime/gmtime may insert leap seconds,
3653
 
                 * indicated by tm->tm_sec > 59.  We don't care about them,
3654
 
                 * except to the extent that passing them on to the datetime
3655
 
                 * constructor would raise ValueError for a reason that
3656
 
                 * made no sense to the user.
3657
 
                 */
3658
 
                if (tm->tm_sec > 59)
3659
 
                        tm->tm_sec = 59;
3660
 
                result = PyObject_CallFunction(cls, "iiiiiiiO",
3661
 
                                               tm->tm_year + 1900,
3662
 
                                               tm->tm_mon + 1,
3663
 
                                               tm->tm_mday,
3664
 
                                               tm->tm_hour,
3665
 
                                               tm->tm_min,
3666
 
                                               tm->tm_sec,
3667
 
                                               us,
3668
 
                                               tzinfo);
3669
 
        }
3670
 
        else
3671
 
                PyErr_SetString(PyExc_ValueError,
3672
 
                                "timestamp out of range for "
3673
 
                                "platform localtime()/gmtime() function");
3674
 
        return result;
 
3648
    tm = f(&timet);
 
3649
    if (tm) {
 
3650
        /* The platform localtime/gmtime may insert leap seconds,
 
3651
         * indicated by tm->tm_sec > 59.  We don't care about them,
 
3652
         * except to the extent that passing them on to the datetime
 
3653
         * constructor would raise ValueError for a reason that
 
3654
         * made no sense to the user.
 
3655
         */
 
3656
        if (tm->tm_sec > 59)
 
3657
            tm->tm_sec = 59;
 
3658
        result = PyObject_CallFunction(cls, "iiiiiiiO",
 
3659
                                       tm->tm_year + 1900,
 
3660
                                       tm->tm_mon + 1,
 
3661
                                       tm->tm_mday,
 
3662
                                       tm->tm_hour,
 
3663
                                       tm->tm_min,
 
3664
                                       tm->tm_sec,
 
3665
                                       us,
 
3666
                                       tzinfo);
 
3667
    }
 
3668
    else
 
3669
        PyErr_SetString(PyExc_ValueError,
 
3670
                        "timestamp out of range for "
 
3671
                        "platform localtime()/gmtime() function");
 
3672
    return result;
3675
3673
}
3676
3674
 
3677
3675
/* Internal helper.
3683
3681
 */
3684
3682
static PyObject *
3685
3683
datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
3686
 
                        PyObject *tzinfo)
 
3684
                        PyObject *tzinfo)
3687
3685
{
3688
 
        time_t timet;
3689
 
        double fraction;
3690
 
        int us;
 
3686
    time_t timet;
 
3687
    double fraction;
 
3688
    int us;
3691
3689
 
3692
 
        timet = _PyTime_DoubleToTimet(timestamp);
3693
 
        if (timet == (time_t)-1 && PyErr_Occurred())
3694
 
                return NULL;
3695
 
        fraction = timestamp - (double)timet;
3696
 
        us = (int)round_to_long(fraction * 1e6);
3697
 
        if (us < 0) {
3698
 
                /* Truncation towards zero is not what we wanted
3699
 
                   for negative numbers (Python's mod semantics) */
3700
 
                timet -= 1;
3701
 
                us += 1000000;
3702
 
        }
3703
 
        /* If timestamp is less than one microsecond smaller than a
3704
 
         * full second, round up. Otherwise, ValueErrors are raised
3705
 
         * for some floats. */
3706
 
        if (us == 1000000) {
3707
 
                timet += 1;
3708
 
                us = 0;
3709
 
        }
3710
 
        return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
 
3690
    timet = _PyTime_DoubleToTimet(timestamp);
 
3691
    if (timet == (time_t)-1 && PyErr_Occurred())
 
3692
        return NULL;
 
3693
    fraction = timestamp - (double)timet;
 
3694
    us = (int)round_to_long(fraction * 1e6);
 
3695
    if (us < 0) {
 
3696
        /* Truncation towards zero is not what we wanted
 
3697
           for negative numbers (Python's mod semantics) */
 
3698
        timet -= 1;
 
3699
        us += 1000000;
 
3700
    }
 
3701
    /* If timestamp is less than one microsecond smaller than a
 
3702
     * full second, round up. Otherwise, ValueErrors are raised
 
3703
     * for some floats. */
 
3704
    if (us == 1000000) {
 
3705
        timet += 1;
 
3706
        us = 0;
 
3707
    }
 
3708
    return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
3711
3709
}
3712
3710
 
3713
3711
/* Internal helper.
3718
3716
datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
3719
3717
{
3720
3718
#ifdef HAVE_GETTIMEOFDAY
3721
 
        struct timeval t;
 
3719
    struct timeval t;
3722
3720
 
3723
3721
#ifdef GETTIMEOFDAY_NO_TZ
3724
 
        gettimeofday(&t);
 
3722
    gettimeofday(&t);
3725
3723
#else
3726
 
        gettimeofday(&t, (struct timezone *)NULL);
 
3724
    gettimeofday(&t, (struct timezone *)NULL);
3727
3725
#endif
3728
 
        return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
3729
 
                                          tzinfo);
3730
 
 
3731
 
#else   /* ! HAVE_GETTIMEOFDAY */
3732
 
        /* No flavor of gettimeofday exists on this platform.  Python's
3733
 
         * time.time() does a lot of other platform tricks to get the
3734
 
         * best time it can on the platform, and we're not going to do
3735
 
         * better than that (if we could, the better code would belong
3736
 
         * in time.time()!)  We're limited by the precision of a double,
3737
 
         * though.
3738
 
         */
3739
 
        PyObject *time;
3740
 
        double dtime;
3741
 
 
3742
 
        time = time_time();
3743
 
        if (time == NULL)
3744
 
                return NULL;
3745
 
        dtime = PyFloat_AsDouble(time);
3746
 
        Py_DECREF(time);
3747
 
        if (dtime == -1.0 && PyErr_Occurred())
3748
 
                return NULL;
3749
 
        return datetime_from_timestamp(cls, f, dtime, tzinfo);
3750
 
#endif  /* ! HAVE_GETTIMEOFDAY */
 
3726
    return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
 
3727
                                      tzinfo);
 
3728
 
 
3729
#else   /* ! HAVE_GETTIMEOFDAY */
 
3730
    /* No flavor of gettimeofday exists on this platform.  Python's
 
3731
     * time.time() does a lot of other platform tricks to get the
 
3732
     * best time it can on the platform, and we're not going to do
 
3733
     * better than that (if we could, the better code would belong
 
3734
     * in time.time()!)  We're limited by the precision of a double,
 
3735
     * though.
 
3736
     */
 
3737
    PyObject *time;
 
3738
    double dtime;
 
3739
 
 
3740
    time = time_time();
 
3741
    if (time == NULL)
 
3742
        return NULL;
 
3743
    dtime = PyFloat_AsDouble(time);
 
3744
    Py_DECREF(time);
 
3745
    if (dtime == -1.0 && PyErr_Occurred())
 
3746
        return NULL;
 
3747
    return datetime_from_timestamp(cls, f, dtime, tzinfo);
 
3748
#endif  /* ! HAVE_GETTIMEOFDAY */
3751
3749
}
3752
3750
 
3753
3751
/* Return best possible local time -- this isn't constrained by the
3756
3754
static PyObject *
3757
3755
datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
3758
3756
{
3759
 
        PyObject *self;
3760
 
        PyObject *tzinfo = Py_None;
3761
 
        static char *keywords[] = {"tz", NULL};
3762
 
 
3763
 
        if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
3764
 
                                          &tzinfo))
3765
 
                return NULL;
3766
 
        if (check_tzinfo_subclass(tzinfo) < 0)
3767
 
                return NULL;
3768
 
 
3769
 
        self = datetime_best_possible(cls,
3770
 
                                      tzinfo == Py_None ? localtime : gmtime,
3771
 
                                      tzinfo);
3772
 
        if (self != NULL && tzinfo != Py_None) {
3773
 
                /* Convert UTC to tzinfo's zone. */
3774
 
                PyObject *temp = self;
3775
 
                self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3776
 
                Py_DECREF(temp);
3777
 
        }
3778
 
        return self;
 
3757
    PyObject *self;
 
3758
    PyObject *tzinfo = Py_None;
 
3759
    static char *keywords[] = {"tz", NULL};
 
3760
 
 
3761
    if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
 
3762
                                      &tzinfo))
 
3763
        return NULL;
 
3764
    if (check_tzinfo_subclass(tzinfo) < 0)
 
3765
        return NULL;
 
3766
 
 
3767
    self = datetime_best_possible(cls,
 
3768
                                  tzinfo == Py_None ? localtime : gmtime,
 
3769
                                  tzinfo);
 
3770
    if (self != NULL && tzinfo != Py_None) {
 
3771
        /* Convert UTC to tzinfo's zone. */
 
3772
        PyObject *temp = self;
 
3773
        self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
 
3774
        Py_DECREF(temp);
 
3775
    }
 
3776
    return self;
3779
3777
}
3780
3778
 
3781
3779
/* Return best possible UTC time -- this isn't constrained by the
3784
3782
static PyObject *
3785
3783
datetime_utcnow(PyObject *cls, PyObject *dummy)
3786
3784
{
3787
 
        return datetime_best_possible(cls, gmtime, Py_None);
 
3785
    return datetime_best_possible(cls, gmtime, Py_None);
3788
3786
}
3789
3787
 
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)
3793
3791
{
3794
 
        PyObject *self;
3795
 
        double timestamp;
3796
 
        PyObject *tzinfo = Py_None;
3797
 
        static char *keywords[] = {"timestamp", "tz", NULL};
3798
 
 
3799
 
        if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3800
 
                                          keywords, &timestamp, &tzinfo))
3801
 
                return NULL;
3802
 
        if (check_tzinfo_subclass(tzinfo) < 0)
3803
 
                return NULL;
3804
 
 
3805
 
        self = datetime_from_timestamp(cls,
3806
 
                                       tzinfo == Py_None ? localtime : gmtime,
3807
 
                                       timestamp,
3808
 
                                       tzinfo);
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);
3813
 
                Py_DECREF(temp);
3814
 
        }
3815
 
        return self;
 
3792
    PyObject *self;
 
3793
    double timestamp;
 
3794
    PyObject *tzinfo = Py_None;
 
3795
    static char *keywords[] = {"timestamp", "tz", NULL};
 
3796
 
 
3797
    if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
 
3798
                                      keywords, &timestamp, &tzinfo))
 
3799
        return NULL;
 
3800
    if (check_tzinfo_subclass(tzinfo) < 0)
 
3801
        return NULL;
 
3802
 
 
3803
    self = datetime_from_timestamp(cls,
 
3804
                                   tzinfo == Py_None ? localtime : gmtime,
 
3805
                                   timestamp,
 
3806
                                   tzinfo);
 
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);
 
3811
        Py_DECREF(temp);
 
3812
    }
 
3813
    return self;
3816
3814
}
3817
3815
 
3818
3816
/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3819
3817
static PyObject *
3820
3818
datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
3821
3819
{
3822
 
        double timestamp;
3823
 
        PyObject *result = NULL;
 
3820
    double timestamp;
 
3821
    PyObject *result = NULL;
3824
3822
 
3825
 
        if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
3826
 
                result = datetime_from_timestamp(cls, gmtime, timestamp,
3827
 
                                                 Py_None);
3828
 
        return result;
 
3823
    if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
 
3824
        result = datetime_from_timestamp(cls, gmtime, timestamp,
 
3825
                                         Py_None);
 
3826
    return result;
3829
3827
}
3830
3828
 
3831
3829
/* Return new datetime from time.strptime(). */
3832
3830
static PyObject *
3833
3831
datetime_strptime(PyObject *cls, PyObject *args)
3834
3832
{
3835
 
        static PyObject *module = NULL;
3836
 
        PyObject *result = NULL, *obj, *st = NULL, *frac = NULL;
3837
 
        const Py_UNICODE *string, *format;
3838
 
 
3839
 
        if (!PyArg_ParseTuple(args, "uu:strptime", &string, &format))
3840
 
                return NULL;
3841
 
 
3842
 
        if (module == NULL &&
3843
 
            (module = PyImport_ImportModuleNoBlock("_strptime")) == NULL)
3844
 
                return NULL;
3845
 
 
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);
3850
 
        if (obj != NULL) {
3851
 
                int i, good_timetuple = 1;
3852
 
                long int ia[7];
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)
3857
 
                                good_timetuple = 0;
3858
 
                        /* copy y/m/d/h/m/s values out of the
3859
 
                           time.struct_time */
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);
3865
 
                                        if (p == NULL) {
3866
 
                                                good_timetuple = 0;
3867
 
                                                break;
3868
 
                                        }
3869
 
                                        if (PyLong_Check(p))
3870
 
                                                ia[i] = PyLong_AsLong(p);
3871
 
                                        else
3872
 
                                                good_timetuple = 0;
3873
 
                                        Py_DECREF(p);
3874
 
                                }
3875
 
/*                              if (PyLong_CheckExact(p)) {
3876
 
                                        ia[i] = PyLong_AsLongAndOverflow(p, &overflow);
3877
 
                                        if (overflow)
3878
 
                                                good_timetuple = 0;
3879
 
                                }
3880
 
                                else
3881
 
                                        good_timetuple = 0;
3882
 
                                Py_DECREF(p);
3883
 
*/                      }
3884
 
                        else
3885
 
                                good_timetuple = 0;
3886
 
                        /* follow that up with a little dose of microseconds */
3887
 
                        if (PyLong_Check(frac))
3888
 
                                ia[6] = PyLong_AsLong(frac);
3889
 
                        else
3890
 
                                good_timetuple = 0;
3891
 
                }
3892
 
                else
3893
 
                        good_timetuple = 0;
3894
 
                if (good_timetuple)
3895
 
                        result = PyObject_CallFunction(cls, "iiiiiii",
3896
 
                                                       ia[0], ia[1], ia[2],
3897
 
                                                       ia[3], ia[4], ia[5],
3898
 
                                                       ia[6]);
3899
 
                else
3900
 
                        PyErr_SetString(PyExc_ValueError,
3901
 
                                "unexpected value from _strptime._strptime");
3902
 
        }
3903
 
        Py_XDECREF(obj);
3904
 
        Py_XDECREF(st);
3905
 
        Py_XDECREF(frac);
3906
 
        return result;
 
3833
    static PyObject *module = NULL;
 
3834
    PyObject *result = NULL, *obj, *st = NULL, *frac = NULL;
 
3835
    const Py_UNICODE *string, *format;
 
3836
 
 
3837
    if (!PyArg_ParseTuple(args, "uu:strptime", &string, &format))
 
3838
        return NULL;
 
3839
 
 
3840
    if (module == NULL &&
 
3841
        (module = PyImport_ImportModuleNoBlock("_strptime")) == NULL)
 
3842
        return NULL;
 
3843
 
 
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);
 
3848
    if (obj != NULL) {
 
3849
        int i, good_timetuple = 1;
 
3850
        long int ia[7];
 
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)
 
3855
                good_timetuple = 0;
 
3856
            /* copy y/m/d/h/m/s values out of the
 
3857
               time.struct_time */
 
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);
 
3863
                    if (p == NULL) {
 
3864
                        good_timetuple = 0;
 
3865
                        break;
 
3866
                    }
 
3867
                    if (PyLong_Check(p))
 
3868
                        ia[i] = PyLong_AsLong(p);
 
3869
                    else
 
3870
                        good_timetuple = 0;
 
3871
                    Py_DECREF(p);
 
3872
                }
 
3873
/*                              if (PyLong_CheckExact(p)) {
 
3874
                                        ia[i] = PyLong_AsLongAndOverflow(p, &overflow);
 
3875
                                        if (overflow)
 
3876
                                                good_timetuple = 0;
 
3877
                                }
 
3878
                                else
 
3879
                                        good_timetuple = 0;
 
3880
                                Py_DECREF(p);
 
3881
*/                      }
 
3882
                        else
 
3883
                                good_timetuple = 0;
 
3884
                        /* follow that up with a little dose of microseconds */
 
3885
            if (PyLong_Check(frac))
 
3886
                ia[6] = PyLong_AsLong(frac);
 
3887
            else
 
3888
                good_timetuple = 0;
 
3889
        }
 
3890
        else
 
3891
            good_timetuple = 0;
 
3892
        if (good_timetuple)
 
3893
            result = PyObject_CallFunction(cls, "iiiiiii",
 
3894
                                           ia[0], ia[1], ia[2],
 
3895
                                           ia[3], ia[4], ia[5],
 
3896
                                           ia[6]);
 
3897
        else
 
3898
            PyErr_SetString(PyExc_ValueError,
 
3899
                "unexpected value from _strptime._strptime");
 
3900
    }
 
3901
    Py_XDECREF(obj);
 
3902
    Py_XDECREF(st);
 
3903
    Py_XDECREF(frac);
 
3904
    return result;
3907
3905
}
3908
3906
 
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)
3912
3910
{
3913
 
        static char *keywords[] = {"date", "time", NULL};
3914
 
        PyObject *date;
3915
 
        PyObject *time;
3916
 
        PyObject *result = NULL;
3917
 
 
3918
 
        if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
3919
 
                                        &PyDateTime_DateType, &date,
3920
 
                                        &PyDateTime_TimeType, &time)) {
3921
 
                PyObject *tzinfo = Py_None;
3922
 
 
3923
 
                if (HASTZINFO(time))
3924
 
                        tzinfo = ((PyDateTime_Time *)time)->tzinfo;
3925
 
                result = PyObject_CallFunction(cls, "iiiiiiiO",
3926
 
                                                GET_YEAR(date),
3927
 
                                                GET_MONTH(date),
3928
 
                                                GET_DAY(date),
3929
 
                                                TIME_GET_HOUR(time),
3930
 
                                                TIME_GET_MINUTE(time),
3931
 
                                                TIME_GET_SECOND(time),
3932
 
                                                TIME_GET_MICROSECOND(time),
3933
 
                                                tzinfo);
3934
 
        }
3935
 
        return result;
 
3911
    static char *keywords[] = {"date", "time", NULL};
 
3912
    PyObject *date;
 
3913
    PyObject *time;
 
3914
    PyObject *result = NULL;
 
3915
 
 
3916
    if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
 
3917
                                    &PyDateTime_DateType, &date,
 
3918
                                    &PyDateTime_TimeType, &time)) {
 
3919
        PyObject *tzinfo = Py_None;
 
3920
 
 
3921
        if (HASTZINFO(time))
 
3922
            tzinfo = ((PyDateTime_Time *)time)->tzinfo;
 
3923
        result = PyObject_CallFunction(cls, "iiiiiiiO",
 
3924
                                        GET_YEAR(date),
 
3925
                                        GET_MONTH(date),
 
3926
                                        GET_DAY(date),
 
3927
                                        TIME_GET_HOUR(time),
 
3928
                                        TIME_GET_MINUTE(time),
 
3929
                                        TIME_GET_SECOND(time),
 
3930
                                        TIME_GET_MICROSECOND(time),
 
3931
                                        tzinfo);
 
3932
    }
 
3933
    return result;
3936
3934
}
3937
3935
 
3938
3936
/*
3942
3940
static void
3943
3941
datetime_dealloc(PyDateTime_DateTime *self)
3944
3942
{
3945
 
        if (HASTZINFO(self)) {
3946
 
                Py_XDECREF(self->tzinfo);
3947
 
        }
3948
 
        Py_TYPE(self)->tp_free((PyObject *)self);
 
3943
    if (HASTZINFO(self)) {
 
3944
        Py_XDECREF(self->tzinfo);
 
3945
    }
 
3946
    Py_TYPE(self)->tp_free((PyObject *)self);
3949
3947
}
3950
3948
 
3951
3949
/*
3955
3953
/* These are all METH_NOARGS, so don't need to check the arglist. */
3956
3954
static PyObject *
3957
3955
datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
3958
 
        return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3959
 
                                   "utcoffset", (PyObject *)self);
 
3956
    return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
 
3957
                               "utcoffset", (PyObject *)self);
3960
3958
}
3961
3959
 
3962
3960
static PyObject *
3963
3961
datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
3964
 
        return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3965
 
                                   "dst", (PyObject *)self);
 
3962
    return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
 
3963
                               "dst", (PyObject *)self);
3966
3964
}
3967
3965
 
3968
3966
static PyObject *
3969
3967
datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
3970
 
        return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3971
 
                           (PyObject *)self);
 
3968
    return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
 
3969
                       (PyObject *)self);
3972
3970
}
3973
3971
 
3974
3972
/*
3980
3978
 */
3981
3979
static PyObject *
3982
3980
add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
3983
 
                       int factor)
 
3981
                       int factor)
3984
3982
{
3985
 
        /* Note that the C-level additions can't overflow, because of
3986
 
         * invariant bounds on the member values.
3987
 
         */
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.
 
3985
     */
 
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;
3996
3994
 
3997
 
        assert(factor == 1 || factor == -1);
3998
 
        if (normalize_datetime(&year, &month, &day,
3999
 
                               &hour, &minute, &second, &microsecond) < 0)
4000
 
                return NULL;
4001
 
        else
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, &microsecond) < 0)
 
3998
        return NULL;
 
3999
    else
 
4000
        return new_datetime(year, month, day,
 
4001
                            hour, minute, second, microsecond,
 
4002
                            HASTZINFO(date) ? date->tzinfo : Py_None);
4005
4003
}
4006
4004
 
4007
4005
static PyObject *
4008
4006
datetime_add(PyObject *left, PyObject *right)
4009
4007
{
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,
4017
 
                                        1);
4018
 
        }
4019
 
        else if (PyDelta_Check(left)) {
4020
 
                /* delta + datetime */
4021
 
                return add_datetime_timedelta((PyDateTime_DateTime *) right,
4022
 
                                              (PyDateTime_Delta *) left,
4023
 
                                              1);
4024
 
        }
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,
 
4015
                            1);
 
4016
    }
 
4017
    else if (PyDelta_Check(left)) {
 
4018
        /* delta + datetime */
 
4019
        return add_datetime_timedelta((PyDateTime_DateTime *) right,
 
4020
                                      (PyDateTime_Delta *) left,
 
4021
                                      1);
 
4022
    }
 
4023
    Py_INCREF(Py_NotImplemented);
 
4024
    return Py_NotImplemented;
4027
4025
}
4028
4026
 
4029
4027
static PyObject *
4030
4028
datetime_subtract(PyObject *left, PyObject *right)
4031
4029
{
4032
 
        PyObject *result = Py_NotImplemented;
4033
 
 
4034
 
        if (PyDateTime_Check(left)) {
4035
 
                /* datetime - ??? */
4036
 
                if (PyDateTime_Check(right)) {
4037
 
                        /* datetime - datetime */
4038
 
                        naivety n1, n2;
4039
 
                        int offset1, offset2;
4040
 
                        int delta_d, delta_s, delta_us;
4041
 
 
4042
 
                        if (classify_two_utcoffsets(left, &offset1, &n1, left,
4043
 
                                                    right, &offset2, &n2,
4044
 
                                                    right) < 0)
4045
 
                                return NULL;
4046
 
                        assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4047
 
                        if (n1 != n2) {
4048
 
                                PyErr_SetString(PyExc_TypeError,
4049
 
                                        "can't subtract offset-naive and "
4050
 
                                        "offset-aware datetimes");
4051
 
                                return NULL;
4052
 
                        }
4053
 
                        delta_d = ymd_to_ord(GET_YEAR(left),
4054
 
                                             GET_MONTH(left),
4055
 
                                             GET_DAY(left)) -
4056
 
                                  ymd_to_ord(GET_YEAR(right),
4057
 
                                             GET_MONTH(right),
4058
 
                                             GET_DAY(right));
4059
 
                        /* These can't overflow, since the values are
4060
 
                         * normalized.  At most this gives the number of
4061
 
                         * seconds in one day.
4062
 
                         */
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)
4073
 
                         */
4074
 
                        delta_s += (offset2 - offset1) * 60;
4075
 
                        result = new_delta(delta_d, delta_s, delta_us, 1);
4076
 
                }
4077
 
                else if (PyDelta_Check(right)) {
4078
 
                        /* datetime - delta */
4079
 
                        result = add_datetime_timedelta(
4080
 
                                        (PyDateTime_DateTime *)left,
4081
 
                                        (PyDateTime_Delta *)right,
4082
 
                                        -1);
4083
 
                }
4084
 
        }
4085
 
 
4086
 
        if (result == Py_NotImplemented)
4087
 
                Py_INCREF(result);
4088
 
        return result;
 
4030
    PyObject *result = Py_NotImplemented;
 
4031
 
 
4032
    if (PyDateTime_Check(left)) {
 
4033
        /* datetime - ??? */
 
4034
        if (PyDateTime_Check(right)) {
 
4035
            /* datetime - datetime */
 
4036
            naivety n1, n2;
 
4037
            int offset1, offset2;
 
4038
            int delta_d, delta_s, delta_us;
 
4039
 
 
4040
            if (classify_two_utcoffsets(left, &offset1, &n1, left,
 
4041
                                        right, &offset2, &n2,
 
4042
                                        right) < 0)
 
4043
                return NULL;
 
4044
            assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
 
4045
            if (n1 != n2) {
 
4046
                PyErr_SetString(PyExc_TypeError,
 
4047
                    "can't subtract offset-naive and "
 
4048
                    "offset-aware datetimes");
 
4049
                return NULL;
 
4050
            }
 
4051
            delta_d = ymd_to_ord(GET_YEAR(left),
 
4052
                                 GET_MONTH(left),
 
4053
                                 GET_DAY(left)) -
 
4054
                      ymd_to_ord(GET_YEAR(right),
 
4055
                                 GET_MONTH(right),
 
4056
                                 GET_DAY(right));
 
4057
            /* These can't overflow, since the values are
 
4058
             * normalized.  At most this gives the number of
 
4059
             * seconds in one day.
 
4060
             */
 
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)
 
4071
             */
 
4072
            delta_s += (offset2 - offset1) * 60;
 
4073
            result = new_delta(delta_d, delta_s, delta_us, 1);
 
4074
        }
 
4075
        else if (PyDelta_Check(right)) {
 
4076
            /* datetime - delta */
 
4077
            result = add_datetime_timedelta(
 
4078
                            (PyDateTime_DateTime *)left,
 
4079
                            (PyDateTime_Delta *)right,
 
4080
                            -1);
 
4081
        }
 
4082
    }
 
4083
 
 
4084
    if (result == Py_NotImplemented)
 
4085
        Py_INCREF(result);
 
4086
    return result;
4089
4087
}
4090
4088
 
4091
4089
/* Various ways to turn a datetime into a string. */
4093
4091
static PyObject *
4094
4092
datetime_repr(PyDateTime_DateTime *self)
4095
4093
{
4096
 
        const char *type_name = Py_TYPE(self)->tp_name;
4097
 
        PyObject *baserepr;
 
4094
    const char *type_name = Py_TYPE(self)->tp_name;
 
4095
    PyObject *baserepr;
4098
4096
 
4099
 
        if (DATE_GET_MICROSECOND(self)) {
4100
 
                baserepr = PyUnicode_FromFormat(
4101
 
                              "%s(%d, %d, %d, %d, %d, %d, %d)",
4102
 
                              type_name,
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));
4107
 
        }
4108
 
        else if (DATE_GET_SECOND(self)) {
4109
 
                baserepr = PyUnicode_FromFormat(
4110
 
                              "%s(%d, %d, %d, %d, %d, %d)",
4111
 
                              type_name,
4112
 
                              GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4113
 
                              DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4114
 
                              DATE_GET_SECOND(self));
4115
 
        }
4116
 
        else {
4117
 
                baserepr = PyUnicode_FromFormat(
4118
 
                              "%s(%d, %d, %d, %d, %d)",
4119
 
                              type_name,
4120
 
                              GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4121
 
                              DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4122
 
        }
4123
 
        if (baserepr == NULL || ! HASTZINFO(self))
4124
 
                return baserepr;
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)",
 
4100
                      type_name,
 
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));
 
4105
    }
 
4106
    else if (DATE_GET_SECOND(self)) {
 
4107
        baserepr = PyUnicode_FromFormat(
 
4108
                      "%s(%d, %d, %d, %d, %d, %d)",
 
4109
                      type_name,
 
4110
                      GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
 
4111
                      DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
 
4112
                      DATE_GET_SECOND(self));
 
4113
    }
 
4114
    else {
 
4115
        baserepr = PyUnicode_FromFormat(
 
4116
                      "%s(%d, %d, %d, %d, %d)",
 
4117
                      type_name,
 
4118
                      GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
 
4119
                      DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
 
4120
    }
 
4121
    if (baserepr == NULL || ! HASTZINFO(self))
 
4122
        return baserepr;
 
4123
    return append_keyword_tzinfo(baserepr, self->tzinfo);
4126
4124
}
4127
4125
 
4128
4126
static PyObject *
4129
4127
datetime_str(PyDateTime_DateTime *self)
4130
4128
{
4131
 
        return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
 
4129
    return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
4132
4130
}
4133
4131
 
4134
4132
static PyObject *
4135
4133
datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
4136
4134
{
4137
 
        int sep = 'T';
4138
 
        static char *keywords[] = {"sep", NULL};
4139
 
        char buffer[100];
4140
 
        PyObject *result;
4141
 
        int us = DATE_GET_MICROSECOND(self);
4142
 
 
4143
 
        if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
4144
 
                return NULL;
4145
 
        if (us)
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);
4151
 
        else
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));
4157
 
 
4158
 
        if (!result || !HASTZINFO(self))
4159
 
                return result;
4160
 
 
4161
 
        /* We need to append the UTC offset. */
4162
 
        if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4163
 
                             (PyObject *)self) < 0) {
4164
 
                Py_DECREF(result);
4165
 
                return NULL;
4166
 
        }
4167
 
        PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4168
 
        return result;
 
4135
    int sep = 'T';
 
4136
    static char *keywords[] = {"sep", NULL};
 
4137
    char buffer[100];
 
4138
    PyObject *result;
 
4139
    int us = DATE_GET_MICROSECOND(self);
 
4140
 
 
4141
    if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
 
4142
        return NULL;
 
4143
    if (us)
 
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);
 
4149
    else
 
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));
 
4155
 
 
4156
    if (!result || !HASTZINFO(self))
 
4157
        return result;
 
4158
 
 
4159
    /* We need to append the UTC offset. */
 
4160
    if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
 
4161
                         (PyObject *)self) < 0) {
 
4162
        Py_DECREF(result);
 
4163
        return NULL;
 
4164
    }
 
4165
    PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
 
4166
    return result;
4169
4167
}
4170
4168
 
4171
4169
static PyObject *
4172
4170
datetime_ctime(PyDateTime_DateTime *self)
4173
4171
{
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));
4178
4176
}
4179
4177
 
4180
4178
/* Miscellaneous methods. */
4182
4180
static PyObject *
4183
4181
datetime_richcompare(PyObject *self, PyObject *other, int op)
4184
4182
{
4185
 
        int diff;
4186
 
        naivety n1, n2;
4187
 
        int offset1, offset2;
4188
 
 
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. */
4198
 
                        if (op == Py_EQ)
4199
 
                                Py_RETURN_FALSE;
4200
 
                        if (op == Py_NE)
4201
 
                                Py_RETURN_TRUE;
4202
 
                        return cmperror(self, other);
4203
 
                }
4204
 
                Py_INCREF(Py_NotImplemented);
4205
 
                return Py_NotImplemented;
4206
 
        }
4207
 
 
4208
 
        if (classify_two_utcoffsets(self, &offset1, &n1, self,
4209
 
                                    other, &offset2, &n2, other) < 0)
4210
 
                return NULL;
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.
4215
 
         */
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);
4221
 
        }
4222
 
 
4223
 
        if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4224
 
                PyDateTime_Delta *delta;
4225
 
 
4226
 
                assert(offset1 != offset2);     /* else last "if" handled it */
4227
 
                delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4228
 
                                                               other);
4229
 
                if (delta == NULL)
4230
 
                        return NULL;
4231
 
                diff = GET_TD_DAYS(delta);
4232
 
                if (diff == 0)
4233
 
                        diff = GET_TD_SECONDS(delta) |
4234
 
                               GET_TD_MICROSECONDS(delta);
4235
 
                Py_DECREF(delta);
4236
 
                return diff_to_bool(diff, op);
4237
 
        }
4238
 
 
4239
 
        assert(n1 != n2);
4240
 
        PyErr_SetString(PyExc_TypeError,
4241
 
                        "can't compare offset-naive and "
4242
 
                        "offset-aware datetimes");
4243
 
        return NULL;
 
4183
    int diff;
 
4184
    naivety n1, n2;
 
4185
    int offset1, offset2;
 
4186
 
 
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. */
 
4196
            if (op == Py_EQ)
 
4197
                Py_RETURN_FALSE;
 
4198
            if (op == Py_NE)
 
4199
                Py_RETURN_TRUE;
 
4200
            return cmperror(self, other);
 
4201
        }
 
4202
        Py_INCREF(Py_NotImplemented);
 
4203
        return Py_NotImplemented;
 
4204
    }
 
4205
 
 
4206
    if (classify_two_utcoffsets(self, &offset1, &n1, self,
 
4207
                                other, &offset2, &n2, other) < 0)
 
4208
        return NULL;
 
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.
 
4213
     */
 
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);
 
4219
    }
 
4220
 
 
4221
    if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
 
4222
        PyDateTime_Delta *delta;
 
4223
 
 
4224
        assert(offset1 != offset2);             /* else last "if" handled it */
 
4225
        delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
 
4226
                                                       other);
 
4227
        if (delta == NULL)
 
4228
            return NULL;
 
4229
        diff = GET_TD_DAYS(delta);
 
4230
        if (diff == 0)
 
4231
            diff = GET_TD_SECONDS(delta) |
 
4232
                   GET_TD_MICROSECONDS(delta);
 
4233
        Py_DECREF(delta);
 
4234
        return diff_to_bool(diff, op);
 
4235
    }
 
4236
 
 
4237
    assert(n1 != n2);
 
4238
    PyErr_SetString(PyExc_TypeError,
 
4239
                    "can't compare offset-naive and "
 
4240
                    "offset-aware datetimes");
 
4241
    return NULL;
4244
4242
}
4245
4243
 
4246
4244
static long
4247
4245
datetime_hash(PyDateTime_DateTime *self)
4248
4246
{
4249
 
        if (self->hashcode == -1) {
4250
 
                naivety n;
4251
 
                int offset;
4252
 
                PyObject *temp;
4253
 
 
4254
 
                n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4255
 
                                       &offset);
4256
 
                assert(n != OFFSET_UNKNOWN);
4257
 
                if (n == OFFSET_ERROR)
4258
 
                        return -1;
4259
 
 
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;
4265
 
                }
4266
 
                else {
4267
 
                        int days;
4268
 
                        int seconds;
4269
 
 
4270
 
                        assert(n == OFFSET_AWARE);
4271
 
                        assert(HASTZINFO(self));
4272
 
                        days = ymd_to_ord(GET_YEAR(self),
4273
 
                                          GET_MONTH(self),
4274
 
                                          GET_DAY(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,
4279
 
                                         seconds,
4280
 
                                         DATE_GET_MICROSECOND(self),
4281
 
                                         1);
4282
 
                }
4283
 
                if (temp != NULL) {
4284
 
                        self->hashcode = PyObject_Hash(temp);
4285
 
                        Py_DECREF(temp);
4286
 
                }
4287
 
        }
4288
 
        return self->hashcode;
 
4247
    if (self->hashcode == -1) {
 
4248
        naivety n;
 
4249
        int offset;
 
4250
        PyObject *temp;
 
4251
 
 
4252
        n = classify_utcoffset((PyObject *)self, (PyObject *)self,
 
4253
                               &offset);
 
4254
        assert(n != OFFSET_UNKNOWN);
 
4255
        if (n == OFFSET_ERROR)
 
4256
            return -1;
 
4257
 
 
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;
 
4263
        }
 
4264
        else {
 
4265
            int days;
 
4266
            int seconds;
 
4267
 
 
4268
            assert(n == OFFSET_AWARE);
 
4269
            assert(HASTZINFO(self));
 
4270
            days = ymd_to_ord(GET_YEAR(self),
 
4271
                              GET_MONTH(self),
 
4272
                              GET_DAY(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,
 
4277
                             seconds,
 
4278
                             DATE_GET_MICROSECOND(self),
 
4279
                             1);
 
4280
        }
 
4281
        if (temp != NULL) {
 
4282
            self->hashcode = PyObject_Hash(temp);
 
4283
            Py_DECREF(temp);
 
4284
        }
 
4285
    }
 
4286
    return self->hashcode;
4289
4287
}
4290
4288
 
4291
4289
static PyObject *
4292
4290
datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
4293
4291
{
4294
 
        PyObject *clone;
4295
 
        PyObject *tuple;
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;
 
4292
    PyObject *clone;
 
4293
    PyObject *tuple;
 
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;
4304
4302
 
4305
 
        if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4306
 
                                          datetime_kws,
4307
 
                                          &y, &m, &d, &hh, &mm, &ss, &us,
4308
 
                                          &tzinfo))
4309
 
                return NULL;
4310
 
        tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4311
 
        if (tuple == NULL)
4312
 
                return NULL;
4313
 
        clone = datetime_new(Py_TYPE(self), tuple, NULL);
4314
 
        Py_DECREF(tuple);
4315
 
        return clone;
 
4303
    if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
 
4304
                                      datetime_kws,
 
4305
                                      &y, &m, &d, &hh, &mm, &ss, &us,
 
4306
                                      &tzinfo))
 
4307
        return NULL;
 
4308
    tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
 
4309
    if (tuple == NULL)
 
4310
        return NULL;
 
4311
    clone = datetime_new(Py_TYPE(self), tuple, NULL);
 
4312
    Py_DECREF(tuple);
 
4313
    return clone;
4316
4314
}
4317
4315
 
4318
4316
static PyObject *
4319
4317
datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
4320
4318
{
4321
 
        int y, m, d, hh, mm, ss, us;
4322
 
        PyObject *result;
4323
 
        int offset, none;
4324
 
 
4325
 
        PyObject *tzinfo;
4326
 
        static char *keywords[] = {"tz", NULL};
4327
 
 
4328
 
        if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4329
 
                                          &PyDateTime_TZInfoType, &tzinfo))
4330
 
                return NULL;
4331
 
 
4332
 
        if (!HASTZINFO(self) || self->tzinfo == Py_None)
4333
 
                goto NeedAware;
4334
 
 
4335
 
        /* Conversion to self's own time zone is a NOP. */
4336
 
        if (self->tzinfo == tzinfo) {
4337
 
                Py_INCREF(self);
4338
 
                return (PyObject *)self;
4339
 
        }
4340
 
 
4341
 
        /* Convert self to UTC. */
4342
 
        offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4343
 
        if (offset == -1 && PyErr_Occurred())
4344
 
                return NULL;
4345
 
        if (none)
4346
 
                goto NeedAware;
4347
 
 
4348
 
        y = GET_YEAR(self);
4349
 
        m = GET_MONTH(self);
4350
 
        d = GET_DAY(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);
4355
 
 
4356
 
        mm -= offset;
4357
 
        if ((mm < 0 || mm >= 60) &&
4358
 
            normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
4359
 
                return NULL;
4360
 
 
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;
4365
 
 
4366
 
                result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4367
 
                Py_DECREF(temp);
4368
 
        }
4369
 
        return result;
 
4319
    int y, m, d, hh, mm, ss, us;
 
4320
    PyObject *result;
 
4321
    int offset, none;
 
4322
 
 
4323
    PyObject *tzinfo;
 
4324
    static char *keywords[] = {"tz", NULL};
 
4325
 
 
4326
    if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
 
4327
                                      &PyDateTime_TZInfoType, &tzinfo))
 
4328
        return NULL;
 
4329
 
 
4330
    if (!HASTZINFO(self) || self->tzinfo == Py_None)
 
4331
        goto NeedAware;
 
4332
 
 
4333
    /* Conversion to self's own time zone is a NOP. */
 
4334
    if (self->tzinfo == tzinfo) {
 
4335
        Py_INCREF(self);
 
4336
        return (PyObject *)self;
 
4337
    }
 
4338
 
 
4339
    /* Convert self to UTC. */
 
4340
    offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
 
4341
    if (offset == -1 && PyErr_Occurred())
 
4342
        return NULL;
 
4343
    if (none)
 
4344
        goto NeedAware;
 
4345
 
 
4346
    y = GET_YEAR(self);
 
4347
    m = GET_MONTH(self);
 
4348
    d = GET_DAY(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);
 
4353
 
 
4354
    mm -= offset;
 
4355
    if ((mm < 0 || mm >= 60) &&
 
4356
        normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
 
4357
        return NULL;
 
4358
 
 
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;
 
4363
 
 
4364
        result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
 
4365
        Py_DECREF(temp);
 
4366
    }
 
4367
    return result;
4370
4368
 
4371
4369
NeedAware:
4372
 
        PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4373
 
                                          "a naive datetime");
4374
 
        return NULL;
 
4370
    PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
 
4371
                                      "a naive datetime");
 
4372
    return NULL;
4375
4373
}
4376
4374
 
4377
4375
static PyObject *
4378
4376
datetime_timetuple(PyDateTime_DateTime *self)
4379
4377
{
4380
 
        int dstflag = -1;
4381
 
 
4382
 
        if (HASTZINFO(self) && self->tzinfo != Py_None) {
4383
 
                int none;
4384
 
 
4385
 
                dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4386
 
                if (dstflag == -1 && PyErr_Occurred())
4387
 
                        return NULL;
4388
 
 
4389
 
                if (none)
4390
 
                        dstflag = -1;
4391
 
                else if (dstflag != 0)
4392
 
                        dstflag = 1;
4393
 
 
4394
 
        }
4395
 
        return build_struct_time(GET_YEAR(self),
4396
 
                                 GET_MONTH(self),
4397
 
                                 GET_DAY(self),
4398
 
                                 DATE_GET_HOUR(self),
4399
 
                                 DATE_GET_MINUTE(self),
4400
 
                                 DATE_GET_SECOND(self),
4401
 
                                 dstflag);
 
4378
    int dstflag = -1;
 
4379
 
 
4380
    if (HASTZINFO(self) && self->tzinfo != Py_None) {
 
4381
        int none;
 
4382
 
 
4383
        dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
 
4384
        if (dstflag == -1 && PyErr_Occurred())
 
4385
            return NULL;
 
4386
 
 
4387
        if (none)
 
4388
            dstflag = -1;
 
4389
        else if (dstflag != 0)
 
4390
            dstflag = 1;
 
4391
 
 
4392
    }
 
4393
    return build_struct_time(GET_YEAR(self),
 
4394
                             GET_MONTH(self),
 
4395
                             GET_DAY(self),
 
4396
                             DATE_GET_HOUR(self),
 
4397
                             DATE_GET_MINUTE(self),
 
4398
                             DATE_GET_SECOND(self),
 
4399
                             dstflag);
4402
4400
}
4403
4401
 
4404
4402
static PyObject *
4405
4403
datetime_getdate(PyDateTime_DateTime *self)
4406
4404
{
4407
 
        return new_date(GET_YEAR(self),
4408
 
                        GET_MONTH(self),
4409
 
                        GET_DAY(self));
 
4405
    return new_date(GET_YEAR(self),
 
4406
                    GET_MONTH(self),
 
4407
                    GET_DAY(self));
4410
4408
}
4411
4409
 
4412
4410
static PyObject *
4413
4411
datetime_gettime(PyDateTime_DateTime *self)
4414
4412
{
4415
 
        return new_time(DATE_GET_HOUR(self),
4416
 
                        DATE_GET_MINUTE(self),
4417
 
                        DATE_GET_SECOND(self),
4418
 
                        DATE_GET_MICROSECOND(self),
4419
 
                        Py_None);
 
4413
    return new_time(DATE_GET_HOUR(self),
 
4414
                    DATE_GET_MINUTE(self),
 
4415
                    DATE_GET_SECOND(self),
 
4416
                    DATE_GET_MICROSECOND(self),
 
4417
                    Py_None);
4420
4418
}
4421
4419
 
4422
4420
static PyObject *
4423
4421
datetime_gettimetz(PyDateTime_DateTime *self)
4424
4422
{
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);
4430
4428
}
4431
4429
 
4432
4430
static PyObject *
4433
4431
datetime_utctimetuple(PyDateTime_DateTime *self)
4434
4432
{
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 */
4442
 
        int offset = 0;
4443
 
 
4444
 
        if (HASTZINFO(self) && self->tzinfo != Py_None) {
4445
 
                int none;
4446
 
 
4447
 
                offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4448
 
                if (offset == -1 && PyErr_Occurred())
4449
 
                        return NULL;
4450
 
        }
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.
4453
 
         */
4454
 
        if (offset) {
4455
 
                /* Subtract offset minutes & normalize. */
4456
 
                int stat;
4457
 
 
4458
 
                mm -= offset;
4459
 
                stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4460
 
                if (stat < 0) {
4461
 
                        /* At the edges, it's possible we overflowed
4462
 
                         * beyond MINYEAR or MAXYEAR.
4463
 
                         */
4464
 
                        if (PyErr_ExceptionMatches(PyExc_OverflowError))
4465
 
                                PyErr_Clear();
4466
 
                        else
4467
 
                                return NULL;
4468
 
                }
4469
 
        }
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 */
 
4440
    int offset = 0;
 
4441
 
 
4442
    if (HASTZINFO(self) && self->tzinfo != Py_None) {
 
4443
        int none;
 
4444
 
 
4445
        offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
 
4446
        if (offset == -1 && PyErr_Occurred())
 
4447
            return NULL;
 
4448
    }
 
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.
 
4451
     */
 
4452
    if (offset) {
 
4453
        /* Subtract offset minutes & normalize. */
 
4454
        int stat;
 
4455
 
 
4456
        mm -= offset;
 
4457
        stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
 
4458
        if (stat < 0) {
 
4459
            /* At the edges, it's possible we overflowed
 
4460
             * beyond MINYEAR or MAXYEAR.
 
4461
             */
 
4462
            if (PyErr_ExceptionMatches(PyExc_OverflowError))
 
4463
                PyErr_Clear();
 
4464
            else
 
4465
                return NULL;
 
4466
        }
 
4467
    }
 
4468
    return build_struct_time(y, m, d, hh, mm, ss, 0);
4471
4469
}
4472
4470
 
4473
4471
/* Pickle support, a simple use of __reduce__. */
4480
4478
static PyObject *
4481
4479
datetime_getstate(PyDateTime_DateTime *self)
4482
4480
{
4483
 
        PyObject *basestate;
4484
 
        PyObject *result = NULL;
 
4481
    PyObject *basestate;
 
4482
    PyObject *result = NULL;
4485
4483
 
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);
4491
 
                else
4492
 
                        result = PyTuple_Pack(2, basestate, self->tzinfo);
4493
 
                Py_DECREF(basestate);
4494
 
        }
4495
 
        return result;
 
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);
 
4489
        else
 
4490
            result = PyTuple_Pack(2, basestate, self->tzinfo);
 
4491
        Py_DECREF(basestate);
 
4492
    }
 
4493
    return result;
4496
4494
}
4497
4495
 
4498
4496
static PyObject *
4499
4497
datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
4500
4498
{
4501
 
        return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
 
4499
    return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
4502
4500
}
4503
4501
 
4504
4502
static PyMethodDef datetime_methods[] = {
4505
4503
 
4506
 
        /* Class methods: */
4507
 
 
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.")},
4511
 
 
4512
 
        {"utcnow",         (PyCFunction)datetime_utcnow,
4513
 
         METH_NOARGS | METH_CLASS,
4514
 
         PyDoc_STR("Return a new datetime representing UTC day and time.")},
4515
 
 
4516
 
        {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4517
 
         METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4518
 
         PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
4519
 
 
4520
 
        {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4521
 
         METH_VARARGS | METH_CLASS,
4522
 
         PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4523
 
                   "(like time.time()).")},
4524
 
 
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()).")},
4529
 
 
4530
 
        {"combine", (PyCFunction)datetime_combine,
4531
 
         METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4532
 
         PyDoc_STR("date, time -> datetime with same date and time fields")},
4533
 
 
4534
 
        /* Instance methods: */
4535
 
 
4536
 
        {"date",   (PyCFunction)datetime_getdate, METH_NOARGS,
4537
 
         PyDoc_STR("Return date object with same year, month and day.")},
4538
 
 
4539
 
        {"time",   (PyCFunction)datetime_gettime, METH_NOARGS,
4540
 
         PyDoc_STR("Return time object with same time but with tzinfo=None.")},
4541
 
 
4542
 
        {"timetz",   (PyCFunction)datetime_gettimetz, METH_NOARGS,
4543
 
         PyDoc_STR("Return time object with same time and tzinfo.")},
4544
 
 
4545
 
        {"ctime",       (PyCFunction)datetime_ctime,    METH_NOARGS,
4546
 
         PyDoc_STR("Return ctime() style string.")},
4547
 
 
4548
 
        {"timetuple",   (PyCFunction)datetime_timetuple, METH_NOARGS,
4549
 
         PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4550
 
 
4551
 
        {"utctimetuple",   (PyCFunction)datetime_utctimetuple, METH_NOARGS,
4552
 
         PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
4553
 
 
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'.")},
4559
 
 
4560
 
        {"utcoffset",   (PyCFunction)datetime_utcoffset, METH_NOARGS,
4561
 
         PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4562
 
 
4563
 
        {"tzname",      (PyCFunction)datetime_tzname,   METH_NOARGS,
4564
 
         PyDoc_STR("Return self.tzinfo.tzname(self).")},
4565
 
 
4566
 
        {"dst",         (PyCFunction)datetime_dst, METH_NOARGS,
4567
 
         PyDoc_STR("Return self.tzinfo.dst(self).")},
4568
 
 
4569
 
        {"replace",     (PyCFunction)datetime_replace,  METH_VARARGS | METH_KEYWORDS,
4570
 
         PyDoc_STR("Return datetime with new specified fields.")},
4571
 
 
4572
 
        {"astimezone",  (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
4573
 
         PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
4574
 
 
4575
 
        {"__reduce__", (PyCFunction)datetime_reduce,     METH_NOARGS,
4576
 
         PyDoc_STR("__reduce__() -> (cls, state)")},
4577
 
 
4578
 
        {NULL,  NULL}
 
4504
    /* Class methods: */
 
4505
 
 
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.")},
 
4509
 
 
4510
    {"utcnow",         (PyCFunction)datetime_utcnow,
 
4511
     METH_NOARGS | METH_CLASS,
 
4512
     PyDoc_STR("Return a new datetime representing UTC day and time.")},
 
4513
 
 
4514
    {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
 
4515
     METH_VARARGS | METH_KEYWORDS | METH_CLASS,
 
4516
     PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
 
4517
 
 
4518
    {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
 
4519
     METH_VARARGS | METH_CLASS,
 
4520
     PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
 
4521
               "(like time.time()).")},
 
4522
 
 
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()).")},
 
4527
 
 
4528
    {"combine", (PyCFunction)datetime_combine,
 
4529
     METH_VARARGS | METH_KEYWORDS | METH_CLASS,
 
4530
     PyDoc_STR("date, time -> datetime with same date and time fields")},
 
4531
 
 
4532
    /* Instance methods: */
 
4533
 
 
4534
    {"date",   (PyCFunction)datetime_getdate, METH_NOARGS,
 
4535
     PyDoc_STR("Return date object with same year, month and day.")},
 
4536
 
 
4537
    {"time",   (PyCFunction)datetime_gettime, METH_NOARGS,
 
4538
     PyDoc_STR("Return time object with same time but with tzinfo=None.")},
 
4539
 
 
4540
    {"timetz",   (PyCFunction)datetime_gettimetz, METH_NOARGS,
 
4541
     PyDoc_STR("Return time object with same time and tzinfo.")},
 
4542
 
 
4543
    {"ctime",       (PyCFunction)datetime_ctime,        METH_NOARGS,
 
4544
     PyDoc_STR("Return ctime() style string.")},
 
4545
 
 
4546
    {"timetuple",   (PyCFunction)datetime_timetuple, METH_NOARGS,
 
4547
     PyDoc_STR("Return time tuple, compatible with time.localtime().")},
 
4548
 
 
4549
    {"utctimetuple",   (PyCFunction)datetime_utctimetuple, METH_NOARGS,
 
4550
     PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
 
4551
 
 
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'.")},
 
4557
 
 
4558
    {"utcoffset",       (PyCFunction)datetime_utcoffset, METH_NOARGS,
 
4559
     PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
 
4560
 
 
4561
    {"tzname",          (PyCFunction)datetime_tzname,   METH_NOARGS,
 
4562
     PyDoc_STR("Return self.tzinfo.tzname(self).")},
 
4563
 
 
4564
    {"dst",             (PyCFunction)datetime_dst, METH_NOARGS,
 
4565
     PyDoc_STR("Return self.tzinfo.dst(self).")},
 
4566
 
 
4567
    {"replace",     (PyCFunction)datetime_replace,      METH_VARARGS | METH_KEYWORDS,
 
4568
     PyDoc_STR("Return datetime with new specified fields.")},
 
4569
 
 
4570
    {"astimezone",  (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
 
4571
     PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
 
4572
 
 
4573
    {"__reduce__", (PyCFunction)datetime_reduce,     METH_NOARGS,
 
4574
     PyDoc_STR("__reduce__() -> (cls, state)")},
 
4575
 
 
4576
    {NULL,      NULL}
4579
4577
};
4580
4578
 
4581
4579
static char datetime_doc[] =
4585
4583
instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
4586
4584
 
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 */
4592
 
        0,                                      /* nb_divmod */
4593
 
        0,                                      /* nb_power */
4594
 
        0,                                      /* nb_negative */
4595
 
        0,                                      /* nb_positive */
4596
 
        0,                                      /* nb_absolute */
4597
 
        0,                                      /* nb_bool */
 
4586
    datetime_add,                               /* nb_add */
 
4587
    datetime_subtract,                          /* nb_subtract */
 
4588
    0,                                          /* nb_multiply */
 
4589
    0,                                          /* nb_remainder */
 
4590
    0,                                          /* nb_divmod */
 
4591
    0,                                          /* nb_power */
 
4592
    0,                                          /* nb_negative */
 
4593
    0,                                          /* nb_positive */
 
4594
    0,                                          /* nb_absolute */
 
4595
    0,                                          /* nb_bool */
4598
4596
};
4599
4597
 
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 */
4606
 
        0,                                      /* tp_print */
4607
 
        0,                                      /* tp_getattr */
4608
 
        0,                                      /* tp_setattr */
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 */
4615
 
        0,                                      /* tp_call */
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 */
4623
 
        0,                                      /* tp_clear */
4624
 
        datetime_richcompare,                   /* tp_richcompare */
4625
 
        0,                                      /* tp_weaklistoffset */
4626
 
        0,                                      /* tp_iter */
4627
 
        0,                                      /* tp_iternext */
4628
 
        datetime_methods,                       /* tp_methods */
4629
 
        0,                                      /* tp_members */
4630
 
        datetime_getset,                        /* tp_getset */
4631
 
        &PyDateTime_DateType,                   /* tp_base */
4632
 
        0,                                      /* tp_dict */
4633
 
        0,                                      /* tp_descr_get */
4634
 
        0,                                      /* tp_descr_set */
4635
 
        0,                                      /* tp_dictoffset */
4636
 
        0,                                      /* tp_init */
4637
 
        datetime_alloc,                         /* tp_alloc */
4638
 
        datetime_new,                           /* tp_new */
4639
 
        0,                                      /* tp_free */
 
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 */
 
4604
    0,                                          /* tp_print */
 
4605
    0,                                          /* tp_getattr */
 
4606
    0,                                          /* tp_setattr */
 
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 */
 
4613
    0,                                          /* tp_call */
 
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 */
 
4621
    0,                                          /* tp_clear */
 
4622
    datetime_richcompare,                       /* tp_richcompare */
 
4623
    0,                                          /* tp_weaklistoffset */
 
4624
    0,                                          /* tp_iter */
 
4625
    0,                                          /* tp_iternext */
 
4626
    datetime_methods,                           /* tp_methods */
 
4627
    0,                                          /* tp_members */
 
4628
    datetime_getset,                            /* tp_getset */
 
4629
    &PyDateTime_DateType,                       /* tp_base */
 
4630
    0,                                          /* tp_dict */
 
4631
    0,                                          /* tp_descr_get */
 
4632
    0,                                          /* tp_descr_set */
 
4633
    0,                                          /* tp_dictoffset */
 
4634
    0,                                          /* tp_init */
 
4635
    datetime_alloc,                             /* tp_alloc */
 
4636
    datetime_new,                               /* tp_new */
 
4637
    0,                                          /* tp_free */
4640
4638
};
4641
4639
 
4642
4640
/* ---------------------------------------------------------------------------
4644
4642
 */
4645
4643
 
4646
4644
static PyMethodDef module_methods[] = {
4647
 
        {NULL, NULL}
 
4645
    {NULL, NULL}
4648
4646
};
4649
4647
 
4650
4648
/* C API.  Clients get at this via PyDateTime_IMPORT, defined in
4651
4649
 * datetime.h.
4652
4650
 */
4653
4651
static PyDateTime_CAPI CAPI = {
4654
 
        &PyDateTime_DateType,
4655
 
        &PyDateTime_DateTimeType,
4656
 
        &PyDateTime_TimeType,
4657
 
        &PyDateTime_DeltaType,
4658
 
        &PyDateTime_TZInfoType,
4659
 
        new_date_ex,
4660
 
        new_datetime_ex,
4661
 
        new_time_ex,
4662
 
        new_delta_ex,
4663
 
        datetime_fromtimestamp,
4664
 
        date_fromtimestamp
 
4652
    &PyDateTime_DateType,
 
4653
    &PyDateTime_DateTimeType,
 
4654
    &PyDateTime_TimeType,
 
4655
    &PyDateTime_DeltaType,
 
4656
    &PyDateTime_TZInfoType,
 
4657
    new_date_ex,
 
4658
    new_datetime_ex,
 
4659
    new_time_ex,
 
4660
    new_delta_ex,
 
4661
    datetime_fromtimestamp,
 
4662
    date_fromtimestamp
4665
4663
};
4666
4664
 
4667
4665
 
4668
4666
 
4669
4667
static struct PyModuleDef datetimemodule = {
4670
 
        PyModuleDef_HEAD_INIT,
4671
 
        "datetime",
4672
 
        "Fast implementation of the datetime type.",
4673
 
        -1,
4674
 
        module_methods,
4675
 
        NULL,
4676
 
        NULL,
4677
 
        NULL,
4678
 
        NULL
 
4668
    PyModuleDef_HEAD_INIT,
 
4669
    "datetime",
 
4670
    "Fast implementation of the datetime type.",
 
4671
    -1,
 
4672
    module_methods,
 
4673
    NULL,
 
4674
    NULL,
 
4675
    NULL,
 
4676
    NULL
4679
4677
};
4680
4678
 
4681
4679
PyMODINIT_FUNC
4682
4680
PyInit_datetime(void)
4683
4681
{
4684
 
        PyObject *m;    /* a module object */
4685
 
        PyObject *d;    /* its dict */
4686
 
        PyObject *x;
4687
 
 
4688
 
        m = PyModule_Create(&datetimemodule);
4689
 
        if (m == NULL)
4690
 
                return NULL;
4691
 
 
4692
 
        if (PyType_Ready(&PyDateTime_DateType) < 0)
4693
 
                return NULL;
4694
 
        if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4695
 
                return NULL;
4696
 
        if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4697
 
                return NULL;
4698
 
        if (PyType_Ready(&PyDateTime_TimeType) < 0)
4699
 
                return NULL;
4700
 
        if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4701
 
                return NULL;
4702
 
 
4703
 
        /* timedelta values */
4704
 
        d = PyDateTime_DeltaType.tp_dict;
4705
 
 
4706
 
        x = new_delta(0, 0, 1, 0);
4707
 
        if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4708
 
                return NULL;
4709
 
        Py_DECREF(x);
4710
 
 
4711
 
        x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4712
 
        if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4713
 
                return NULL;
4714
 
        Py_DECREF(x);
4715
 
 
4716
 
        x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4717
 
        if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4718
 
                return NULL;
4719
 
        Py_DECREF(x);
4720
 
 
4721
 
        /* date values */
4722
 
        d = PyDateTime_DateType.tp_dict;
4723
 
 
4724
 
        x = new_date(1, 1, 1);
4725
 
        if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4726
 
                return NULL;
4727
 
        Py_DECREF(x);
4728
 
 
4729
 
        x = new_date(MAXYEAR, 12, 31);
4730
 
        if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4731
 
                return NULL;
4732
 
        Py_DECREF(x);
4733
 
 
4734
 
        x = new_delta(1, 0, 0, 0);
4735
 
        if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4736
 
                return NULL;
4737
 
        Py_DECREF(x);
4738
 
 
4739
 
        /* time values */
4740
 
        d = PyDateTime_TimeType.tp_dict;
4741
 
 
4742
 
        x = new_time(0, 0, 0, 0, Py_None);
4743
 
        if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4744
 
                return NULL;
4745
 
        Py_DECREF(x);
4746
 
 
4747
 
        x = new_time(23, 59, 59, 999999, Py_None);
4748
 
        if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4749
 
                return NULL;
4750
 
        Py_DECREF(x);
4751
 
 
4752
 
        x = new_delta(0, 0, 1, 0);
4753
 
        if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4754
 
                return NULL;
4755
 
        Py_DECREF(x);
4756
 
 
4757
 
        /* datetime values */
4758
 
        d = PyDateTime_DateTimeType.tp_dict;
4759
 
 
4760
 
        x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
4761
 
        if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4762
 
                return NULL;
4763
 
        Py_DECREF(x);
4764
 
 
4765
 
        x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
4766
 
        if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4767
 
                return NULL;
4768
 
        Py_DECREF(x);
4769
 
 
4770
 
        x = new_delta(0, 0, 1, 0);
4771
 
        if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4772
 
                return NULL;
4773
 
        Py_DECREF(x);
4774
 
 
4775
 
        /* module initialization */
4776
 
        PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4777
 
        PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
4778
 
 
4779
 
        Py_INCREF(&PyDateTime_DateType);
4780
 
        PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
4781
 
 
4782
 
        Py_INCREF(&PyDateTime_DateTimeType);
4783
 
        PyModule_AddObject(m, "datetime",
4784
 
                           (PyObject *)&PyDateTime_DateTimeType);
4785
 
 
4786
 
        Py_INCREF(&PyDateTime_TimeType);
4787
 
        PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
4788
 
 
4789
 
        Py_INCREF(&PyDateTime_DeltaType);
4790
 
        PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
4791
 
 
4792
 
        Py_INCREF(&PyDateTime_TZInfoType);
4793
 
        PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
 
4682
    PyObject *m;        /* a module object */
 
4683
    PyObject *d;        /* its dict */
 
4684
    PyObject *x;
 
4685
 
 
4686
    m = PyModule_Create(&datetimemodule);
 
4687
    if (m == NULL)
 
4688
        return NULL;
 
4689
 
 
4690
    if (PyType_Ready(&PyDateTime_DateType) < 0)
 
4691
        return NULL;
 
4692
    if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
 
4693
        return NULL;
 
4694
    if (PyType_Ready(&PyDateTime_DeltaType) < 0)
 
4695
        return NULL;
 
4696
    if (PyType_Ready(&PyDateTime_TimeType) < 0)
 
4697
        return NULL;
 
4698
    if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
 
4699
        return NULL;
 
4700
 
 
4701
    /* timedelta values */
 
4702
    d = PyDateTime_DeltaType.tp_dict;
 
4703
 
 
4704
    x = new_delta(0, 0, 1, 0);
 
4705
    if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
 
4706
        return NULL;
 
4707
    Py_DECREF(x);
 
4708
 
 
4709
    x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
 
4710
    if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
 
4711
        return NULL;
 
4712
    Py_DECREF(x);
 
4713
 
 
4714
    x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
 
4715
    if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
 
4716
        return NULL;
 
4717
    Py_DECREF(x);
 
4718
 
 
4719
    /* date values */
 
4720
    d = PyDateTime_DateType.tp_dict;
 
4721
 
 
4722
    x = new_date(1, 1, 1);
 
4723
    if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
 
4724
        return NULL;
 
4725
    Py_DECREF(x);
 
4726
 
 
4727
    x = new_date(MAXYEAR, 12, 31);
 
4728
    if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
 
4729
        return NULL;
 
4730
    Py_DECREF(x);
 
4731
 
 
4732
    x = new_delta(1, 0, 0, 0);
 
4733
    if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
 
4734
        return NULL;
 
4735
    Py_DECREF(x);
 
4736
 
 
4737
    /* time values */
 
4738
    d = PyDateTime_TimeType.tp_dict;
 
4739
 
 
4740
    x = new_time(0, 0, 0, 0, Py_None);
 
4741
    if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
 
4742
        return NULL;
 
4743
    Py_DECREF(x);
 
4744
 
 
4745
    x = new_time(23, 59, 59, 999999, Py_None);
 
4746
    if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
 
4747
        return NULL;
 
4748
    Py_DECREF(x);
 
4749
 
 
4750
    x = new_delta(0, 0, 1, 0);
 
4751
    if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
 
4752
        return NULL;
 
4753
    Py_DECREF(x);
 
4754
 
 
4755
    /* datetime values */
 
4756
    d = PyDateTime_DateTimeType.tp_dict;
 
4757
 
 
4758
    x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
 
4759
    if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
 
4760
        return NULL;
 
4761
    Py_DECREF(x);
 
4762
 
 
4763
    x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
 
4764
    if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
 
4765
        return NULL;
 
4766
    Py_DECREF(x);
 
4767
 
 
4768
    x = new_delta(0, 0, 1, 0);
 
4769
    if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
 
4770
        return NULL;
 
4771
    Py_DECREF(x);
 
4772
 
 
4773
    /* module initialization */
 
4774
    PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
 
4775
    PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
 
4776
 
 
4777
    Py_INCREF(&PyDateTime_DateType);
 
4778
    PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
 
4779
 
 
4780
    Py_INCREF(&PyDateTime_DateTimeType);
 
4781
    PyModule_AddObject(m, "datetime",
 
4782
                       (PyObject *)&PyDateTime_DateTimeType);
 
4783
 
 
4784
    Py_INCREF(&PyDateTime_TimeType);
 
4785
    PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
 
4786
 
 
4787
    Py_INCREF(&PyDateTime_DeltaType);
 
4788
    PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
 
4789
 
 
4790
    Py_INCREF(&PyDateTime_TZInfoType);
 
4791
    PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
4794
4792
 
4795
4793
    x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
4796
4794
    if (x == NULL)
4797
 
        return NULL;
 
4795
    return NULL;
4798
4796
    PyModule_AddObject(m, "datetime_CAPI", x);
4799
4797
 
4800
 
        /* A 4-year cycle has an extra leap day over what we'd get from
4801
 
         * pasting together 4 single years.
4802
 
         */
4803
 
        assert(DI4Y == 4 * 365 + 1);
4804
 
        assert(DI4Y == days_before_year(4+1));
4805
 
 
4806
 
        /* Similarly, a 400-year cycle has an extra leap day over what we'd
4807
 
         * get from pasting together 4 100-year cycles.
4808
 
         */
4809
 
        assert(DI400Y == 4 * DI100Y + 1);
4810
 
        assert(DI400Y == days_before_year(400+1));
4811
 
 
4812
 
        /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4813
 
         * pasting together 25 4-year cycles.
4814
 
         */
4815
 
        assert(DI100Y == 25 * DI4Y - 1);
4816
 
        assert(DI100Y == days_before_year(100+1));
4817
 
 
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)
4825
 
                return NULL;
4826
 
 
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.
4829
 
         */
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)
4834
 
                return NULL;
4835
 
        return m;
 
4798
    /* A 4-year cycle has an extra leap day over what we'd get from
 
4799
     * pasting together 4 single years.
 
4800
     */
 
4801
    assert(DI4Y == 4 * 365 + 1);
 
4802
    assert(DI4Y == days_before_year(4+1));
 
4803
 
 
4804
    /* Similarly, a 400-year cycle has an extra leap day over what we'd
 
4805
     * get from pasting together 4 100-year cycles.
 
4806
     */
 
4807
    assert(DI400Y == 4 * DI100Y + 1);
 
4808
    assert(DI400Y == days_before_year(400+1));
 
4809
 
 
4810
    /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
 
4811
     * pasting together 25 4-year cycles.
 
4812
     */
 
4813
    assert(DI100Y == 25 * DI4Y - 1);
 
4814
    assert(DI100Y == days_before_year(100+1));
 
4815
 
 
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)
 
4823
        return NULL;
 
4824
 
 
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.
 
4827
     */
 
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)
 
4832
        return NULL;
 
4833
    return m;
4836
4834
}
4837
4835
 
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
4842
 
          return None
 
4840
      return None
4843
4841
    x.d = x.dst(), and assuming that doesn't raise an exception or
4844
 
          return None
 
4842
      return None
4845
4843
    x.s = x's standard offset, x.o - x.d
4846
4844
 
4847
4845
Now some derived rules, where k is a duration (timedelta).
4963
4961
already):
4964
4962
 
4965
4963
    diff' = x.n - (z'.n - z'.o) =           replacing z'.n via [7]
4966
 
            x.n  - (z.n + diff - z'.o) =    replacing diff via [6]
4967
 
            x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
4968
 
            x.n - z.n - x.n + z.n - z.o + z'.o =    cancel x.n
4969
 
            - z.n + z.n - z.o + z'.o =              cancel z.n
4970
 
            - z.o + z'.o =                      #1 twice
4971
 
            -z.s - z.d + z'.s + z'.d =          z and z' have same tzinfo
4972
 
            z'.d - z.d
 
4964
        x.n  - (z.n + diff - z'.o) =    replacing diff via [6]
 
4965
        x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
 
4966
        x.n - z.n - x.n + z.n - z.o + z'.o =    cancel x.n
 
4967
        - z.n + z.n - z.o + z'.o =              cancel z.n
 
4968
        - z.o + z'.o =                      #1 twice
 
4969
        -z.s - z.d + z'.s + z'.d =          z and z' have same tzinfo
 
4970
        z'.d - z.d
4973
4971
 
4974
4972
So z' is UTC-equivalent to x iff z'.d = z.d at this point.  If they are equal,
4975
4973
we've found the UTC-equivalent so are done.  In fact, we stop with [7] and