xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/datetime.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
1*cda5da8dSAndroid Build Coastguard Worker"""Concrete date/time and related types.
2*cda5da8dSAndroid Build Coastguard Worker
3*cda5da8dSAndroid Build Coastguard WorkerSee http://www.iana.org/time-zones/repository/tz-link.html for
4*cda5da8dSAndroid Build Coastguard Workertime zone and DST data sources.
5*cda5da8dSAndroid Build Coastguard Worker"""
6*cda5da8dSAndroid Build Coastguard Worker
7*cda5da8dSAndroid Build Coastguard Worker__all__ = ("date", "datetime", "time", "timedelta", "timezone", "tzinfo",
8*cda5da8dSAndroid Build Coastguard Worker           "MINYEAR", "MAXYEAR", "UTC")
9*cda5da8dSAndroid Build Coastguard Worker
10*cda5da8dSAndroid Build Coastguard Worker
11*cda5da8dSAndroid Build Coastguard Workerimport time as _time
12*cda5da8dSAndroid Build Coastguard Workerimport math as _math
13*cda5da8dSAndroid Build Coastguard Workerimport sys
14*cda5da8dSAndroid Build Coastguard Workerfrom operator import index as _index
15*cda5da8dSAndroid Build Coastguard Worker
16*cda5da8dSAndroid Build Coastguard Workerdef _cmp(x, y):
17*cda5da8dSAndroid Build Coastguard Worker    return 0 if x == y else 1 if x > y else -1
18*cda5da8dSAndroid Build Coastguard Worker
19*cda5da8dSAndroid Build Coastguard WorkerMINYEAR = 1
20*cda5da8dSAndroid Build Coastguard WorkerMAXYEAR = 9999
21*cda5da8dSAndroid Build Coastguard Worker_MAXORDINAL = 3652059  # date.max.toordinal()
22*cda5da8dSAndroid Build Coastguard Worker
23*cda5da8dSAndroid Build Coastguard Worker# Utility functions, adapted from Python's Demo/classes/Dates.py, which
24*cda5da8dSAndroid Build Coastguard Worker# also assumes the current Gregorian calendar indefinitely extended in
25*cda5da8dSAndroid Build Coastguard Worker# both directions.  Difference:  Dates.py calls January 1 of year 0 day
26*cda5da8dSAndroid Build Coastguard Worker# number 1.  The code here calls January 1 of year 1 day number 1.  This is
27*cda5da8dSAndroid Build Coastguard Worker# to match the definition of the "proleptic Gregorian" calendar in Dershowitz
28*cda5da8dSAndroid Build Coastguard Worker# and Reingold's "Calendrical Calculations", where it's the base calendar
29*cda5da8dSAndroid Build Coastguard Worker# for all computations.  See the book for algorithms for converting between
30*cda5da8dSAndroid Build Coastguard Worker# proleptic Gregorian ordinals and many other calendar systems.
31*cda5da8dSAndroid Build Coastguard Worker
32*cda5da8dSAndroid Build Coastguard Worker# -1 is a placeholder for indexing purposes.
33*cda5da8dSAndroid Build Coastguard Worker_DAYS_IN_MONTH = [-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
34*cda5da8dSAndroid Build Coastguard Worker
35*cda5da8dSAndroid Build Coastguard Worker_DAYS_BEFORE_MONTH = [-1]  # -1 is a placeholder for indexing purposes.
36*cda5da8dSAndroid Build Coastguard Workerdbm = 0
37*cda5da8dSAndroid Build Coastguard Workerfor dim in _DAYS_IN_MONTH[1:]:
38*cda5da8dSAndroid Build Coastguard Worker    _DAYS_BEFORE_MONTH.append(dbm)
39*cda5da8dSAndroid Build Coastguard Worker    dbm += dim
40*cda5da8dSAndroid Build Coastguard Workerdel dbm, dim
41*cda5da8dSAndroid Build Coastguard Worker
42*cda5da8dSAndroid Build Coastguard Workerdef _is_leap(year):
43*cda5da8dSAndroid Build Coastguard Worker    "year -> 1 if leap year, else 0."
44*cda5da8dSAndroid Build Coastguard Worker    return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
45*cda5da8dSAndroid Build Coastguard Worker
46*cda5da8dSAndroid Build Coastguard Workerdef _days_before_year(year):
47*cda5da8dSAndroid Build Coastguard Worker    "year -> number of days before January 1st of year."
48*cda5da8dSAndroid Build Coastguard Worker    y = year - 1
49*cda5da8dSAndroid Build Coastguard Worker    return y*365 + y//4 - y//100 + y//400
50*cda5da8dSAndroid Build Coastguard Worker
51*cda5da8dSAndroid Build Coastguard Workerdef _days_in_month(year, month):
52*cda5da8dSAndroid Build Coastguard Worker    "year, month -> number of days in that month in that year."
53*cda5da8dSAndroid Build Coastguard Worker    assert 1 <= month <= 12, month
54*cda5da8dSAndroid Build Coastguard Worker    if month == 2 and _is_leap(year):
55*cda5da8dSAndroid Build Coastguard Worker        return 29
56*cda5da8dSAndroid Build Coastguard Worker    return _DAYS_IN_MONTH[month]
57*cda5da8dSAndroid Build Coastguard Worker
58*cda5da8dSAndroid Build Coastguard Workerdef _days_before_month(year, month):
59*cda5da8dSAndroid Build Coastguard Worker    "year, month -> number of days in year preceding first day of month."
60*cda5da8dSAndroid Build Coastguard Worker    assert 1 <= month <= 12, 'month must be in 1..12'
61*cda5da8dSAndroid Build Coastguard Worker    return _DAYS_BEFORE_MONTH[month] + (month > 2 and _is_leap(year))
62*cda5da8dSAndroid Build Coastguard Worker
63*cda5da8dSAndroid Build Coastguard Workerdef _ymd2ord(year, month, day):
64*cda5da8dSAndroid Build Coastguard Worker    "year, month, day -> ordinal, considering 01-Jan-0001 as day 1."
65*cda5da8dSAndroid Build Coastguard Worker    assert 1 <= month <= 12, 'month must be in 1..12'
66*cda5da8dSAndroid Build Coastguard Worker    dim = _days_in_month(year, month)
67*cda5da8dSAndroid Build Coastguard Worker    assert 1 <= day <= dim, ('day must be in 1..%d' % dim)
68*cda5da8dSAndroid Build Coastguard Worker    return (_days_before_year(year) +
69*cda5da8dSAndroid Build Coastguard Worker            _days_before_month(year, month) +
70*cda5da8dSAndroid Build Coastguard Worker            day)
71*cda5da8dSAndroid Build Coastguard Worker
72*cda5da8dSAndroid Build Coastguard Worker_DI400Y = _days_before_year(401)    # number of days in 400 years
73*cda5da8dSAndroid Build Coastguard Worker_DI100Y = _days_before_year(101)    #    "    "   "   " 100   "
74*cda5da8dSAndroid Build Coastguard Worker_DI4Y   = _days_before_year(5)      #    "    "   "   "   4   "
75*cda5da8dSAndroid Build Coastguard Worker
76*cda5da8dSAndroid Build Coastguard Worker# A 4-year cycle has an extra leap day over what we'd get from pasting
77*cda5da8dSAndroid Build Coastguard Worker# together 4 single years.
78*cda5da8dSAndroid Build Coastguard Workerassert _DI4Y == 4 * 365 + 1
79*cda5da8dSAndroid Build Coastguard Worker
80*cda5da8dSAndroid Build Coastguard Worker# Similarly, a 400-year cycle has an extra leap day over what we'd get from
81*cda5da8dSAndroid Build Coastguard Worker# pasting together 4 100-year cycles.
82*cda5da8dSAndroid Build Coastguard Workerassert _DI400Y == 4 * _DI100Y + 1
83*cda5da8dSAndroid Build Coastguard Worker
84*cda5da8dSAndroid Build Coastguard Worker# OTOH, a 100-year cycle has one fewer leap day than we'd get from
85*cda5da8dSAndroid Build Coastguard Worker# pasting together 25 4-year cycles.
86*cda5da8dSAndroid Build Coastguard Workerassert _DI100Y == 25 * _DI4Y - 1
87*cda5da8dSAndroid Build Coastguard Worker
88*cda5da8dSAndroid Build Coastguard Workerdef _ord2ymd(n):
89*cda5da8dSAndroid Build Coastguard Worker    "ordinal -> (year, month, day), considering 01-Jan-0001 as day 1."
90*cda5da8dSAndroid Build Coastguard Worker
91*cda5da8dSAndroid Build Coastguard Worker    # n is a 1-based index, starting at 1-Jan-1.  The pattern of leap years
92*cda5da8dSAndroid Build Coastguard Worker    # repeats exactly every 400 years.  The basic strategy is to find the
93*cda5da8dSAndroid Build Coastguard Worker    # closest 400-year boundary at or before n, then work with the offset
94*cda5da8dSAndroid Build Coastguard Worker    # from that boundary to n.  Life is much clearer if we subtract 1 from
95*cda5da8dSAndroid Build Coastguard Worker    # n first -- then the values of n at 400-year boundaries are exactly
96*cda5da8dSAndroid Build Coastguard Worker    # those divisible by _DI400Y:
97*cda5da8dSAndroid Build Coastguard Worker    #
98*cda5da8dSAndroid Build Coastguard Worker    #     D  M   Y            n              n-1
99*cda5da8dSAndroid Build Coastguard Worker    #     -- --- ----        ----------     ----------------
100*cda5da8dSAndroid Build Coastguard Worker    #     31 Dec -400        -_DI400Y       -_DI400Y -1
101*cda5da8dSAndroid Build Coastguard Worker    #      1 Jan -399         -_DI400Y +1   -_DI400Y      400-year boundary
102*cda5da8dSAndroid Build Coastguard Worker    #     ...
103*cda5da8dSAndroid Build Coastguard Worker    #     30 Dec  000        -1             -2
104*cda5da8dSAndroid Build Coastguard Worker    #     31 Dec  000         0             -1
105*cda5da8dSAndroid Build Coastguard Worker    #      1 Jan  001         1              0            400-year boundary
106*cda5da8dSAndroid Build Coastguard Worker    #      2 Jan  001         2              1
107*cda5da8dSAndroid Build Coastguard Worker    #      3 Jan  001         3              2
108*cda5da8dSAndroid Build Coastguard Worker    #     ...
109*cda5da8dSAndroid Build Coastguard Worker    #     31 Dec  400         _DI400Y        _DI400Y -1
110*cda5da8dSAndroid Build Coastguard Worker    #      1 Jan  401         _DI400Y +1     _DI400Y      400-year boundary
111*cda5da8dSAndroid Build Coastguard Worker    n -= 1
112*cda5da8dSAndroid Build Coastguard Worker    n400, n = divmod(n, _DI400Y)
113*cda5da8dSAndroid Build Coastguard Worker    year = n400 * 400 + 1   # ..., -399, 1, 401, ...
114*cda5da8dSAndroid Build Coastguard Worker
115*cda5da8dSAndroid Build Coastguard Worker    # Now n is the (non-negative) offset, in days, from January 1 of year, to
116*cda5da8dSAndroid Build Coastguard Worker    # the desired date.  Now compute how many 100-year cycles precede n.
117*cda5da8dSAndroid Build Coastguard Worker    # Note that it's possible for n100 to equal 4!  In that case 4 full
118*cda5da8dSAndroid Build Coastguard Worker    # 100-year cycles precede the desired day, which implies the desired
119*cda5da8dSAndroid Build Coastguard Worker    # day is December 31 at the end of a 400-year cycle.
120*cda5da8dSAndroid Build Coastguard Worker    n100, n = divmod(n, _DI100Y)
121*cda5da8dSAndroid Build Coastguard Worker
122*cda5da8dSAndroid Build Coastguard Worker    # Now compute how many 4-year cycles precede it.
123*cda5da8dSAndroid Build Coastguard Worker    n4, n = divmod(n, _DI4Y)
124*cda5da8dSAndroid Build Coastguard Worker
125*cda5da8dSAndroid Build Coastguard Worker    # And now how many single years.  Again n1 can be 4, and again meaning
126*cda5da8dSAndroid Build Coastguard Worker    # that the desired day is December 31 at the end of the 4-year cycle.
127*cda5da8dSAndroid Build Coastguard Worker    n1, n = divmod(n, 365)
128*cda5da8dSAndroid Build Coastguard Worker
129*cda5da8dSAndroid Build Coastguard Worker    year += n100 * 100 + n4 * 4 + n1
130*cda5da8dSAndroid Build Coastguard Worker    if n1 == 4 or n100 == 4:
131*cda5da8dSAndroid Build Coastguard Worker        assert n == 0
132*cda5da8dSAndroid Build Coastguard Worker        return year-1, 12, 31
133*cda5da8dSAndroid Build Coastguard Worker
134*cda5da8dSAndroid Build Coastguard Worker    # Now the year is correct, and n is the offset from January 1.  We find
135*cda5da8dSAndroid Build Coastguard Worker    # the month via an estimate that's either exact or one too large.
136*cda5da8dSAndroid Build Coastguard Worker    leapyear = n1 == 3 and (n4 != 24 or n100 == 3)
137*cda5da8dSAndroid Build Coastguard Worker    assert leapyear == _is_leap(year)
138*cda5da8dSAndroid Build Coastguard Worker    month = (n + 50) >> 5
139*cda5da8dSAndroid Build Coastguard Worker    preceding = _DAYS_BEFORE_MONTH[month] + (month > 2 and leapyear)
140*cda5da8dSAndroid Build Coastguard Worker    if preceding > n:  # estimate is too large
141*cda5da8dSAndroid Build Coastguard Worker        month -= 1
142*cda5da8dSAndroid Build Coastguard Worker        preceding -= _DAYS_IN_MONTH[month] + (month == 2 and leapyear)
143*cda5da8dSAndroid Build Coastguard Worker    n -= preceding
144*cda5da8dSAndroid Build Coastguard Worker    assert 0 <= n < _days_in_month(year, month)
145*cda5da8dSAndroid Build Coastguard Worker
146*cda5da8dSAndroid Build Coastguard Worker    # Now the year and month are correct, and n is the offset from the
147*cda5da8dSAndroid Build Coastguard Worker    # start of that month:  we're done!
148*cda5da8dSAndroid Build Coastguard Worker    return year, month, n+1
149*cda5da8dSAndroid Build Coastguard Worker
150*cda5da8dSAndroid Build Coastguard Worker# Month and day names.  For localized versions, see the calendar module.
151*cda5da8dSAndroid Build Coastguard Worker_MONTHNAMES = [None, "Jan", "Feb", "Mar", "Apr", "May", "Jun",
152*cda5da8dSAndroid Build Coastguard Worker                     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
153*cda5da8dSAndroid Build Coastguard Worker_DAYNAMES = [None, "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
154*cda5da8dSAndroid Build Coastguard Worker
155*cda5da8dSAndroid Build Coastguard Worker
156*cda5da8dSAndroid Build Coastguard Workerdef _build_struct_time(y, m, d, hh, mm, ss, dstflag):
157*cda5da8dSAndroid Build Coastguard Worker    wday = (_ymd2ord(y, m, d) + 6) % 7
158*cda5da8dSAndroid Build Coastguard Worker    dnum = _days_before_month(y, m) + d
159*cda5da8dSAndroid Build Coastguard Worker    return _time.struct_time((y, m, d, hh, mm, ss, wday, dnum, dstflag))
160*cda5da8dSAndroid Build Coastguard Worker
161*cda5da8dSAndroid Build Coastguard Workerdef _format_time(hh, mm, ss, us, timespec='auto'):
162*cda5da8dSAndroid Build Coastguard Worker    specs = {
163*cda5da8dSAndroid Build Coastguard Worker        'hours': '{:02d}',
164*cda5da8dSAndroid Build Coastguard Worker        'minutes': '{:02d}:{:02d}',
165*cda5da8dSAndroid Build Coastguard Worker        'seconds': '{:02d}:{:02d}:{:02d}',
166*cda5da8dSAndroid Build Coastguard Worker        'milliseconds': '{:02d}:{:02d}:{:02d}.{:03d}',
167*cda5da8dSAndroid Build Coastguard Worker        'microseconds': '{:02d}:{:02d}:{:02d}.{:06d}'
168*cda5da8dSAndroid Build Coastguard Worker    }
169*cda5da8dSAndroid Build Coastguard Worker
170*cda5da8dSAndroid Build Coastguard Worker    if timespec == 'auto':
171*cda5da8dSAndroid Build Coastguard Worker        # Skip trailing microseconds when us==0.
172*cda5da8dSAndroid Build Coastguard Worker        timespec = 'microseconds' if us else 'seconds'
173*cda5da8dSAndroid Build Coastguard Worker    elif timespec == 'milliseconds':
174*cda5da8dSAndroid Build Coastguard Worker        us //= 1000
175*cda5da8dSAndroid Build Coastguard Worker    try:
176*cda5da8dSAndroid Build Coastguard Worker        fmt = specs[timespec]
177*cda5da8dSAndroid Build Coastguard Worker    except KeyError:
178*cda5da8dSAndroid Build Coastguard Worker        raise ValueError('Unknown timespec value')
179*cda5da8dSAndroid Build Coastguard Worker    else:
180*cda5da8dSAndroid Build Coastguard Worker        return fmt.format(hh, mm, ss, us)
181*cda5da8dSAndroid Build Coastguard Worker
182*cda5da8dSAndroid Build Coastguard Workerdef _format_offset(off):
183*cda5da8dSAndroid Build Coastguard Worker    s = ''
184*cda5da8dSAndroid Build Coastguard Worker    if off is not None:
185*cda5da8dSAndroid Build Coastguard Worker        if off.days < 0:
186*cda5da8dSAndroid Build Coastguard Worker            sign = "-"
187*cda5da8dSAndroid Build Coastguard Worker            off = -off
188*cda5da8dSAndroid Build Coastguard Worker        else:
189*cda5da8dSAndroid Build Coastguard Worker            sign = "+"
190*cda5da8dSAndroid Build Coastguard Worker        hh, mm = divmod(off, timedelta(hours=1))
191*cda5da8dSAndroid Build Coastguard Worker        mm, ss = divmod(mm, timedelta(minutes=1))
192*cda5da8dSAndroid Build Coastguard Worker        s += "%s%02d:%02d" % (sign, hh, mm)
193*cda5da8dSAndroid Build Coastguard Worker        if ss or ss.microseconds:
194*cda5da8dSAndroid Build Coastguard Worker            s += ":%02d" % ss.seconds
195*cda5da8dSAndroid Build Coastguard Worker
196*cda5da8dSAndroid Build Coastguard Worker            if ss.microseconds:
197*cda5da8dSAndroid Build Coastguard Worker                s += '.%06d' % ss.microseconds
198*cda5da8dSAndroid Build Coastguard Worker    return s
199*cda5da8dSAndroid Build Coastguard Worker
200*cda5da8dSAndroid Build Coastguard Worker# Correctly substitute for %z and %Z escapes in strftime formats.
201*cda5da8dSAndroid Build Coastguard Workerdef _wrap_strftime(object, format, timetuple):
202*cda5da8dSAndroid Build Coastguard Worker    # Don't call utcoffset() or tzname() unless actually needed.
203*cda5da8dSAndroid Build Coastguard Worker    freplace = None  # the string to use for %f
204*cda5da8dSAndroid Build Coastguard Worker    zreplace = None  # the string to use for %z
205*cda5da8dSAndroid Build Coastguard Worker    Zreplace = None  # the string to use for %Z
206*cda5da8dSAndroid Build Coastguard Worker
207*cda5da8dSAndroid Build Coastguard Worker    # Scan format for %z and %Z escapes, replacing as needed.
208*cda5da8dSAndroid Build Coastguard Worker    newformat = []
209*cda5da8dSAndroid Build Coastguard Worker    push = newformat.append
210*cda5da8dSAndroid Build Coastguard Worker    i, n = 0, len(format)
211*cda5da8dSAndroid Build Coastguard Worker    while i < n:
212*cda5da8dSAndroid Build Coastguard Worker        ch = format[i]
213*cda5da8dSAndroid Build Coastguard Worker        i += 1
214*cda5da8dSAndroid Build Coastguard Worker        if ch == '%':
215*cda5da8dSAndroid Build Coastguard Worker            if i < n:
216*cda5da8dSAndroid Build Coastguard Worker                ch = format[i]
217*cda5da8dSAndroid Build Coastguard Worker                i += 1
218*cda5da8dSAndroid Build Coastguard Worker                if ch == 'f':
219*cda5da8dSAndroid Build Coastguard Worker                    if freplace is None:
220*cda5da8dSAndroid Build Coastguard Worker                        freplace = '%06d' % getattr(object,
221*cda5da8dSAndroid Build Coastguard Worker                                                    'microsecond', 0)
222*cda5da8dSAndroid Build Coastguard Worker                    newformat.append(freplace)
223*cda5da8dSAndroid Build Coastguard Worker                elif ch == 'z':
224*cda5da8dSAndroid Build Coastguard Worker                    if zreplace is None:
225*cda5da8dSAndroid Build Coastguard Worker                        zreplace = ""
226*cda5da8dSAndroid Build Coastguard Worker                        if hasattr(object, "utcoffset"):
227*cda5da8dSAndroid Build Coastguard Worker                            offset = object.utcoffset()
228*cda5da8dSAndroid Build Coastguard Worker                            if offset is not None:
229*cda5da8dSAndroid Build Coastguard Worker                                sign = '+'
230*cda5da8dSAndroid Build Coastguard Worker                                if offset.days < 0:
231*cda5da8dSAndroid Build Coastguard Worker                                    offset = -offset
232*cda5da8dSAndroid Build Coastguard Worker                                    sign = '-'
233*cda5da8dSAndroid Build Coastguard Worker                                h, rest = divmod(offset, timedelta(hours=1))
234*cda5da8dSAndroid Build Coastguard Worker                                m, rest = divmod(rest, timedelta(minutes=1))
235*cda5da8dSAndroid Build Coastguard Worker                                s = rest.seconds
236*cda5da8dSAndroid Build Coastguard Worker                                u = offset.microseconds
237*cda5da8dSAndroid Build Coastguard Worker                                if u:
238*cda5da8dSAndroid Build Coastguard Worker                                    zreplace = '%c%02d%02d%02d.%06d' % (sign, h, m, s, u)
239*cda5da8dSAndroid Build Coastguard Worker                                elif s:
240*cda5da8dSAndroid Build Coastguard Worker                                    zreplace = '%c%02d%02d%02d' % (sign, h, m, s)
241*cda5da8dSAndroid Build Coastguard Worker                                else:
242*cda5da8dSAndroid Build Coastguard Worker                                    zreplace = '%c%02d%02d' % (sign, h, m)
243*cda5da8dSAndroid Build Coastguard Worker                    assert '%' not in zreplace
244*cda5da8dSAndroid Build Coastguard Worker                    newformat.append(zreplace)
245*cda5da8dSAndroid Build Coastguard Worker                elif ch == 'Z':
246*cda5da8dSAndroid Build Coastguard Worker                    if Zreplace is None:
247*cda5da8dSAndroid Build Coastguard Worker                        Zreplace = ""
248*cda5da8dSAndroid Build Coastguard Worker                        if hasattr(object, "tzname"):
249*cda5da8dSAndroid Build Coastguard Worker                            s = object.tzname()
250*cda5da8dSAndroid Build Coastguard Worker                            if s is not None:
251*cda5da8dSAndroid Build Coastguard Worker                                # strftime is going to have at this: escape %
252*cda5da8dSAndroid Build Coastguard Worker                                Zreplace = s.replace('%', '%%')
253*cda5da8dSAndroid Build Coastguard Worker                    newformat.append(Zreplace)
254*cda5da8dSAndroid Build Coastguard Worker                else:
255*cda5da8dSAndroid Build Coastguard Worker                    push('%')
256*cda5da8dSAndroid Build Coastguard Worker                    push(ch)
257*cda5da8dSAndroid Build Coastguard Worker            else:
258*cda5da8dSAndroid Build Coastguard Worker                push('%')
259*cda5da8dSAndroid Build Coastguard Worker        else:
260*cda5da8dSAndroid Build Coastguard Worker            push(ch)
261*cda5da8dSAndroid Build Coastguard Worker    newformat = "".join(newformat)
262*cda5da8dSAndroid Build Coastguard Worker    return _time.strftime(newformat, timetuple)
263*cda5da8dSAndroid Build Coastguard Worker
264*cda5da8dSAndroid Build Coastguard Worker# Helpers for parsing the result of isoformat()
265*cda5da8dSAndroid Build Coastguard Workerdef _is_ascii_digit(c):
266*cda5da8dSAndroid Build Coastguard Worker    return c in "0123456789"
267*cda5da8dSAndroid Build Coastguard Worker
268*cda5da8dSAndroid Build Coastguard Workerdef _find_isoformat_datetime_separator(dtstr):
269*cda5da8dSAndroid Build Coastguard Worker    # See the comment in _datetimemodule.c:_find_isoformat_datetime_separator
270*cda5da8dSAndroid Build Coastguard Worker    len_dtstr = len(dtstr)
271*cda5da8dSAndroid Build Coastguard Worker    if len_dtstr == 7:
272*cda5da8dSAndroid Build Coastguard Worker        return 7
273*cda5da8dSAndroid Build Coastguard Worker
274*cda5da8dSAndroid Build Coastguard Worker    assert len_dtstr > 7
275*cda5da8dSAndroid Build Coastguard Worker    date_separator = "-"
276*cda5da8dSAndroid Build Coastguard Worker    week_indicator = "W"
277*cda5da8dSAndroid Build Coastguard Worker
278*cda5da8dSAndroid Build Coastguard Worker    if dtstr[4] == date_separator:
279*cda5da8dSAndroid Build Coastguard Worker        if dtstr[5] == week_indicator:
280*cda5da8dSAndroid Build Coastguard Worker            if len_dtstr < 8:
281*cda5da8dSAndroid Build Coastguard Worker                raise ValueError("Invalid ISO string")
282*cda5da8dSAndroid Build Coastguard Worker            if len_dtstr > 8 and dtstr[8] == date_separator:
283*cda5da8dSAndroid Build Coastguard Worker                if len_dtstr == 9:
284*cda5da8dSAndroid Build Coastguard Worker                    raise ValueError("Invalid ISO string")
285*cda5da8dSAndroid Build Coastguard Worker                if len_dtstr > 10 and _is_ascii_digit(dtstr[10]):
286*cda5da8dSAndroid Build Coastguard Worker                    # This is as far as we need to resolve the ambiguity for
287*cda5da8dSAndroid Build Coastguard Worker                    # the moment - if we have YYYY-Www-##, the separator is
288*cda5da8dSAndroid Build Coastguard Worker                    # either a hyphen at 8 or a number at 10.
289*cda5da8dSAndroid Build Coastguard Worker                    #
290*cda5da8dSAndroid Build Coastguard Worker                    # We'll assume it's a hyphen at 8 because it's way more
291*cda5da8dSAndroid Build Coastguard Worker                    # likely that someone will use a hyphen as a separator than
292*cda5da8dSAndroid Build Coastguard Worker                    # a number, but at this point it's really best effort
293*cda5da8dSAndroid Build Coastguard Worker                    # because this is an extension of the spec anyway.
294*cda5da8dSAndroid Build Coastguard Worker                    # TODO(pganssle): Document this
295*cda5da8dSAndroid Build Coastguard Worker                    return 8
296*cda5da8dSAndroid Build Coastguard Worker                return 10
297*cda5da8dSAndroid Build Coastguard Worker            else:
298*cda5da8dSAndroid Build Coastguard Worker                # YYYY-Www (8)
299*cda5da8dSAndroid Build Coastguard Worker                return 8
300*cda5da8dSAndroid Build Coastguard Worker        else:
301*cda5da8dSAndroid Build Coastguard Worker            # YYYY-MM-DD (10)
302*cda5da8dSAndroid Build Coastguard Worker            return 10
303*cda5da8dSAndroid Build Coastguard Worker    else:
304*cda5da8dSAndroid Build Coastguard Worker        if dtstr[4] == week_indicator:
305*cda5da8dSAndroid Build Coastguard Worker            # YYYYWww (7) or YYYYWwwd (8)
306*cda5da8dSAndroid Build Coastguard Worker            idx = 7
307*cda5da8dSAndroid Build Coastguard Worker            while idx < len_dtstr:
308*cda5da8dSAndroid Build Coastguard Worker                if not _is_ascii_digit(dtstr[idx]):
309*cda5da8dSAndroid Build Coastguard Worker                    break
310*cda5da8dSAndroid Build Coastguard Worker                idx += 1
311*cda5da8dSAndroid Build Coastguard Worker
312*cda5da8dSAndroid Build Coastguard Worker            if idx < 9:
313*cda5da8dSAndroid Build Coastguard Worker                return idx
314*cda5da8dSAndroid Build Coastguard Worker
315*cda5da8dSAndroid Build Coastguard Worker            if idx % 2 == 0:
316*cda5da8dSAndroid Build Coastguard Worker                # If the index of the last number is even, it's YYYYWwwd
317*cda5da8dSAndroid Build Coastguard Worker                return 7
318*cda5da8dSAndroid Build Coastguard Worker            else:
319*cda5da8dSAndroid Build Coastguard Worker                return 8
320*cda5da8dSAndroid Build Coastguard Worker        else:
321*cda5da8dSAndroid Build Coastguard Worker            # YYYYMMDD (8)
322*cda5da8dSAndroid Build Coastguard Worker            return 8
323*cda5da8dSAndroid Build Coastguard Worker
324*cda5da8dSAndroid Build Coastguard Worker
325*cda5da8dSAndroid Build Coastguard Workerdef _parse_isoformat_date(dtstr):
326*cda5da8dSAndroid Build Coastguard Worker    # It is assumed that this is an ASCII-only string of lengths 7, 8 or 10,
327*cda5da8dSAndroid Build Coastguard Worker    # see the comment on Modules/_datetimemodule.c:_find_isoformat_datetime_separator
328*cda5da8dSAndroid Build Coastguard Worker    assert len(dtstr) in (7, 8, 10)
329*cda5da8dSAndroid Build Coastguard Worker    year = int(dtstr[0:4])
330*cda5da8dSAndroid Build Coastguard Worker    has_sep = dtstr[4] == '-'
331*cda5da8dSAndroid Build Coastguard Worker
332*cda5da8dSAndroid Build Coastguard Worker    pos = 4 + has_sep
333*cda5da8dSAndroid Build Coastguard Worker    if dtstr[pos:pos + 1] == "W":
334*cda5da8dSAndroid Build Coastguard Worker        # YYYY-?Www-?D?
335*cda5da8dSAndroid Build Coastguard Worker        pos += 1
336*cda5da8dSAndroid Build Coastguard Worker        weekno = int(dtstr[pos:pos + 2])
337*cda5da8dSAndroid Build Coastguard Worker        pos += 2
338*cda5da8dSAndroid Build Coastguard Worker
339*cda5da8dSAndroid Build Coastguard Worker        dayno = 1
340*cda5da8dSAndroid Build Coastguard Worker        if len(dtstr) > pos:
341*cda5da8dSAndroid Build Coastguard Worker            if (dtstr[pos:pos + 1] == '-') != has_sep:
342*cda5da8dSAndroid Build Coastguard Worker                raise ValueError("Inconsistent use of dash separator")
343*cda5da8dSAndroid Build Coastguard Worker
344*cda5da8dSAndroid Build Coastguard Worker            pos += has_sep
345*cda5da8dSAndroid Build Coastguard Worker
346*cda5da8dSAndroid Build Coastguard Worker            dayno = int(dtstr[pos:pos + 1])
347*cda5da8dSAndroid Build Coastguard Worker
348*cda5da8dSAndroid Build Coastguard Worker        return list(_isoweek_to_gregorian(year, weekno, dayno))
349*cda5da8dSAndroid Build Coastguard Worker    else:
350*cda5da8dSAndroid Build Coastguard Worker        month = int(dtstr[pos:pos + 2])
351*cda5da8dSAndroid Build Coastguard Worker        pos += 2
352*cda5da8dSAndroid Build Coastguard Worker        if (dtstr[pos:pos + 1] == "-") != has_sep:
353*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("Inconsistent use of dash separator")
354*cda5da8dSAndroid Build Coastguard Worker
355*cda5da8dSAndroid Build Coastguard Worker        pos += has_sep
356*cda5da8dSAndroid Build Coastguard Worker        day = int(dtstr[pos:pos + 2])
357*cda5da8dSAndroid Build Coastguard Worker
358*cda5da8dSAndroid Build Coastguard Worker        return [year, month, day]
359*cda5da8dSAndroid Build Coastguard Worker
360*cda5da8dSAndroid Build Coastguard Worker
361*cda5da8dSAndroid Build Coastguard Worker_FRACTION_CORRECTION = [100000, 10000, 1000, 100, 10]
362*cda5da8dSAndroid Build Coastguard Worker
363*cda5da8dSAndroid Build Coastguard Worker
364*cda5da8dSAndroid Build Coastguard Workerdef _parse_hh_mm_ss_ff(tstr):
365*cda5da8dSAndroid Build Coastguard Worker    # Parses things of the form HH[:?MM[:?SS[{.,}fff[fff]]]]
366*cda5da8dSAndroid Build Coastguard Worker    len_str = len(tstr)
367*cda5da8dSAndroid Build Coastguard Worker
368*cda5da8dSAndroid Build Coastguard Worker    time_comps = [0, 0, 0, 0]
369*cda5da8dSAndroid Build Coastguard Worker    pos = 0
370*cda5da8dSAndroid Build Coastguard Worker    for comp in range(0, 3):
371*cda5da8dSAndroid Build Coastguard Worker        if (len_str - pos) < 2:
372*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("Incomplete time component")
373*cda5da8dSAndroid Build Coastguard Worker
374*cda5da8dSAndroid Build Coastguard Worker        time_comps[comp] = int(tstr[pos:pos+2])
375*cda5da8dSAndroid Build Coastguard Worker
376*cda5da8dSAndroid Build Coastguard Worker        pos += 2
377*cda5da8dSAndroid Build Coastguard Worker        next_char = tstr[pos:pos+1]
378*cda5da8dSAndroid Build Coastguard Worker
379*cda5da8dSAndroid Build Coastguard Worker        if comp == 0:
380*cda5da8dSAndroid Build Coastguard Worker            has_sep = next_char == ':'
381*cda5da8dSAndroid Build Coastguard Worker
382*cda5da8dSAndroid Build Coastguard Worker        if not next_char or comp >= 2:
383*cda5da8dSAndroid Build Coastguard Worker            break
384*cda5da8dSAndroid Build Coastguard Worker
385*cda5da8dSAndroid Build Coastguard Worker        if has_sep and next_char != ':':
386*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("Invalid time separator: %c" % next_char)
387*cda5da8dSAndroid Build Coastguard Worker
388*cda5da8dSAndroid Build Coastguard Worker        pos += has_sep
389*cda5da8dSAndroid Build Coastguard Worker
390*cda5da8dSAndroid Build Coastguard Worker    if pos < len_str:
391*cda5da8dSAndroid Build Coastguard Worker        if tstr[pos] not in '.,':
392*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("Invalid microsecond component")
393*cda5da8dSAndroid Build Coastguard Worker        else:
394*cda5da8dSAndroid Build Coastguard Worker            pos += 1
395*cda5da8dSAndroid Build Coastguard Worker
396*cda5da8dSAndroid Build Coastguard Worker            len_remainder = len_str - pos
397*cda5da8dSAndroid Build Coastguard Worker
398*cda5da8dSAndroid Build Coastguard Worker            if len_remainder >= 6:
399*cda5da8dSAndroid Build Coastguard Worker                to_parse = 6
400*cda5da8dSAndroid Build Coastguard Worker            else:
401*cda5da8dSAndroid Build Coastguard Worker                to_parse = len_remainder
402*cda5da8dSAndroid Build Coastguard Worker
403*cda5da8dSAndroid Build Coastguard Worker            time_comps[3] = int(tstr[pos:(pos+to_parse)])
404*cda5da8dSAndroid Build Coastguard Worker            if to_parse < 6:
405*cda5da8dSAndroid Build Coastguard Worker                time_comps[3] *= _FRACTION_CORRECTION[to_parse-1]
406*cda5da8dSAndroid Build Coastguard Worker            if (len_remainder > to_parse
407*cda5da8dSAndroid Build Coastguard Worker                    and not all(map(_is_ascii_digit, tstr[(pos+to_parse):]))):
408*cda5da8dSAndroid Build Coastguard Worker                raise ValueError("Non-digit values in unparsed fraction")
409*cda5da8dSAndroid Build Coastguard Worker
410*cda5da8dSAndroid Build Coastguard Worker    return time_comps
411*cda5da8dSAndroid Build Coastguard Worker
412*cda5da8dSAndroid Build Coastguard Workerdef _parse_isoformat_time(tstr):
413*cda5da8dSAndroid Build Coastguard Worker    # Format supported is HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]
414*cda5da8dSAndroid Build Coastguard Worker    len_str = len(tstr)
415*cda5da8dSAndroid Build Coastguard Worker    if len_str < 2:
416*cda5da8dSAndroid Build Coastguard Worker        raise ValueError("Isoformat time too short")
417*cda5da8dSAndroid Build Coastguard Worker
418*cda5da8dSAndroid Build Coastguard Worker    # This is equivalent to re.search('[+-Z]', tstr), but faster
419*cda5da8dSAndroid Build Coastguard Worker    tz_pos = (tstr.find('-') + 1 or tstr.find('+') + 1 or tstr.find('Z') + 1)
420*cda5da8dSAndroid Build Coastguard Worker    timestr = tstr[:tz_pos-1] if tz_pos > 0 else tstr
421*cda5da8dSAndroid Build Coastguard Worker
422*cda5da8dSAndroid Build Coastguard Worker    time_comps = _parse_hh_mm_ss_ff(timestr)
423*cda5da8dSAndroid Build Coastguard Worker
424*cda5da8dSAndroid Build Coastguard Worker    tzi = None
425*cda5da8dSAndroid Build Coastguard Worker    if tz_pos == len_str and tstr[-1] == 'Z':
426*cda5da8dSAndroid Build Coastguard Worker        tzi = timezone.utc
427*cda5da8dSAndroid Build Coastguard Worker    elif tz_pos > 0:
428*cda5da8dSAndroid Build Coastguard Worker        tzstr = tstr[tz_pos:]
429*cda5da8dSAndroid Build Coastguard Worker
430*cda5da8dSAndroid Build Coastguard Worker        # Valid time zone strings are:
431*cda5da8dSAndroid Build Coastguard Worker        # HH                  len: 2
432*cda5da8dSAndroid Build Coastguard Worker        # HHMM                len: 4
433*cda5da8dSAndroid Build Coastguard Worker        # HH:MM               len: 5
434*cda5da8dSAndroid Build Coastguard Worker        # HHMMSS              len: 6
435*cda5da8dSAndroid Build Coastguard Worker        # HHMMSS.f+           len: 7+
436*cda5da8dSAndroid Build Coastguard Worker        # HH:MM:SS            len: 8
437*cda5da8dSAndroid Build Coastguard Worker        # HH:MM:SS.f+         len: 10+
438*cda5da8dSAndroid Build Coastguard Worker
439*cda5da8dSAndroid Build Coastguard Worker        if len(tzstr) in (0, 1, 3):
440*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("Malformed time zone string")
441*cda5da8dSAndroid Build Coastguard Worker
442*cda5da8dSAndroid Build Coastguard Worker        tz_comps = _parse_hh_mm_ss_ff(tzstr)
443*cda5da8dSAndroid Build Coastguard Worker
444*cda5da8dSAndroid Build Coastguard Worker        if all(x == 0 for x in tz_comps):
445*cda5da8dSAndroid Build Coastguard Worker            tzi = timezone.utc
446*cda5da8dSAndroid Build Coastguard Worker        else:
447*cda5da8dSAndroid Build Coastguard Worker            tzsign = -1 if tstr[tz_pos - 1] == '-' else 1
448*cda5da8dSAndroid Build Coastguard Worker
449*cda5da8dSAndroid Build Coastguard Worker            td = timedelta(hours=tz_comps[0], minutes=tz_comps[1],
450*cda5da8dSAndroid Build Coastguard Worker                           seconds=tz_comps[2], microseconds=tz_comps[3])
451*cda5da8dSAndroid Build Coastguard Worker
452*cda5da8dSAndroid Build Coastguard Worker            tzi = timezone(tzsign * td)
453*cda5da8dSAndroid Build Coastguard Worker
454*cda5da8dSAndroid Build Coastguard Worker    time_comps.append(tzi)
455*cda5da8dSAndroid Build Coastguard Worker
456*cda5da8dSAndroid Build Coastguard Worker    return time_comps
457*cda5da8dSAndroid Build Coastguard Worker
458*cda5da8dSAndroid Build Coastguard Worker# tuple[int, int, int] -> tuple[int, int, int] version of date.fromisocalendar
459*cda5da8dSAndroid Build Coastguard Workerdef _isoweek_to_gregorian(year, week, day):
460*cda5da8dSAndroid Build Coastguard Worker    # Year is bounded this way because 9999-12-31 is (9999, 52, 5)
461*cda5da8dSAndroid Build Coastguard Worker    if not MINYEAR <= year <= MAXYEAR:
462*cda5da8dSAndroid Build Coastguard Worker        raise ValueError(f"Year is out of range: {year}")
463*cda5da8dSAndroid Build Coastguard Worker
464*cda5da8dSAndroid Build Coastguard Worker    if not 0 < week < 53:
465*cda5da8dSAndroid Build Coastguard Worker        out_of_range = True
466*cda5da8dSAndroid Build Coastguard Worker
467*cda5da8dSAndroid Build Coastguard Worker        if week == 53:
468*cda5da8dSAndroid Build Coastguard Worker            # ISO years have 53 weeks in them on years starting with a
469*cda5da8dSAndroid Build Coastguard Worker            # Thursday and leap years starting on a Wednesday
470*cda5da8dSAndroid Build Coastguard Worker            first_weekday = _ymd2ord(year, 1, 1) % 7
471*cda5da8dSAndroid Build Coastguard Worker            if (first_weekday == 4 or (first_weekday == 3 and
472*cda5da8dSAndroid Build Coastguard Worker                                       _is_leap(year))):
473*cda5da8dSAndroid Build Coastguard Worker                out_of_range = False
474*cda5da8dSAndroid Build Coastguard Worker
475*cda5da8dSAndroid Build Coastguard Worker        if out_of_range:
476*cda5da8dSAndroid Build Coastguard Worker            raise ValueError(f"Invalid week: {week}")
477*cda5da8dSAndroid Build Coastguard Worker
478*cda5da8dSAndroid Build Coastguard Worker    if not 0 < day < 8:
479*cda5da8dSAndroid Build Coastguard Worker        raise ValueError(f"Invalid weekday: {day} (range is [1, 7])")
480*cda5da8dSAndroid Build Coastguard Worker
481*cda5da8dSAndroid Build Coastguard Worker    # Now compute the offset from (Y, 1, 1) in days:
482*cda5da8dSAndroid Build Coastguard Worker    day_offset = (week - 1) * 7 + (day - 1)
483*cda5da8dSAndroid Build Coastguard Worker
484*cda5da8dSAndroid Build Coastguard Worker    # Calculate the ordinal day for monday, week 1
485*cda5da8dSAndroid Build Coastguard Worker    day_1 = _isoweek1monday(year)
486*cda5da8dSAndroid Build Coastguard Worker    ord_day = day_1 + day_offset
487*cda5da8dSAndroid Build Coastguard Worker
488*cda5da8dSAndroid Build Coastguard Worker    return _ord2ymd(ord_day)
489*cda5da8dSAndroid Build Coastguard Worker
490*cda5da8dSAndroid Build Coastguard Worker
491*cda5da8dSAndroid Build Coastguard Worker# Just raise TypeError if the arg isn't None or a string.
492*cda5da8dSAndroid Build Coastguard Workerdef _check_tzname(name):
493*cda5da8dSAndroid Build Coastguard Worker    if name is not None and not isinstance(name, str):
494*cda5da8dSAndroid Build Coastguard Worker        raise TypeError("tzinfo.tzname() must return None or string, "
495*cda5da8dSAndroid Build Coastguard Worker                        "not '%s'" % type(name))
496*cda5da8dSAndroid Build Coastguard Worker
497*cda5da8dSAndroid Build Coastguard Worker# name is the offset-producing method, "utcoffset" or "dst".
498*cda5da8dSAndroid Build Coastguard Worker# offset is what it returned.
499*cda5da8dSAndroid Build Coastguard Worker# If offset isn't None or timedelta, raises TypeError.
500*cda5da8dSAndroid Build Coastguard Worker# If offset is None, returns None.
501*cda5da8dSAndroid Build Coastguard Worker# Else offset is checked for being in range.
502*cda5da8dSAndroid Build Coastguard Worker# If it is, its integer value is returned.  Else ValueError is raised.
503*cda5da8dSAndroid Build Coastguard Workerdef _check_utc_offset(name, offset):
504*cda5da8dSAndroid Build Coastguard Worker    assert name in ("utcoffset", "dst")
505*cda5da8dSAndroid Build Coastguard Worker    if offset is None:
506*cda5da8dSAndroid Build Coastguard Worker        return
507*cda5da8dSAndroid Build Coastguard Worker    if not isinstance(offset, timedelta):
508*cda5da8dSAndroid Build Coastguard Worker        raise TypeError("tzinfo.%s() must return None "
509*cda5da8dSAndroid Build Coastguard Worker                        "or timedelta, not '%s'" % (name, type(offset)))
510*cda5da8dSAndroid Build Coastguard Worker    if not -timedelta(1) < offset < timedelta(1):
511*cda5da8dSAndroid Build Coastguard Worker        raise ValueError("%s()=%s, must be strictly between "
512*cda5da8dSAndroid Build Coastguard Worker                         "-timedelta(hours=24) and timedelta(hours=24)" %
513*cda5da8dSAndroid Build Coastguard Worker                         (name, offset))
514*cda5da8dSAndroid Build Coastguard Worker
515*cda5da8dSAndroid Build Coastguard Workerdef _check_date_fields(year, month, day):
516*cda5da8dSAndroid Build Coastguard Worker    year = _index(year)
517*cda5da8dSAndroid Build Coastguard Worker    month = _index(month)
518*cda5da8dSAndroid Build Coastguard Worker    day = _index(day)
519*cda5da8dSAndroid Build Coastguard Worker    if not MINYEAR <= year <= MAXYEAR:
520*cda5da8dSAndroid Build Coastguard Worker        raise ValueError('year must be in %d..%d' % (MINYEAR, MAXYEAR), year)
521*cda5da8dSAndroid Build Coastguard Worker    if not 1 <= month <= 12:
522*cda5da8dSAndroid Build Coastguard Worker        raise ValueError('month must be in 1..12', month)
523*cda5da8dSAndroid Build Coastguard Worker    dim = _days_in_month(year, month)
524*cda5da8dSAndroid Build Coastguard Worker    if not 1 <= day <= dim:
525*cda5da8dSAndroid Build Coastguard Worker        raise ValueError('day must be in 1..%d' % dim, day)
526*cda5da8dSAndroid Build Coastguard Worker    return year, month, day
527*cda5da8dSAndroid Build Coastguard Worker
528*cda5da8dSAndroid Build Coastguard Workerdef _check_time_fields(hour, minute, second, microsecond, fold):
529*cda5da8dSAndroid Build Coastguard Worker    hour = _index(hour)
530*cda5da8dSAndroid Build Coastguard Worker    minute = _index(minute)
531*cda5da8dSAndroid Build Coastguard Worker    second = _index(second)
532*cda5da8dSAndroid Build Coastguard Worker    microsecond = _index(microsecond)
533*cda5da8dSAndroid Build Coastguard Worker    if not 0 <= hour <= 23:
534*cda5da8dSAndroid Build Coastguard Worker        raise ValueError('hour must be in 0..23', hour)
535*cda5da8dSAndroid Build Coastguard Worker    if not 0 <= minute <= 59:
536*cda5da8dSAndroid Build Coastguard Worker        raise ValueError('minute must be in 0..59', minute)
537*cda5da8dSAndroid Build Coastguard Worker    if not 0 <= second <= 59:
538*cda5da8dSAndroid Build Coastguard Worker        raise ValueError('second must be in 0..59', second)
539*cda5da8dSAndroid Build Coastguard Worker    if not 0 <= microsecond <= 999999:
540*cda5da8dSAndroid Build Coastguard Worker        raise ValueError('microsecond must be in 0..999999', microsecond)
541*cda5da8dSAndroid Build Coastguard Worker    if fold not in (0, 1):
542*cda5da8dSAndroid Build Coastguard Worker        raise ValueError('fold must be either 0 or 1', fold)
543*cda5da8dSAndroid Build Coastguard Worker    return hour, minute, second, microsecond, fold
544*cda5da8dSAndroid Build Coastguard Worker
545*cda5da8dSAndroid Build Coastguard Workerdef _check_tzinfo_arg(tz):
546*cda5da8dSAndroid Build Coastguard Worker    if tz is not None and not isinstance(tz, tzinfo):
547*cda5da8dSAndroid Build Coastguard Worker        raise TypeError("tzinfo argument must be None or of a tzinfo subclass")
548*cda5da8dSAndroid Build Coastguard Worker
549*cda5da8dSAndroid Build Coastguard Workerdef _cmperror(x, y):
550*cda5da8dSAndroid Build Coastguard Worker    raise TypeError("can't compare '%s' to '%s'" % (
551*cda5da8dSAndroid Build Coastguard Worker                    type(x).__name__, type(y).__name__))
552*cda5da8dSAndroid Build Coastguard Worker
553*cda5da8dSAndroid Build Coastguard Workerdef _divide_and_round(a, b):
554*cda5da8dSAndroid Build Coastguard Worker    """divide a by b and round result to the nearest integer
555*cda5da8dSAndroid Build Coastguard Worker
556*cda5da8dSAndroid Build Coastguard Worker    When the ratio is exactly half-way between two integers,
557*cda5da8dSAndroid Build Coastguard Worker    the even integer is returned.
558*cda5da8dSAndroid Build Coastguard Worker    """
559*cda5da8dSAndroid Build Coastguard Worker    # Based on the reference implementation for divmod_near
560*cda5da8dSAndroid Build Coastguard Worker    # in Objects/longobject.c.
561*cda5da8dSAndroid Build Coastguard Worker    q, r = divmod(a, b)
562*cda5da8dSAndroid Build Coastguard Worker    # round up if either r / b > 0.5, or r / b == 0.5 and q is odd.
563*cda5da8dSAndroid Build Coastguard Worker    # The expression r / b > 0.5 is equivalent to 2 * r > b if b is
564*cda5da8dSAndroid Build Coastguard Worker    # positive, 2 * r < b if b negative.
565*cda5da8dSAndroid Build Coastguard Worker    r *= 2
566*cda5da8dSAndroid Build Coastguard Worker    greater_than_half = r > b if b > 0 else r < b
567*cda5da8dSAndroid Build Coastguard Worker    if greater_than_half or r == b and q % 2 == 1:
568*cda5da8dSAndroid Build Coastguard Worker        q += 1
569*cda5da8dSAndroid Build Coastguard Worker
570*cda5da8dSAndroid Build Coastguard Worker    return q
571*cda5da8dSAndroid Build Coastguard Worker
572*cda5da8dSAndroid Build Coastguard Worker
573*cda5da8dSAndroid Build Coastguard Workerclass timedelta:
574*cda5da8dSAndroid Build Coastguard Worker    """Represent the difference between two datetime objects.
575*cda5da8dSAndroid Build Coastguard Worker
576*cda5da8dSAndroid Build Coastguard Worker    Supported operators:
577*cda5da8dSAndroid Build Coastguard Worker
578*cda5da8dSAndroid Build Coastguard Worker    - add, subtract timedelta
579*cda5da8dSAndroid Build Coastguard Worker    - unary plus, minus, abs
580*cda5da8dSAndroid Build Coastguard Worker    - compare to timedelta
581*cda5da8dSAndroid Build Coastguard Worker    - multiply, divide by int
582*cda5da8dSAndroid Build Coastguard Worker
583*cda5da8dSAndroid Build Coastguard Worker    In addition, datetime supports subtraction of two datetime objects
584*cda5da8dSAndroid Build Coastguard Worker    returning a timedelta, and addition or subtraction of a datetime
585*cda5da8dSAndroid Build Coastguard Worker    and a timedelta giving a datetime.
586*cda5da8dSAndroid Build Coastguard Worker
587*cda5da8dSAndroid Build Coastguard Worker    Representation: (days, seconds, microseconds).  Why?  Because I
588*cda5da8dSAndroid Build Coastguard Worker    felt like it.
589*cda5da8dSAndroid Build Coastguard Worker    """
590*cda5da8dSAndroid Build Coastguard Worker    __slots__ = '_days', '_seconds', '_microseconds', '_hashcode'
591*cda5da8dSAndroid Build Coastguard Worker
592*cda5da8dSAndroid Build Coastguard Worker    def __new__(cls, days=0, seconds=0, microseconds=0,
593*cda5da8dSAndroid Build Coastguard Worker                milliseconds=0, minutes=0, hours=0, weeks=0):
594*cda5da8dSAndroid Build Coastguard Worker        # Doing this efficiently and accurately in C is going to be difficult
595*cda5da8dSAndroid Build Coastguard Worker        # and error-prone, due to ubiquitous overflow possibilities, and that
596*cda5da8dSAndroid Build Coastguard Worker        # C double doesn't have enough bits of precision to represent
597*cda5da8dSAndroid Build Coastguard Worker        # microseconds over 10K years faithfully.  The code here tries to make
598*cda5da8dSAndroid Build Coastguard Worker        # explicit where go-fast assumptions can be relied on, in order to
599*cda5da8dSAndroid Build Coastguard Worker        # guide the C implementation; it's way more convoluted than speed-
600*cda5da8dSAndroid Build Coastguard Worker        # ignoring auto-overflow-to-long idiomatic Python could be.
601*cda5da8dSAndroid Build Coastguard Worker
602*cda5da8dSAndroid Build Coastguard Worker        # XXX Check that all inputs are ints or floats.
603*cda5da8dSAndroid Build Coastguard Worker
604*cda5da8dSAndroid Build Coastguard Worker        # Final values, all integer.
605*cda5da8dSAndroid Build Coastguard Worker        # s and us fit in 32-bit signed ints; d isn't bounded.
606*cda5da8dSAndroid Build Coastguard Worker        d = s = us = 0
607*cda5da8dSAndroid Build Coastguard Worker
608*cda5da8dSAndroid Build Coastguard Worker        # Normalize everything to days, seconds, microseconds.
609*cda5da8dSAndroid Build Coastguard Worker        days += weeks*7
610*cda5da8dSAndroid Build Coastguard Worker        seconds += minutes*60 + hours*3600
611*cda5da8dSAndroid Build Coastguard Worker        microseconds += milliseconds*1000
612*cda5da8dSAndroid Build Coastguard Worker
613*cda5da8dSAndroid Build Coastguard Worker        # Get rid of all fractions, and normalize s and us.
614*cda5da8dSAndroid Build Coastguard Worker        # Take a deep breath <wink>.
615*cda5da8dSAndroid Build Coastguard Worker        if isinstance(days, float):
616*cda5da8dSAndroid Build Coastguard Worker            dayfrac, days = _math.modf(days)
617*cda5da8dSAndroid Build Coastguard Worker            daysecondsfrac, daysecondswhole = _math.modf(dayfrac * (24.*3600.))
618*cda5da8dSAndroid Build Coastguard Worker            assert daysecondswhole == int(daysecondswhole)  # can't overflow
619*cda5da8dSAndroid Build Coastguard Worker            s = int(daysecondswhole)
620*cda5da8dSAndroid Build Coastguard Worker            assert days == int(days)
621*cda5da8dSAndroid Build Coastguard Worker            d = int(days)
622*cda5da8dSAndroid Build Coastguard Worker        else:
623*cda5da8dSAndroid Build Coastguard Worker            daysecondsfrac = 0.0
624*cda5da8dSAndroid Build Coastguard Worker            d = days
625*cda5da8dSAndroid Build Coastguard Worker        assert isinstance(daysecondsfrac, float)
626*cda5da8dSAndroid Build Coastguard Worker        assert abs(daysecondsfrac) <= 1.0
627*cda5da8dSAndroid Build Coastguard Worker        assert isinstance(d, int)
628*cda5da8dSAndroid Build Coastguard Worker        assert abs(s) <= 24 * 3600
629*cda5da8dSAndroid Build Coastguard Worker        # days isn't referenced again before redefinition
630*cda5da8dSAndroid Build Coastguard Worker
631*cda5da8dSAndroid Build Coastguard Worker        if isinstance(seconds, float):
632*cda5da8dSAndroid Build Coastguard Worker            secondsfrac, seconds = _math.modf(seconds)
633*cda5da8dSAndroid Build Coastguard Worker            assert seconds == int(seconds)
634*cda5da8dSAndroid Build Coastguard Worker            seconds = int(seconds)
635*cda5da8dSAndroid Build Coastguard Worker            secondsfrac += daysecondsfrac
636*cda5da8dSAndroid Build Coastguard Worker            assert abs(secondsfrac) <= 2.0
637*cda5da8dSAndroid Build Coastguard Worker        else:
638*cda5da8dSAndroid Build Coastguard Worker            secondsfrac = daysecondsfrac
639*cda5da8dSAndroid Build Coastguard Worker        # daysecondsfrac isn't referenced again
640*cda5da8dSAndroid Build Coastguard Worker        assert isinstance(secondsfrac, float)
641*cda5da8dSAndroid Build Coastguard Worker        assert abs(secondsfrac) <= 2.0
642*cda5da8dSAndroid Build Coastguard Worker
643*cda5da8dSAndroid Build Coastguard Worker        assert isinstance(seconds, int)
644*cda5da8dSAndroid Build Coastguard Worker        days, seconds = divmod(seconds, 24*3600)
645*cda5da8dSAndroid Build Coastguard Worker        d += days
646*cda5da8dSAndroid Build Coastguard Worker        s += int(seconds)    # can't overflow
647*cda5da8dSAndroid Build Coastguard Worker        assert isinstance(s, int)
648*cda5da8dSAndroid Build Coastguard Worker        assert abs(s) <= 2 * 24 * 3600
649*cda5da8dSAndroid Build Coastguard Worker        # seconds isn't referenced again before redefinition
650*cda5da8dSAndroid Build Coastguard Worker
651*cda5da8dSAndroid Build Coastguard Worker        usdouble = secondsfrac * 1e6
652*cda5da8dSAndroid Build Coastguard Worker        assert abs(usdouble) < 2.1e6    # exact value not critical
653*cda5da8dSAndroid Build Coastguard Worker        # secondsfrac isn't referenced again
654*cda5da8dSAndroid Build Coastguard Worker
655*cda5da8dSAndroid Build Coastguard Worker        if isinstance(microseconds, float):
656*cda5da8dSAndroid Build Coastguard Worker            microseconds = round(microseconds + usdouble)
657*cda5da8dSAndroid Build Coastguard Worker            seconds, microseconds = divmod(microseconds, 1000000)
658*cda5da8dSAndroid Build Coastguard Worker            days, seconds = divmod(seconds, 24*3600)
659*cda5da8dSAndroid Build Coastguard Worker            d += days
660*cda5da8dSAndroid Build Coastguard Worker            s += seconds
661*cda5da8dSAndroid Build Coastguard Worker        else:
662*cda5da8dSAndroid Build Coastguard Worker            microseconds = int(microseconds)
663*cda5da8dSAndroid Build Coastguard Worker            seconds, microseconds = divmod(microseconds, 1000000)
664*cda5da8dSAndroid Build Coastguard Worker            days, seconds = divmod(seconds, 24*3600)
665*cda5da8dSAndroid Build Coastguard Worker            d += days
666*cda5da8dSAndroid Build Coastguard Worker            s += seconds
667*cda5da8dSAndroid Build Coastguard Worker            microseconds = round(microseconds + usdouble)
668*cda5da8dSAndroid Build Coastguard Worker        assert isinstance(s, int)
669*cda5da8dSAndroid Build Coastguard Worker        assert isinstance(microseconds, int)
670*cda5da8dSAndroid Build Coastguard Worker        assert abs(s) <= 3 * 24 * 3600
671*cda5da8dSAndroid Build Coastguard Worker        assert abs(microseconds) < 3.1e6
672*cda5da8dSAndroid Build Coastguard Worker
673*cda5da8dSAndroid Build Coastguard Worker        # Just a little bit of carrying possible for microseconds and seconds.
674*cda5da8dSAndroid Build Coastguard Worker        seconds, us = divmod(microseconds, 1000000)
675*cda5da8dSAndroid Build Coastguard Worker        s += seconds
676*cda5da8dSAndroid Build Coastguard Worker        days, s = divmod(s, 24*3600)
677*cda5da8dSAndroid Build Coastguard Worker        d += days
678*cda5da8dSAndroid Build Coastguard Worker
679*cda5da8dSAndroid Build Coastguard Worker        assert isinstance(d, int)
680*cda5da8dSAndroid Build Coastguard Worker        assert isinstance(s, int) and 0 <= s < 24*3600
681*cda5da8dSAndroid Build Coastguard Worker        assert isinstance(us, int) and 0 <= us < 1000000
682*cda5da8dSAndroid Build Coastguard Worker
683*cda5da8dSAndroid Build Coastguard Worker        if abs(d) > 999999999:
684*cda5da8dSAndroid Build Coastguard Worker            raise OverflowError("timedelta # of days is too large: %d" % d)
685*cda5da8dSAndroid Build Coastguard Worker
686*cda5da8dSAndroid Build Coastguard Worker        self = object.__new__(cls)
687*cda5da8dSAndroid Build Coastguard Worker        self._days = d
688*cda5da8dSAndroid Build Coastguard Worker        self._seconds = s
689*cda5da8dSAndroid Build Coastguard Worker        self._microseconds = us
690*cda5da8dSAndroid Build Coastguard Worker        self._hashcode = -1
691*cda5da8dSAndroid Build Coastguard Worker        return self
692*cda5da8dSAndroid Build Coastguard Worker
693*cda5da8dSAndroid Build Coastguard Worker    def __repr__(self):
694*cda5da8dSAndroid Build Coastguard Worker        args = []
695*cda5da8dSAndroid Build Coastguard Worker        if self._days:
696*cda5da8dSAndroid Build Coastguard Worker            args.append("days=%d" % self._days)
697*cda5da8dSAndroid Build Coastguard Worker        if self._seconds:
698*cda5da8dSAndroid Build Coastguard Worker            args.append("seconds=%d" % self._seconds)
699*cda5da8dSAndroid Build Coastguard Worker        if self._microseconds:
700*cda5da8dSAndroid Build Coastguard Worker            args.append("microseconds=%d" % self._microseconds)
701*cda5da8dSAndroid Build Coastguard Worker        if not args:
702*cda5da8dSAndroid Build Coastguard Worker            args.append('0')
703*cda5da8dSAndroid Build Coastguard Worker        return "%s.%s(%s)" % (self.__class__.__module__,
704*cda5da8dSAndroid Build Coastguard Worker                              self.__class__.__qualname__,
705*cda5da8dSAndroid Build Coastguard Worker                              ', '.join(args))
706*cda5da8dSAndroid Build Coastguard Worker
707*cda5da8dSAndroid Build Coastguard Worker    def __str__(self):
708*cda5da8dSAndroid Build Coastguard Worker        mm, ss = divmod(self._seconds, 60)
709*cda5da8dSAndroid Build Coastguard Worker        hh, mm = divmod(mm, 60)
710*cda5da8dSAndroid Build Coastguard Worker        s = "%d:%02d:%02d" % (hh, mm, ss)
711*cda5da8dSAndroid Build Coastguard Worker        if self._days:
712*cda5da8dSAndroid Build Coastguard Worker            def plural(n):
713*cda5da8dSAndroid Build Coastguard Worker                return n, abs(n) != 1 and "s" or ""
714*cda5da8dSAndroid Build Coastguard Worker            s = ("%d day%s, " % plural(self._days)) + s
715*cda5da8dSAndroid Build Coastguard Worker        if self._microseconds:
716*cda5da8dSAndroid Build Coastguard Worker            s = s + ".%06d" % self._microseconds
717*cda5da8dSAndroid Build Coastguard Worker        return s
718*cda5da8dSAndroid Build Coastguard Worker
719*cda5da8dSAndroid Build Coastguard Worker    def total_seconds(self):
720*cda5da8dSAndroid Build Coastguard Worker        """Total seconds in the duration."""
721*cda5da8dSAndroid Build Coastguard Worker        return ((self.days * 86400 + self.seconds) * 10**6 +
722*cda5da8dSAndroid Build Coastguard Worker                self.microseconds) / 10**6
723*cda5da8dSAndroid Build Coastguard Worker
724*cda5da8dSAndroid Build Coastguard Worker    # Read-only field accessors
725*cda5da8dSAndroid Build Coastguard Worker    @property
726*cda5da8dSAndroid Build Coastguard Worker    def days(self):
727*cda5da8dSAndroid Build Coastguard Worker        """days"""
728*cda5da8dSAndroid Build Coastguard Worker        return self._days
729*cda5da8dSAndroid Build Coastguard Worker
730*cda5da8dSAndroid Build Coastguard Worker    @property
731*cda5da8dSAndroid Build Coastguard Worker    def seconds(self):
732*cda5da8dSAndroid Build Coastguard Worker        """seconds"""
733*cda5da8dSAndroid Build Coastguard Worker        return self._seconds
734*cda5da8dSAndroid Build Coastguard Worker
735*cda5da8dSAndroid Build Coastguard Worker    @property
736*cda5da8dSAndroid Build Coastguard Worker    def microseconds(self):
737*cda5da8dSAndroid Build Coastguard Worker        """microseconds"""
738*cda5da8dSAndroid Build Coastguard Worker        return self._microseconds
739*cda5da8dSAndroid Build Coastguard Worker
740*cda5da8dSAndroid Build Coastguard Worker    def __add__(self, other):
741*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, timedelta):
742*cda5da8dSAndroid Build Coastguard Worker            # for CPython compatibility, we cannot use
743*cda5da8dSAndroid Build Coastguard Worker            # our __class__ here, but need a real timedelta
744*cda5da8dSAndroid Build Coastguard Worker            return timedelta(self._days + other._days,
745*cda5da8dSAndroid Build Coastguard Worker                             self._seconds + other._seconds,
746*cda5da8dSAndroid Build Coastguard Worker                             self._microseconds + other._microseconds)
747*cda5da8dSAndroid Build Coastguard Worker        return NotImplemented
748*cda5da8dSAndroid Build Coastguard Worker
749*cda5da8dSAndroid Build Coastguard Worker    __radd__ = __add__
750*cda5da8dSAndroid Build Coastguard Worker
751*cda5da8dSAndroid Build Coastguard Worker    def __sub__(self, other):
752*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, timedelta):
753*cda5da8dSAndroid Build Coastguard Worker            # for CPython compatibility, we cannot use
754*cda5da8dSAndroid Build Coastguard Worker            # our __class__ here, but need a real timedelta
755*cda5da8dSAndroid Build Coastguard Worker            return timedelta(self._days - other._days,
756*cda5da8dSAndroid Build Coastguard Worker                             self._seconds - other._seconds,
757*cda5da8dSAndroid Build Coastguard Worker                             self._microseconds - other._microseconds)
758*cda5da8dSAndroid Build Coastguard Worker        return NotImplemented
759*cda5da8dSAndroid Build Coastguard Worker
760*cda5da8dSAndroid Build Coastguard Worker    def __rsub__(self, other):
761*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, timedelta):
762*cda5da8dSAndroid Build Coastguard Worker            return -self + other
763*cda5da8dSAndroid Build Coastguard Worker        return NotImplemented
764*cda5da8dSAndroid Build Coastguard Worker
765*cda5da8dSAndroid Build Coastguard Worker    def __neg__(self):
766*cda5da8dSAndroid Build Coastguard Worker        # for CPython compatibility, we cannot use
767*cda5da8dSAndroid Build Coastguard Worker        # our __class__ here, but need a real timedelta
768*cda5da8dSAndroid Build Coastguard Worker        return timedelta(-self._days,
769*cda5da8dSAndroid Build Coastguard Worker                         -self._seconds,
770*cda5da8dSAndroid Build Coastguard Worker                         -self._microseconds)
771*cda5da8dSAndroid Build Coastguard Worker
772*cda5da8dSAndroid Build Coastguard Worker    def __pos__(self):
773*cda5da8dSAndroid Build Coastguard Worker        return self
774*cda5da8dSAndroid Build Coastguard Worker
775*cda5da8dSAndroid Build Coastguard Worker    def __abs__(self):
776*cda5da8dSAndroid Build Coastguard Worker        if self._days < 0:
777*cda5da8dSAndroid Build Coastguard Worker            return -self
778*cda5da8dSAndroid Build Coastguard Worker        else:
779*cda5da8dSAndroid Build Coastguard Worker            return self
780*cda5da8dSAndroid Build Coastguard Worker
781*cda5da8dSAndroid Build Coastguard Worker    def __mul__(self, other):
782*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, int):
783*cda5da8dSAndroid Build Coastguard Worker            # for CPython compatibility, we cannot use
784*cda5da8dSAndroid Build Coastguard Worker            # our __class__ here, but need a real timedelta
785*cda5da8dSAndroid Build Coastguard Worker            return timedelta(self._days * other,
786*cda5da8dSAndroid Build Coastguard Worker                             self._seconds * other,
787*cda5da8dSAndroid Build Coastguard Worker                             self._microseconds * other)
788*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, float):
789*cda5da8dSAndroid Build Coastguard Worker            usec = self._to_microseconds()
790*cda5da8dSAndroid Build Coastguard Worker            a, b = other.as_integer_ratio()
791*cda5da8dSAndroid Build Coastguard Worker            return timedelta(0, 0, _divide_and_round(usec * a, b))
792*cda5da8dSAndroid Build Coastguard Worker        return NotImplemented
793*cda5da8dSAndroid Build Coastguard Worker
794*cda5da8dSAndroid Build Coastguard Worker    __rmul__ = __mul__
795*cda5da8dSAndroid Build Coastguard Worker
796*cda5da8dSAndroid Build Coastguard Worker    def _to_microseconds(self):
797*cda5da8dSAndroid Build Coastguard Worker        return ((self._days * (24*3600) + self._seconds) * 1000000 +
798*cda5da8dSAndroid Build Coastguard Worker                self._microseconds)
799*cda5da8dSAndroid Build Coastguard Worker
800*cda5da8dSAndroid Build Coastguard Worker    def __floordiv__(self, other):
801*cda5da8dSAndroid Build Coastguard Worker        if not isinstance(other, (int, timedelta)):
802*cda5da8dSAndroid Build Coastguard Worker            return NotImplemented
803*cda5da8dSAndroid Build Coastguard Worker        usec = self._to_microseconds()
804*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, timedelta):
805*cda5da8dSAndroid Build Coastguard Worker            return usec // other._to_microseconds()
806*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, int):
807*cda5da8dSAndroid Build Coastguard Worker            return timedelta(0, 0, usec // other)
808*cda5da8dSAndroid Build Coastguard Worker
809*cda5da8dSAndroid Build Coastguard Worker    def __truediv__(self, other):
810*cda5da8dSAndroid Build Coastguard Worker        if not isinstance(other, (int, float, timedelta)):
811*cda5da8dSAndroid Build Coastguard Worker            return NotImplemented
812*cda5da8dSAndroid Build Coastguard Worker        usec = self._to_microseconds()
813*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, timedelta):
814*cda5da8dSAndroid Build Coastguard Worker            return usec / other._to_microseconds()
815*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, int):
816*cda5da8dSAndroid Build Coastguard Worker            return timedelta(0, 0, _divide_and_round(usec, other))
817*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, float):
818*cda5da8dSAndroid Build Coastguard Worker            a, b = other.as_integer_ratio()
819*cda5da8dSAndroid Build Coastguard Worker            return timedelta(0, 0, _divide_and_round(b * usec, a))
820*cda5da8dSAndroid Build Coastguard Worker
821*cda5da8dSAndroid Build Coastguard Worker    def __mod__(self, other):
822*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, timedelta):
823*cda5da8dSAndroid Build Coastguard Worker            r = self._to_microseconds() % other._to_microseconds()
824*cda5da8dSAndroid Build Coastguard Worker            return timedelta(0, 0, r)
825*cda5da8dSAndroid Build Coastguard Worker        return NotImplemented
826*cda5da8dSAndroid Build Coastguard Worker
827*cda5da8dSAndroid Build Coastguard Worker    def __divmod__(self, other):
828*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, timedelta):
829*cda5da8dSAndroid Build Coastguard Worker            q, r = divmod(self._to_microseconds(),
830*cda5da8dSAndroid Build Coastguard Worker                          other._to_microseconds())
831*cda5da8dSAndroid Build Coastguard Worker            return q, timedelta(0, 0, r)
832*cda5da8dSAndroid Build Coastguard Worker        return NotImplemented
833*cda5da8dSAndroid Build Coastguard Worker
834*cda5da8dSAndroid Build Coastguard Worker    # Comparisons of timedelta objects with other.
835*cda5da8dSAndroid Build Coastguard Worker
836*cda5da8dSAndroid Build Coastguard Worker    def __eq__(self, other):
837*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, timedelta):
838*cda5da8dSAndroid Build Coastguard Worker            return self._cmp(other) == 0
839*cda5da8dSAndroid Build Coastguard Worker        else:
840*cda5da8dSAndroid Build Coastguard Worker            return NotImplemented
841*cda5da8dSAndroid Build Coastguard Worker
842*cda5da8dSAndroid Build Coastguard Worker    def __le__(self, other):
843*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, timedelta):
844*cda5da8dSAndroid Build Coastguard Worker            return self._cmp(other) <= 0
845*cda5da8dSAndroid Build Coastguard Worker        else:
846*cda5da8dSAndroid Build Coastguard Worker            return NotImplemented
847*cda5da8dSAndroid Build Coastguard Worker
848*cda5da8dSAndroid Build Coastguard Worker    def __lt__(self, other):
849*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, timedelta):
850*cda5da8dSAndroid Build Coastguard Worker            return self._cmp(other) < 0
851*cda5da8dSAndroid Build Coastguard Worker        else:
852*cda5da8dSAndroid Build Coastguard Worker            return NotImplemented
853*cda5da8dSAndroid Build Coastguard Worker
854*cda5da8dSAndroid Build Coastguard Worker    def __ge__(self, other):
855*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, timedelta):
856*cda5da8dSAndroid Build Coastguard Worker            return self._cmp(other) >= 0
857*cda5da8dSAndroid Build Coastguard Worker        else:
858*cda5da8dSAndroid Build Coastguard Worker            return NotImplemented
859*cda5da8dSAndroid Build Coastguard Worker
860*cda5da8dSAndroid Build Coastguard Worker    def __gt__(self, other):
861*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, timedelta):
862*cda5da8dSAndroid Build Coastguard Worker            return self._cmp(other) > 0
863*cda5da8dSAndroid Build Coastguard Worker        else:
864*cda5da8dSAndroid Build Coastguard Worker            return NotImplemented
865*cda5da8dSAndroid Build Coastguard Worker
866*cda5da8dSAndroid Build Coastguard Worker    def _cmp(self, other):
867*cda5da8dSAndroid Build Coastguard Worker        assert isinstance(other, timedelta)
868*cda5da8dSAndroid Build Coastguard Worker        return _cmp(self._getstate(), other._getstate())
869*cda5da8dSAndroid Build Coastguard Worker
870*cda5da8dSAndroid Build Coastguard Worker    def __hash__(self):
871*cda5da8dSAndroid Build Coastguard Worker        if self._hashcode == -1:
872*cda5da8dSAndroid Build Coastguard Worker            self._hashcode = hash(self._getstate())
873*cda5da8dSAndroid Build Coastguard Worker        return self._hashcode
874*cda5da8dSAndroid Build Coastguard Worker
875*cda5da8dSAndroid Build Coastguard Worker    def __bool__(self):
876*cda5da8dSAndroid Build Coastguard Worker        return (self._days != 0 or
877*cda5da8dSAndroid Build Coastguard Worker                self._seconds != 0 or
878*cda5da8dSAndroid Build Coastguard Worker                self._microseconds != 0)
879*cda5da8dSAndroid Build Coastguard Worker
880*cda5da8dSAndroid Build Coastguard Worker    # Pickle support.
881*cda5da8dSAndroid Build Coastguard Worker
882*cda5da8dSAndroid Build Coastguard Worker    def _getstate(self):
883*cda5da8dSAndroid Build Coastguard Worker        return (self._days, self._seconds, self._microseconds)
884*cda5da8dSAndroid Build Coastguard Worker
885*cda5da8dSAndroid Build Coastguard Worker    def __reduce__(self):
886*cda5da8dSAndroid Build Coastguard Worker        return (self.__class__, self._getstate())
887*cda5da8dSAndroid Build Coastguard Worker
888*cda5da8dSAndroid Build Coastguard Workertimedelta.min = timedelta(-999999999)
889*cda5da8dSAndroid Build Coastguard Workertimedelta.max = timedelta(days=999999999, hours=23, minutes=59, seconds=59,
890*cda5da8dSAndroid Build Coastguard Worker                          microseconds=999999)
891*cda5da8dSAndroid Build Coastguard Workertimedelta.resolution = timedelta(microseconds=1)
892*cda5da8dSAndroid Build Coastguard Worker
893*cda5da8dSAndroid Build Coastguard Workerclass date:
894*cda5da8dSAndroid Build Coastguard Worker    """Concrete date type.
895*cda5da8dSAndroid Build Coastguard Worker
896*cda5da8dSAndroid Build Coastguard Worker    Constructors:
897*cda5da8dSAndroid Build Coastguard Worker
898*cda5da8dSAndroid Build Coastguard Worker    __new__()
899*cda5da8dSAndroid Build Coastguard Worker    fromtimestamp()
900*cda5da8dSAndroid Build Coastguard Worker    today()
901*cda5da8dSAndroid Build Coastguard Worker    fromordinal()
902*cda5da8dSAndroid Build Coastguard Worker
903*cda5da8dSAndroid Build Coastguard Worker    Operators:
904*cda5da8dSAndroid Build Coastguard Worker
905*cda5da8dSAndroid Build Coastguard Worker    __repr__, __str__
906*cda5da8dSAndroid Build Coastguard Worker    __eq__, __le__, __lt__, __ge__, __gt__, __hash__
907*cda5da8dSAndroid Build Coastguard Worker    __add__, __radd__, __sub__ (add/radd only with timedelta arg)
908*cda5da8dSAndroid Build Coastguard Worker
909*cda5da8dSAndroid Build Coastguard Worker    Methods:
910*cda5da8dSAndroid Build Coastguard Worker
911*cda5da8dSAndroid Build Coastguard Worker    timetuple()
912*cda5da8dSAndroid Build Coastguard Worker    toordinal()
913*cda5da8dSAndroid Build Coastguard Worker    weekday()
914*cda5da8dSAndroid Build Coastguard Worker    isoweekday(), isocalendar(), isoformat()
915*cda5da8dSAndroid Build Coastguard Worker    ctime()
916*cda5da8dSAndroid Build Coastguard Worker    strftime()
917*cda5da8dSAndroid Build Coastguard Worker
918*cda5da8dSAndroid Build Coastguard Worker    Properties (readonly):
919*cda5da8dSAndroid Build Coastguard Worker    year, month, day
920*cda5da8dSAndroid Build Coastguard Worker    """
921*cda5da8dSAndroid Build Coastguard Worker    __slots__ = '_year', '_month', '_day', '_hashcode'
922*cda5da8dSAndroid Build Coastguard Worker
923*cda5da8dSAndroid Build Coastguard Worker    def __new__(cls, year, month=None, day=None):
924*cda5da8dSAndroid Build Coastguard Worker        """Constructor.
925*cda5da8dSAndroid Build Coastguard Worker
926*cda5da8dSAndroid Build Coastguard Worker        Arguments:
927*cda5da8dSAndroid Build Coastguard Worker
928*cda5da8dSAndroid Build Coastguard Worker        year, month, day (required, base 1)
929*cda5da8dSAndroid Build Coastguard Worker        """
930*cda5da8dSAndroid Build Coastguard Worker        if (month is None and
931*cda5da8dSAndroid Build Coastguard Worker            isinstance(year, (bytes, str)) and len(year) == 4 and
932*cda5da8dSAndroid Build Coastguard Worker            1 <= ord(year[2:3]) <= 12):
933*cda5da8dSAndroid Build Coastguard Worker            # Pickle support
934*cda5da8dSAndroid Build Coastguard Worker            if isinstance(year, str):
935*cda5da8dSAndroid Build Coastguard Worker                try:
936*cda5da8dSAndroid Build Coastguard Worker                    year = year.encode('latin1')
937*cda5da8dSAndroid Build Coastguard Worker                except UnicodeEncodeError:
938*cda5da8dSAndroid Build Coastguard Worker                    # More informative error message.
939*cda5da8dSAndroid Build Coastguard Worker                    raise ValueError(
940*cda5da8dSAndroid Build Coastguard Worker                        "Failed to encode latin1 string when unpickling "
941*cda5da8dSAndroid Build Coastguard Worker                        "a date object. "
942*cda5da8dSAndroid Build Coastguard Worker                        "pickle.load(data, encoding='latin1') is assumed.")
943*cda5da8dSAndroid Build Coastguard Worker            self = object.__new__(cls)
944*cda5da8dSAndroid Build Coastguard Worker            self.__setstate(year)
945*cda5da8dSAndroid Build Coastguard Worker            self._hashcode = -1
946*cda5da8dSAndroid Build Coastguard Worker            return self
947*cda5da8dSAndroid Build Coastguard Worker        year, month, day = _check_date_fields(year, month, day)
948*cda5da8dSAndroid Build Coastguard Worker        self = object.__new__(cls)
949*cda5da8dSAndroid Build Coastguard Worker        self._year = year
950*cda5da8dSAndroid Build Coastguard Worker        self._month = month
951*cda5da8dSAndroid Build Coastguard Worker        self._day = day
952*cda5da8dSAndroid Build Coastguard Worker        self._hashcode = -1
953*cda5da8dSAndroid Build Coastguard Worker        return self
954*cda5da8dSAndroid Build Coastguard Worker
955*cda5da8dSAndroid Build Coastguard Worker    # Additional constructors
956*cda5da8dSAndroid Build Coastguard Worker
957*cda5da8dSAndroid Build Coastguard Worker    @classmethod
958*cda5da8dSAndroid Build Coastguard Worker    def fromtimestamp(cls, t):
959*cda5da8dSAndroid Build Coastguard Worker        "Construct a date from a POSIX timestamp (like time.time())."
960*cda5da8dSAndroid Build Coastguard Worker        y, m, d, hh, mm, ss, weekday, jday, dst = _time.localtime(t)
961*cda5da8dSAndroid Build Coastguard Worker        return cls(y, m, d)
962*cda5da8dSAndroid Build Coastguard Worker
963*cda5da8dSAndroid Build Coastguard Worker    @classmethod
964*cda5da8dSAndroid Build Coastguard Worker    def today(cls):
965*cda5da8dSAndroid Build Coastguard Worker        "Construct a date from time.time()."
966*cda5da8dSAndroid Build Coastguard Worker        t = _time.time()
967*cda5da8dSAndroid Build Coastguard Worker        return cls.fromtimestamp(t)
968*cda5da8dSAndroid Build Coastguard Worker
969*cda5da8dSAndroid Build Coastguard Worker    @classmethod
970*cda5da8dSAndroid Build Coastguard Worker    def fromordinal(cls, n):
971*cda5da8dSAndroid Build Coastguard Worker        """Construct a date from a proleptic Gregorian ordinal.
972*cda5da8dSAndroid Build Coastguard Worker
973*cda5da8dSAndroid Build Coastguard Worker        January 1 of year 1 is day 1.  Only the year, month and day are
974*cda5da8dSAndroid Build Coastguard Worker        non-zero in the result.
975*cda5da8dSAndroid Build Coastguard Worker        """
976*cda5da8dSAndroid Build Coastguard Worker        y, m, d = _ord2ymd(n)
977*cda5da8dSAndroid Build Coastguard Worker        return cls(y, m, d)
978*cda5da8dSAndroid Build Coastguard Worker
979*cda5da8dSAndroid Build Coastguard Worker    @classmethod
980*cda5da8dSAndroid Build Coastguard Worker    def fromisoformat(cls, date_string):
981*cda5da8dSAndroid Build Coastguard Worker        """Construct a date from a string in ISO 8601 format."""
982*cda5da8dSAndroid Build Coastguard Worker        if not isinstance(date_string, str):
983*cda5da8dSAndroid Build Coastguard Worker            raise TypeError('fromisoformat: argument must be str')
984*cda5da8dSAndroid Build Coastguard Worker
985*cda5da8dSAndroid Build Coastguard Worker        if len(date_string) not in (7, 8, 10):
986*cda5da8dSAndroid Build Coastguard Worker            raise ValueError(f'Invalid isoformat string: {date_string!r}')
987*cda5da8dSAndroid Build Coastguard Worker
988*cda5da8dSAndroid Build Coastguard Worker        try:
989*cda5da8dSAndroid Build Coastguard Worker            return cls(*_parse_isoformat_date(date_string))
990*cda5da8dSAndroid Build Coastguard Worker        except Exception:
991*cda5da8dSAndroid Build Coastguard Worker            raise ValueError(f'Invalid isoformat string: {date_string!r}')
992*cda5da8dSAndroid Build Coastguard Worker
993*cda5da8dSAndroid Build Coastguard Worker    @classmethod
994*cda5da8dSAndroid Build Coastguard Worker    def fromisocalendar(cls, year, week, day):
995*cda5da8dSAndroid Build Coastguard Worker        """Construct a date from the ISO year, week number and weekday.
996*cda5da8dSAndroid Build Coastguard Worker
997*cda5da8dSAndroid Build Coastguard Worker        This is the inverse of the date.isocalendar() function"""
998*cda5da8dSAndroid Build Coastguard Worker        return cls(*_isoweek_to_gregorian(year, week, day))
999*cda5da8dSAndroid Build Coastguard Worker
1000*cda5da8dSAndroid Build Coastguard Worker    # Conversions to string
1001*cda5da8dSAndroid Build Coastguard Worker
1002*cda5da8dSAndroid Build Coastguard Worker    def __repr__(self):
1003*cda5da8dSAndroid Build Coastguard Worker        """Convert to formal string, for repr().
1004*cda5da8dSAndroid Build Coastguard Worker
1005*cda5da8dSAndroid Build Coastguard Worker        >>> dt = datetime(2010, 1, 1)
1006*cda5da8dSAndroid Build Coastguard Worker        >>> repr(dt)
1007*cda5da8dSAndroid Build Coastguard Worker        'datetime.datetime(2010, 1, 1, 0, 0)'
1008*cda5da8dSAndroid Build Coastguard Worker
1009*cda5da8dSAndroid Build Coastguard Worker        >>> dt = datetime(2010, 1, 1, tzinfo=timezone.utc)
1010*cda5da8dSAndroid Build Coastguard Worker        >>> repr(dt)
1011*cda5da8dSAndroid Build Coastguard Worker        'datetime.datetime(2010, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)'
1012*cda5da8dSAndroid Build Coastguard Worker        """
1013*cda5da8dSAndroid Build Coastguard Worker        return "%s.%s(%d, %d, %d)" % (self.__class__.__module__,
1014*cda5da8dSAndroid Build Coastguard Worker                                      self.__class__.__qualname__,
1015*cda5da8dSAndroid Build Coastguard Worker                                      self._year,
1016*cda5da8dSAndroid Build Coastguard Worker                                      self._month,
1017*cda5da8dSAndroid Build Coastguard Worker                                      self._day)
1018*cda5da8dSAndroid Build Coastguard Worker    # XXX These shouldn't depend on time.localtime(), because that
1019*cda5da8dSAndroid Build Coastguard Worker    # clips the usable dates to [1970 .. 2038).  At least ctime() is
1020*cda5da8dSAndroid Build Coastguard Worker    # easily done without using strftime() -- that's better too because
1021*cda5da8dSAndroid Build Coastguard Worker    # strftime("%c", ...) is locale specific.
1022*cda5da8dSAndroid Build Coastguard Worker
1023*cda5da8dSAndroid Build Coastguard Worker
1024*cda5da8dSAndroid Build Coastguard Worker    def ctime(self):
1025*cda5da8dSAndroid Build Coastguard Worker        "Return ctime() style string."
1026*cda5da8dSAndroid Build Coastguard Worker        weekday = self.toordinal() % 7 or 7
1027*cda5da8dSAndroid Build Coastguard Worker        return "%s %s %2d 00:00:00 %04d" % (
1028*cda5da8dSAndroid Build Coastguard Worker            _DAYNAMES[weekday],
1029*cda5da8dSAndroid Build Coastguard Worker            _MONTHNAMES[self._month],
1030*cda5da8dSAndroid Build Coastguard Worker            self._day, self._year)
1031*cda5da8dSAndroid Build Coastguard Worker
1032*cda5da8dSAndroid Build Coastguard Worker    def strftime(self, fmt):
1033*cda5da8dSAndroid Build Coastguard Worker        """
1034*cda5da8dSAndroid Build Coastguard Worker        Format using strftime().
1035*cda5da8dSAndroid Build Coastguard Worker
1036*cda5da8dSAndroid Build Coastguard Worker        Example: "%d/%m/%Y, %H:%M:%S"
1037*cda5da8dSAndroid Build Coastguard Worker        """
1038*cda5da8dSAndroid Build Coastguard Worker        return _wrap_strftime(self, fmt, self.timetuple())
1039*cda5da8dSAndroid Build Coastguard Worker
1040*cda5da8dSAndroid Build Coastguard Worker    def __format__(self, fmt):
1041*cda5da8dSAndroid Build Coastguard Worker        if not isinstance(fmt, str):
1042*cda5da8dSAndroid Build Coastguard Worker            raise TypeError("must be str, not %s" % type(fmt).__name__)
1043*cda5da8dSAndroid Build Coastguard Worker        if len(fmt) != 0:
1044*cda5da8dSAndroid Build Coastguard Worker            return self.strftime(fmt)
1045*cda5da8dSAndroid Build Coastguard Worker        return str(self)
1046*cda5da8dSAndroid Build Coastguard Worker
1047*cda5da8dSAndroid Build Coastguard Worker    def isoformat(self):
1048*cda5da8dSAndroid Build Coastguard Worker        """Return the date formatted according to ISO.
1049*cda5da8dSAndroid Build Coastguard Worker
1050*cda5da8dSAndroid Build Coastguard Worker        This is 'YYYY-MM-DD'.
1051*cda5da8dSAndroid Build Coastguard Worker
1052*cda5da8dSAndroid Build Coastguard Worker        References:
1053*cda5da8dSAndroid Build Coastguard Worker        - http://www.w3.org/TR/NOTE-datetime
1054*cda5da8dSAndroid Build Coastguard Worker        - http://www.cl.cam.ac.uk/~mgk25/iso-time.html
1055*cda5da8dSAndroid Build Coastguard Worker        """
1056*cda5da8dSAndroid Build Coastguard Worker        return "%04d-%02d-%02d" % (self._year, self._month, self._day)
1057*cda5da8dSAndroid Build Coastguard Worker
1058*cda5da8dSAndroid Build Coastguard Worker    __str__ = isoformat
1059*cda5da8dSAndroid Build Coastguard Worker
1060*cda5da8dSAndroid Build Coastguard Worker    # Read-only field accessors
1061*cda5da8dSAndroid Build Coastguard Worker    @property
1062*cda5da8dSAndroid Build Coastguard Worker    def year(self):
1063*cda5da8dSAndroid Build Coastguard Worker        """year (1-9999)"""
1064*cda5da8dSAndroid Build Coastguard Worker        return self._year
1065*cda5da8dSAndroid Build Coastguard Worker
1066*cda5da8dSAndroid Build Coastguard Worker    @property
1067*cda5da8dSAndroid Build Coastguard Worker    def month(self):
1068*cda5da8dSAndroid Build Coastguard Worker        """month (1-12)"""
1069*cda5da8dSAndroid Build Coastguard Worker        return self._month
1070*cda5da8dSAndroid Build Coastguard Worker
1071*cda5da8dSAndroid Build Coastguard Worker    @property
1072*cda5da8dSAndroid Build Coastguard Worker    def day(self):
1073*cda5da8dSAndroid Build Coastguard Worker        """day (1-31)"""
1074*cda5da8dSAndroid Build Coastguard Worker        return self._day
1075*cda5da8dSAndroid Build Coastguard Worker
1076*cda5da8dSAndroid Build Coastguard Worker    # Standard conversions, __eq__, __le__, __lt__, __ge__, __gt__,
1077*cda5da8dSAndroid Build Coastguard Worker    # __hash__ (and helpers)
1078*cda5da8dSAndroid Build Coastguard Worker
1079*cda5da8dSAndroid Build Coastguard Worker    def timetuple(self):
1080*cda5da8dSAndroid Build Coastguard Worker        "Return local time tuple compatible with time.localtime()."
1081*cda5da8dSAndroid Build Coastguard Worker        return _build_struct_time(self._year, self._month, self._day,
1082*cda5da8dSAndroid Build Coastguard Worker                                  0, 0, 0, -1)
1083*cda5da8dSAndroid Build Coastguard Worker
1084*cda5da8dSAndroid Build Coastguard Worker    def toordinal(self):
1085*cda5da8dSAndroid Build Coastguard Worker        """Return proleptic Gregorian ordinal for the year, month and day.
1086*cda5da8dSAndroid Build Coastguard Worker
1087*cda5da8dSAndroid Build Coastguard Worker        January 1 of year 1 is day 1.  Only the year, month and day values
1088*cda5da8dSAndroid Build Coastguard Worker        contribute to the result.
1089*cda5da8dSAndroid Build Coastguard Worker        """
1090*cda5da8dSAndroid Build Coastguard Worker        return _ymd2ord(self._year, self._month, self._day)
1091*cda5da8dSAndroid Build Coastguard Worker
1092*cda5da8dSAndroid Build Coastguard Worker    def replace(self, year=None, month=None, day=None):
1093*cda5da8dSAndroid Build Coastguard Worker        """Return a new date with new values for the specified fields."""
1094*cda5da8dSAndroid Build Coastguard Worker        if year is None:
1095*cda5da8dSAndroid Build Coastguard Worker            year = self._year
1096*cda5da8dSAndroid Build Coastguard Worker        if month is None:
1097*cda5da8dSAndroid Build Coastguard Worker            month = self._month
1098*cda5da8dSAndroid Build Coastguard Worker        if day is None:
1099*cda5da8dSAndroid Build Coastguard Worker            day = self._day
1100*cda5da8dSAndroid Build Coastguard Worker        return type(self)(year, month, day)
1101*cda5da8dSAndroid Build Coastguard Worker
1102*cda5da8dSAndroid Build Coastguard Worker    # Comparisons of date objects with other.
1103*cda5da8dSAndroid Build Coastguard Worker
1104*cda5da8dSAndroid Build Coastguard Worker    def __eq__(self, other):
1105*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, date):
1106*cda5da8dSAndroid Build Coastguard Worker            return self._cmp(other) == 0
1107*cda5da8dSAndroid Build Coastguard Worker        return NotImplemented
1108*cda5da8dSAndroid Build Coastguard Worker
1109*cda5da8dSAndroid Build Coastguard Worker    def __le__(self, other):
1110*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, date):
1111*cda5da8dSAndroid Build Coastguard Worker            return self._cmp(other) <= 0
1112*cda5da8dSAndroid Build Coastguard Worker        return NotImplemented
1113*cda5da8dSAndroid Build Coastguard Worker
1114*cda5da8dSAndroid Build Coastguard Worker    def __lt__(self, other):
1115*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, date):
1116*cda5da8dSAndroid Build Coastguard Worker            return self._cmp(other) < 0
1117*cda5da8dSAndroid Build Coastguard Worker        return NotImplemented
1118*cda5da8dSAndroid Build Coastguard Worker
1119*cda5da8dSAndroid Build Coastguard Worker    def __ge__(self, other):
1120*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, date):
1121*cda5da8dSAndroid Build Coastguard Worker            return self._cmp(other) >= 0
1122*cda5da8dSAndroid Build Coastguard Worker        return NotImplemented
1123*cda5da8dSAndroid Build Coastguard Worker
1124*cda5da8dSAndroid Build Coastguard Worker    def __gt__(self, other):
1125*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, date):
1126*cda5da8dSAndroid Build Coastguard Worker            return self._cmp(other) > 0
1127*cda5da8dSAndroid Build Coastguard Worker        return NotImplemented
1128*cda5da8dSAndroid Build Coastguard Worker
1129*cda5da8dSAndroid Build Coastguard Worker    def _cmp(self, other):
1130*cda5da8dSAndroid Build Coastguard Worker        assert isinstance(other, date)
1131*cda5da8dSAndroid Build Coastguard Worker        y, m, d = self._year, self._month, self._day
1132*cda5da8dSAndroid Build Coastguard Worker        y2, m2, d2 = other._year, other._month, other._day
1133*cda5da8dSAndroid Build Coastguard Worker        return _cmp((y, m, d), (y2, m2, d2))
1134*cda5da8dSAndroid Build Coastguard Worker
1135*cda5da8dSAndroid Build Coastguard Worker    def __hash__(self):
1136*cda5da8dSAndroid Build Coastguard Worker        "Hash."
1137*cda5da8dSAndroid Build Coastguard Worker        if self._hashcode == -1:
1138*cda5da8dSAndroid Build Coastguard Worker            self._hashcode = hash(self._getstate())
1139*cda5da8dSAndroid Build Coastguard Worker        return self._hashcode
1140*cda5da8dSAndroid Build Coastguard Worker
1141*cda5da8dSAndroid Build Coastguard Worker    # Computations
1142*cda5da8dSAndroid Build Coastguard Worker
1143*cda5da8dSAndroid Build Coastguard Worker    def __add__(self, other):
1144*cda5da8dSAndroid Build Coastguard Worker        "Add a date to a timedelta."
1145*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, timedelta):
1146*cda5da8dSAndroid Build Coastguard Worker            o = self.toordinal() + other.days
1147*cda5da8dSAndroid Build Coastguard Worker            if 0 < o <= _MAXORDINAL:
1148*cda5da8dSAndroid Build Coastguard Worker                return type(self).fromordinal(o)
1149*cda5da8dSAndroid Build Coastguard Worker            raise OverflowError("result out of range")
1150*cda5da8dSAndroid Build Coastguard Worker        return NotImplemented
1151*cda5da8dSAndroid Build Coastguard Worker
1152*cda5da8dSAndroid Build Coastguard Worker    __radd__ = __add__
1153*cda5da8dSAndroid Build Coastguard Worker
1154*cda5da8dSAndroid Build Coastguard Worker    def __sub__(self, other):
1155*cda5da8dSAndroid Build Coastguard Worker        """Subtract two dates, or a date and a timedelta."""
1156*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, timedelta):
1157*cda5da8dSAndroid Build Coastguard Worker            return self + timedelta(-other.days)
1158*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, date):
1159*cda5da8dSAndroid Build Coastguard Worker            days1 = self.toordinal()
1160*cda5da8dSAndroid Build Coastguard Worker            days2 = other.toordinal()
1161*cda5da8dSAndroid Build Coastguard Worker            return timedelta(days1 - days2)
1162*cda5da8dSAndroid Build Coastguard Worker        return NotImplemented
1163*cda5da8dSAndroid Build Coastguard Worker
1164*cda5da8dSAndroid Build Coastguard Worker    def weekday(self):
1165*cda5da8dSAndroid Build Coastguard Worker        "Return day of the week, where Monday == 0 ... Sunday == 6."
1166*cda5da8dSAndroid Build Coastguard Worker        return (self.toordinal() + 6) % 7
1167*cda5da8dSAndroid Build Coastguard Worker
1168*cda5da8dSAndroid Build Coastguard Worker    # Day-of-the-week and week-of-the-year, according to ISO
1169*cda5da8dSAndroid Build Coastguard Worker
1170*cda5da8dSAndroid Build Coastguard Worker    def isoweekday(self):
1171*cda5da8dSAndroid Build Coastguard Worker        "Return day of the week, where Monday == 1 ... Sunday == 7."
1172*cda5da8dSAndroid Build Coastguard Worker        # 1-Jan-0001 is a Monday
1173*cda5da8dSAndroid Build Coastguard Worker        return self.toordinal() % 7 or 7
1174*cda5da8dSAndroid Build Coastguard Worker
1175*cda5da8dSAndroid Build Coastguard Worker    def isocalendar(self):
1176*cda5da8dSAndroid Build Coastguard Worker        """Return a named tuple containing ISO year, week number, and weekday.
1177*cda5da8dSAndroid Build Coastguard Worker
1178*cda5da8dSAndroid Build Coastguard Worker        The first ISO week of the year is the (Mon-Sun) week
1179*cda5da8dSAndroid Build Coastguard Worker        containing the year's first Thursday; everything else derives
1180*cda5da8dSAndroid Build Coastguard Worker        from that.
1181*cda5da8dSAndroid Build Coastguard Worker
1182*cda5da8dSAndroid Build Coastguard Worker        The first week is 1; Monday is 1 ... Sunday is 7.
1183*cda5da8dSAndroid Build Coastguard Worker
1184*cda5da8dSAndroid Build Coastguard Worker        ISO calendar algorithm taken from
1185*cda5da8dSAndroid Build Coastguard Worker        http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm
1186*cda5da8dSAndroid Build Coastguard Worker        (used with permission)
1187*cda5da8dSAndroid Build Coastguard Worker        """
1188*cda5da8dSAndroid Build Coastguard Worker        year = self._year
1189*cda5da8dSAndroid Build Coastguard Worker        week1monday = _isoweek1monday(year)
1190*cda5da8dSAndroid Build Coastguard Worker        today = _ymd2ord(self._year, self._month, self._day)
1191*cda5da8dSAndroid Build Coastguard Worker        # Internally, week and day have origin 0
1192*cda5da8dSAndroid Build Coastguard Worker        week, day = divmod(today - week1monday, 7)
1193*cda5da8dSAndroid Build Coastguard Worker        if week < 0:
1194*cda5da8dSAndroid Build Coastguard Worker            year -= 1
1195*cda5da8dSAndroid Build Coastguard Worker            week1monday = _isoweek1monday(year)
1196*cda5da8dSAndroid Build Coastguard Worker            week, day = divmod(today - week1monday, 7)
1197*cda5da8dSAndroid Build Coastguard Worker        elif week >= 52:
1198*cda5da8dSAndroid Build Coastguard Worker            if today >= _isoweek1monday(year+1):
1199*cda5da8dSAndroid Build Coastguard Worker                year += 1
1200*cda5da8dSAndroid Build Coastguard Worker                week = 0
1201*cda5da8dSAndroid Build Coastguard Worker        return _IsoCalendarDate(year, week+1, day+1)
1202*cda5da8dSAndroid Build Coastguard Worker
1203*cda5da8dSAndroid Build Coastguard Worker    # Pickle support.
1204*cda5da8dSAndroid Build Coastguard Worker
1205*cda5da8dSAndroid Build Coastguard Worker    def _getstate(self):
1206*cda5da8dSAndroid Build Coastguard Worker        yhi, ylo = divmod(self._year, 256)
1207*cda5da8dSAndroid Build Coastguard Worker        return bytes([yhi, ylo, self._month, self._day]),
1208*cda5da8dSAndroid Build Coastguard Worker
1209*cda5da8dSAndroid Build Coastguard Worker    def __setstate(self, string):
1210*cda5da8dSAndroid Build Coastguard Worker        yhi, ylo, self._month, self._day = string
1211*cda5da8dSAndroid Build Coastguard Worker        self._year = yhi * 256 + ylo
1212*cda5da8dSAndroid Build Coastguard Worker
1213*cda5da8dSAndroid Build Coastguard Worker    def __reduce__(self):
1214*cda5da8dSAndroid Build Coastguard Worker        return (self.__class__, self._getstate())
1215*cda5da8dSAndroid Build Coastguard Worker
1216*cda5da8dSAndroid Build Coastguard Worker_date_class = date  # so functions w/ args named "date" can get at the class
1217*cda5da8dSAndroid Build Coastguard Worker
1218*cda5da8dSAndroid Build Coastguard Workerdate.min = date(1, 1, 1)
1219*cda5da8dSAndroid Build Coastguard Workerdate.max = date(9999, 12, 31)
1220*cda5da8dSAndroid Build Coastguard Workerdate.resolution = timedelta(days=1)
1221*cda5da8dSAndroid Build Coastguard Worker
1222*cda5da8dSAndroid Build Coastguard Worker
1223*cda5da8dSAndroid Build Coastguard Workerclass tzinfo:
1224*cda5da8dSAndroid Build Coastguard Worker    """Abstract base class for time zone info classes.
1225*cda5da8dSAndroid Build Coastguard Worker
1226*cda5da8dSAndroid Build Coastguard Worker    Subclasses must override the name(), utcoffset() and dst() methods.
1227*cda5da8dSAndroid Build Coastguard Worker    """
1228*cda5da8dSAndroid Build Coastguard Worker    __slots__ = ()
1229*cda5da8dSAndroid Build Coastguard Worker
1230*cda5da8dSAndroid Build Coastguard Worker    def tzname(self, dt):
1231*cda5da8dSAndroid Build Coastguard Worker        "datetime -> string name of time zone."
1232*cda5da8dSAndroid Build Coastguard Worker        raise NotImplementedError("tzinfo subclass must override tzname()")
1233*cda5da8dSAndroid Build Coastguard Worker
1234*cda5da8dSAndroid Build Coastguard Worker    def utcoffset(self, dt):
1235*cda5da8dSAndroid Build Coastguard Worker        "datetime -> timedelta, positive for east of UTC, negative for west of UTC"
1236*cda5da8dSAndroid Build Coastguard Worker        raise NotImplementedError("tzinfo subclass must override utcoffset()")
1237*cda5da8dSAndroid Build Coastguard Worker
1238*cda5da8dSAndroid Build Coastguard Worker    def dst(self, dt):
1239*cda5da8dSAndroid Build Coastguard Worker        """datetime -> DST offset as timedelta, positive for east of UTC.
1240*cda5da8dSAndroid Build Coastguard Worker
1241*cda5da8dSAndroid Build Coastguard Worker        Return 0 if DST not in effect.  utcoffset() must include the DST
1242*cda5da8dSAndroid Build Coastguard Worker        offset.
1243*cda5da8dSAndroid Build Coastguard Worker        """
1244*cda5da8dSAndroid Build Coastguard Worker        raise NotImplementedError("tzinfo subclass must override dst()")
1245*cda5da8dSAndroid Build Coastguard Worker
1246*cda5da8dSAndroid Build Coastguard Worker    def fromutc(self, dt):
1247*cda5da8dSAndroid Build Coastguard Worker        "datetime in UTC -> datetime in local time."
1248*cda5da8dSAndroid Build Coastguard Worker
1249*cda5da8dSAndroid Build Coastguard Worker        if not isinstance(dt, datetime):
1250*cda5da8dSAndroid Build Coastguard Worker            raise TypeError("fromutc() requires a datetime argument")
1251*cda5da8dSAndroid Build Coastguard Worker        if dt.tzinfo is not self:
1252*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("dt.tzinfo is not self")
1253*cda5da8dSAndroid Build Coastguard Worker
1254*cda5da8dSAndroid Build Coastguard Worker        dtoff = dt.utcoffset()
1255*cda5da8dSAndroid Build Coastguard Worker        if dtoff is None:
1256*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("fromutc() requires a non-None utcoffset() "
1257*cda5da8dSAndroid Build Coastguard Worker                             "result")
1258*cda5da8dSAndroid Build Coastguard Worker
1259*cda5da8dSAndroid Build Coastguard Worker        # See the long comment block at the end of this file for an
1260*cda5da8dSAndroid Build Coastguard Worker        # explanation of this algorithm.
1261*cda5da8dSAndroid Build Coastguard Worker        dtdst = dt.dst()
1262*cda5da8dSAndroid Build Coastguard Worker        if dtdst is None:
1263*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("fromutc() requires a non-None dst() result")
1264*cda5da8dSAndroid Build Coastguard Worker        delta = dtoff - dtdst
1265*cda5da8dSAndroid Build Coastguard Worker        if delta:
1266*cda5da8dSAndroid Build Coastguard Worker            dt += delta
1267*cda5da8dSAndroid Build Coastguard Worker            dtdst = dt.dst()
1268*cda5da8dSAndroid Build Coastguard Worker            if dtdst is None:
1269*cda5da8dSAndroid Build Coastguard Worker                raise ValueError("fromutc(): dt.dst gave inconsistent "
1270*cda5da8dSAndroid Build Coastguard Worker                                 "results; cannot convert")
1271*cda5da8dSAndroid Build Coastguard Worker        return dt + dtdst
1272*cda5da8dSAndroid Build Coastguard Worker
1273*cda5da8dSAndroid Build Coastguard Worker    # Pickle support.
1274*cda5da8dSAndroid Build Coastguard Worker
1275*cda5da8dSAndroid Build Coastguard Worker    def __reduce__(self):
1276*cda5da8dSAndroid Build Coastguard Worker        getinitargs = getattr(self, "__getinitargs__", None)
1277*cda5da8dSAndroid Build Coastguard Worker        if getinitargs:
1278*cda5da8dSAndroid Build Coastguard Worker            args = getinitargs()
1279*cda5da8dSAndroid Build Coastguard Worker        else:
1280*cda5da8dSAndroid Build Coastguard Worker            args = ()
1281*cda5da8dSAndroid Build Coastguard Worker        return (self.__class__, args, self.__getstate__())
1282*cda5da8dSAndroid Build Coastguard Worker
1283*cda5da8dSAndroid Build Coastguard Worker
1284*cda5da8dSAndroid Build Coastguard Workerclass IsoCalendarDate(tuple):
1285*cda5da8dSAndroid Build Coastguard Worker
1286*cda5da8dSAndroid Build Coastguard Worker    def __new__(cls, year, week, weekday, /):
1287*cda5da8dSAndroid Build Coastguard Worker        return super().__new__(cls, (year, week, weekday))
1288*cda5da8dSAndroid Build Coastguard Worker
1289*cda5da8dSAndroid Build Coastguard Worker    @property
1290*cda5da8dSAndroid Build Coastguard Worker    def year(self):
1291*cda5da8dSAndroid Build Coastguard Worker        return self[0]
1292*cda5da8dSAndroid Build Coastguard Worker
1293*cda5da8dSAndroid Build Coastguard Worker    @property
1294*cda5da8dSAndroid Build Coastguard Worker    def week(self):
1295*cda5da8dSAndroid Build Coastguard Worker        return self[1]
1296*cda5da8dSAndroid Build Coastguard Worker
1297*cda5da8dSAndroid Build Coastguard Worker    @property
1298*cda5da8dSAndroid Build Coastguard Worker    def weekday(self):
1299*cda5da8dSAndroid Build Coastguard Worker        return self[2]
1300*cda5da8dSAndroid Build Coastguard Worker
1301*cda5da8dSAndroid Build Coastguard Worker    def __reduce__(self):
1302*cda5da8dSAndroid Build Coastguard Worker        # This code is intended to pickle the object without making the
1303*cda5da8dSAndroid Build Coastguard Worker        # class public. See https://bugs.python.org/msg352381
1304*cda5da8dSAndroid Build Coastguard Worker        return (tuple, (tuple(self),))
1305*cda5da8dSAndroid Build Coastguard Worker
1306*cda5da8dSAndroid Build Coastguard Worker    def __repr__(self):
1307*cda5da8dSAndroid Build Coastguard Worker        return (f'{self.__class__.__name__}'
1308*cda5da8dSAndroid Build Coastguard Worker                f'(year={self[0]}, week={self[1]}, weekday={self[2]})')
1309*cda5da8dSAndroid Build Coastguard Worker
1310*cda5da8dSAndroid Build Coastguard Worker
1311*cda5da8dSAndroid Build Coastguard Worker_IsoCalendarDate = IsoCalendarDate
1312*cda5da8dSAndroid Build Coastguard Workerdel IsoCalendarDate
1313*cda5da8dSAndroid Build Coastguard Worker_tzinfo_class = tzinfo
1314*cda5da8dSAndroid Build Coastguard Worker
1315*cda5da8dSAndroid Build Coastguard Workerclass time:
1316*cda5da8dSAndroid Build Coastguard Worker    """Time with time zone.
1317*cda5da8dSAndroid Build Coastguard Worker
1318*cda5da8dSAndroid Build Coastguard Worker    Constructors:
1319*cda5da8dSAndroid Build Coastguard Worker
1320*cda5da8dSAndroid Build Coastguard Worker    __new__()
1321*cda5da8dSAndroid Build Coastguard Worker
1322*cda5da8dSAndroid Build Coastguard Worker    Operators:
1323*cda5da8dSAndroid Build Coastguard Worker
1324*cda5da8dSAndroid Build Coastguard Worker    __repr__, __str__
1325*cda5da8dSAndroid Build Coastguard Worker    __eq__, __le__, __lt__, __ge__, __gt__, __hash__
1326*cda5da8dSAndroid Build Coastguard Worker
1327*cda5da8dSAndroid Build Coastguard Worker    Methods:
1328*cda5da8dSAndroid Build Coastguard Worker
1329*cda5da8dSAndroid Build Coastguard Worker    strftime()
1330*cda5da8dSAndroid Build Coastguard Worker    isoformat()
1331*cda5da8dSAndroid Build Coastguard Worker    utcoffset()
1332*cda5da8dSAndroid Build Coastguard Worker    tzname()
1333*cda5da8dSAndroid Build Coastguard Worker    dst()
1334*cda5da8dSAndroid Build Coastguard Worker
1335*cda5da8dSAndroid Build Coastguard Worker    Properties (readonly):
1336*cda5da8dSAndroid Build Coastguard Worker    hour, minute, second, microsecond, tzinfo, fold
1337*cda5da8dSAndroid Build Coastguard Worker    """
1338*cda5da8dSAndroid Build Coastguard Worker    __slots__ = '_hour', '_minute', '_second', '_microsecond', '_tzinfo', '_hashcode', '_fold'
1339*cda5da8dSAndroid Build Coastguard Worker
1340*cda5da8dSAndroid Build Coastguard Worker    def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0):
1341*cda5da8dSAndroid Build Coastguard Worker        """Constructor.
1342*cda5da8dSAndroid Build Coastguard Worker
1343*cda5da8dSAndroid Build Coastguard Worker        Arguments:
1344*cda5da8dSAndroid Build Coastguard Worker
1345*cda5da8dSAndroid Build Coastguard Worker        hour, minute (required)
1346*cda5da8dSAndroid Build Coastguard Worker        second, microsecond (default to zero)
1347*cda5da8dSAndroid Build Coastguard Worker        tzinfo (default to None)
1348*cda5da8dSAndroid Build Coastguard Worker        fold (keyword only, default to zero)
1349*cda5da8dSAndroid Build Coastguard Worker        """
1350*cda5da8dSAndroid Build Coastguard Worker        if (isinstance(hour, (bytes, str)) and len(hour) == 6 and
1351*cda5da8dSAndroid Build Coastguard Worker            ord(hour[0:1])&0x7F < 24):
1352*cda5da8dSAndroid Build Coastguard Worker            # Pickle support
1353*cda5da8dSAndroid Build Coastguard Worker            if isinstance(hour, str):
1354*cda5da8dSAndroid Build Coastguard Worker                try:
1355*cda5da8dSAndroid Build Coastguard Worker                    hour = hour.encode('latin1')
1356*cda5da8dSAndroid Build Coastguard Worker                except UnicodeEncodeError:
1357*cda5da8dSAndroid Build Coastguard Worker                    # More informative error message.
1358*cda5da8dSAndroid Build Coastguard Worker                    raise ValueError(
1359*cda5da8dSAndroid Build Coastguard Worker                        "Failed to encode latin1 string when unpickling "
1360*cda5da8dSAndroid Build Coastguard Worker                        "a time object. "
1361*cda5da8dSAndroid Build Coastguard Worker                        "pickle.load(data, encoding='latin1') is assumed.")
1362*cda5da8dSAndroid Build Coastguard Worker            self = object.__new__(cls)
1363*cda5da8dSAndroid Build Coastguard Worker            self.__setstate(hour, minute or None)
1364*cda5da8dSAndroid Build Coastguard Worker            self._hashcode = -1
1365*cda5da8dSAndroid Build Coastguard Worker            return self
1366*cda5da8dSAndroid Build Coastguard Worker        hour, minute, second, microsecond, fold = _check_time_fields(
1367*cda5da8dSAndroid Build Coastguard Worker            hour, minute, second, microsecond, fold)
1368*cda5da8dSAndroid Build Coastguard Worker        _check_tzinfo_arg(tzinfo)
1369*cda5da8dSAndroid Build Coastguard Worker        self = object.__new__(cls)
1370*cda5da8dSAndroid Build Coastguard Worker        self._hour = hour
1371*cda5da8dSAndroid Build Coastguard Worker        self._minute = minute
1372*cda5da8dSAndroid Build Coastguard Worker        self._second = second
1373*cda5da8dSAndroid Build Coastguard Worker        self._microsecond = microsecond
1374*cda5da8dSAndroid Build Coastguard Worker        self._tzinfo = tzinfo
1375*cda5da8dSAndroid Build Coastguard Worker        self._hashcode = -1
1376*cda5da8dSAndroid Build Coastguard Worker        self._fold = fold
1377*cda5da8dSAndroid Build Coastguard Worker        return self
1378*cda5da8dSAndroid Build Coastguard Worker
1379*cda5da8dSAndroid Build Coastguard Worker    # Read-only field accessors
1380*cda5da8dSAndroid Build Coastguard Worker    @property
1381*cda5da8dSAndroid Build Coastguard Worker    def hour(self):
1382*cda5da8dSAndroid Build Coastguard Worker        """hour (0-23)"""
1383*cda5da8dSAndroid Build Coastguard Worker        return self._hour
1384*cda5da8dSAndroid Build Coastguard Worker
1385*cda5da8dSAndroid Build Coastguard Worker    @property
1386*cda5da8dSAndroid Build Coastguard Worker    def minute(self):
1387*cda5da8dSAndroid Build Coastguard Worker        """minute (0-59)"""
1388*cda5da8dSAndroid Build Coastguard Worker        return self._minute
1389*cda5da8dSAndroid Build Coastguard Worker
1390*cda5da8dSAndroid Build Coastguard Worker    @property
1391*cda5da8dSAndroid Build Coastguard Worker    def second(self):
1392*cda5da8dSAndroid Build Coastguard Worker        """second (0-59)"""
1393*cda5da8dSAndroid Build Coastguard Worker        return self._second
1394*cda5da8dSAndroid Build Coastguard Worker
1395*cda5da8dSAndroid Build Coastguard Worker    @property
1396*cda5da8dSAndroid Build Coastguard Worker    def microsecond(self):
1397*cda5da8dSAndroid Build Coastguard Worker        """microsecond (0-999999)"""
1398*cda5da8dSAndroid Build Coastguard Worker        return self._microsecond
1399*cda5da8dSAndroid Build Coastguard Worker
1400*cda5da8dSAndroid Build Coastguard Worker    @property
1401*cda5da8dSAndroid Build Coastguard Worker    def tzinfo(self):
1402*cda5da8dSAndroid Build Coastguard Worker        """timezone info object"""
1403*cda5da8dSAndroid Build Coastguard Worker        return self._tzinfo
1404*cda5da8dSAndroid Build Coastguard Worker
1405*cda5da8dSAndroid Build Coastguard Worker    @property
1406*cda5da8dSAndroid Build Coastguard Worker    def fold(self):
1407*cda5da8dSAndroid Build Coastguard Worker        return self._fold
1408*cda5da8dSAndroid Build Coastguard Worker
1409*cda5da8dSAndroid Build Coastguard Worker    # Standard conversions, __hash__ (and helpers)
1410*cda5da8dSAndroid Build Coastguard Worker
1411*cda5da8dSAndroid Build Coastguard Worker    # Comparisons of time objects with other.
1412*cda5da8dSAndroid Build Coastguard Worker
1413*cda5da8dSAndroid Build Coastguard Worker    def __eq__(self, other):
1414*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, time):
1415*cda5da8dSAndroid Build Coastguard Worker            return self._cmp(other, allow_mixed=True) == 0
1416*cda5da8dSAndroid Build Coastguard Worker        else:
1417*cda5da8dSAndroid Build Coastguard Worker            return NotImplemented
1418*cda5da8dSAndroid Build Coastguard Worker
1419*cda5da8dSAndroid Build Coastguard Worker    def __le__(self, other):
1420*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, time):
1421*cda5da8dSAndroid Build Coastguard Worker            return self._cmp(other) <= 0
1422*cda5da8dSAndroid Build Coastguard Worker        else:
1423*cda5da8dSAndroid Build Coastguard Worker            return NotImplemented
1424*cda5da8dSAndroid Build Coastguard Worker
1425*cda5da8dSAndroid Build Coastguard Worker    def __lt__(self, other):
1426*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, time):
1427*cda5da8dSAndroid Build Coastguard Worker            return self._cmp(other) < 0
1428*cda5da8dSAndroid Build Coastguard Worker        else:
1429*cda5da8dSAndroid Build Coastguard Worker            return NotImplemented
1430*cda5da8dSAndroid Build Coastguard Worker
1431*cda5da8dSAndroid Build Coastguard Worker    def __ge__(self, other):
1432*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, time):
1433*cda5da8dSAndroid Build Coastguard Worker            return self._cmp(other) >= 0
1434*cda5da8dSAndroid Build Coastguard Worker        else:
1435*cda5da8dSAndroid Build Coastguard Worker            return NotImplemented
1436*cda5da8dSAndroid Build Coastguard Worker
1437*cda5da8dSAndroid Build Coastguard Worker    def __gt__(self, other):
1438*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, time):
1439*cda5da8dSAndroid Build Coastguard Worker            return self._cmp(other) > 0
1440*cda5da8dSAndroid Build Coastguard Worker        else:
1441*cda5da8dSAndroid Build Coastguard Worker            return NotImplemented
1442*cda5da8dSAndroid Build Coastguard Worker
1443*cda5da8dSAndroid Build Coastguard Worker    def _cmp(self, other, allow_mixed=False):
1444*cda5da8dSAndroid Build Coastguard Worker        assert isinstance(other, time)
1445*cda5da8dSAndroid Build Coastguard Worker        mytz = self._tzinfo
1446*cda5da8dSAndroid Build Coastguard Worker        ottz = other._tzinfo
1447*cda5da8dSAndroid Build Coastguard Worker        myoff = otoff = None
1448*cda5da8dSAndroid Build Coastguard Worker
1449*cda5da8dSAndroid Build Coastguard Worker        if mytz is ottz:
1450*cda5da8dSAndroid Build Coastguard Worker            base_compare = True
1451*cda5da8dSAndroid Build Coastguard Worker        else:
1452*cda5da8dSAndroid Build Coastguard Worker            myoff = self.utcoffset()
1453*cda5da8dSAndroid Build Coastguard Worker            otoff = other.utcoffset()
1454*cda5da8dSAndroid Build Coastguard Worker            base_compare = myoff == otoff
1455*cda5da8dSAndroid Build Coastguard Worker
1456*cda5da8dSAndroid Build Coastguard Worker        if base_compare:
1457*cda5da8dSAndroid Build Coastguard Worker            return _cmp((self._hour, self._minute, self._second,
1458*cda5da8dSAndroid Build Coastguard Worker                         self._microsecond),
1459*cda5da8dSAndroid Build Coastguard Worker                        (other._hour, other._minute, other._second,
1460*cda5da8dSAndroid Build Coastguard Worker                         other._microsecond))
1461*cda5da8dSAndroid Build Coastguard Worker        if myoff is None or otoff is None:
1462*cda5da8dSAndroid Build Coastguard Worker            if allow_mixed:
1463*cda5da8dSAndroid Build Coastguard Worker                return 2 # arbitrary non-zero value
1464*cda5da8dSAndroid Build Coastguard Worker            else:
1465*cda5da8dSAndroid Build Coastguard Worker                raise TypeError("cannot compare naive and aware times")
1466*cda5da8dSAndroid Build Coastguard Worker        myhhmm = self._hour * 60 + self._minute - myoff//timedelta(minutes=1)
1467*cda5da8dSAndroid Build Coastguard Worker        othhmm = other._hour * 60 + other._minute - otoff//timedelta(minutes=1)
1468*cda5da8dSAndroid Build Coastguard Worker        return _cmp((myhhmm, self._second, self._microsecond),
1469*cda5da8dSAndroid Build Coastguard Worker                    (othhmm, other._second, other._microsecond))
1470*cda5da8dSAndroid Build Coastguard Worker
1471*cda5da8dSAndroid Build Coastguard Worker    def __hash__(self):
1472*cda5da8dSAndroid Build Coastguard Worker        """Hash."""
1473*cda5da8dSAndroid Build Coastguard Worker        if self._hashcode == -1:
1474*cda5da8dSAndroid Build Coastguard Worker            if self.fold:
1475*cda5da8dSAndroid Build Coastguard Worker                t = self.replace(fold=0)
1476*cda5da8dSAndroid Build Coastguard Worker            else:
1477*cda5da8dSAndroid Build Coastguard Worker                t = self
1478*cda5da8dSAndroid Build Coastguard Worker            tzoff = t.utcoffset()
1479*cda5da8dSAndroid Build Coastguard Worker            if not tzoff:  # zero or None
1480*cda5da8dSAndroid Build Coastguard Worker                self._hashcode = hash(t._getstate()[0])
1481*cda5da8dSAndroid Build Coastguard Worker            else:
1482*cda5da8dSAndroid Build Coastguard Worker                h, m = divmod(timedelta(hours=self.hour, minutes=self.minute) - tzoff,
1483*cda5da8dSAndroid Build Coastguard Worker                              timedelta(hours=1))
1484*cda5da8dSAndroid Build Coastguard Worker                assert not m % timedelta(minutes=1), "whole minute"
1485*cda5da8dSAndroid Build Coastguard Worker                m //= timedelta(minutes=1)
1486*cda5da8dSAndroid Build Coastguard Worker                if 0 <= h < 24:
1487*cda5da8dSAndroid Build Coastguard Worker                    self._hashcode = hash(time(h, m, self.second, self.microsecond))
1488*cda5da8dSAndroid Build Coastguard Worker                else:
1489*cda5da8dSAndroid Build Coastguard Worker                    self._hashcode = hash((h, m, self.second, self.microsecond))
1490*cda5da8dSAndroid Build Coastguard Worker        return self._hashcode
1491*cda5da8dSAndroid Build Coastguard Worker
1492*cda5da8dSAndroid Build Coastguard Worker    # Conversion to string
1493*cda5da8dSAndroid Build Coastguard Worker
1494*cda5da8dSAndroid Build Coastguard Worker    def _tzstr(self):
1495*cda5da8dSAndroid Build Coastguard Worker        """Return formatted timezone offset (+xx:xx) or an empty string."""
1496*cda5da8dSAndroid Build Coastguard Worker        off = self.utcoffset()
1497*cda5da8dSAndroid Build Coastguard Worker        return _format_offset(off)
1498*cda5da8dSAndroid Build Coastguard Worker
1499*cda5da8dSAndroid Build Coastguard Worker    def __repr__(self):
1500*cda5da8dSAndroid Build Coastguard Worker        """Convert to formal string, for repr()."""
1501*cda5da8dSAndroid Build Coastguard Worker        if self._microsecond != 0:
1502*cda5da8dSAndroid Build Coastguard Worker            s = ", %d, %d" % (self._second, self._microsecond)
1503*cda5da8dSAndroid Build Coastguard Worker        elif self._second != 0:
1504*cda5da8dSAndroid Build Coastguard Worker            s = ", %d" % self._second
1505*cda5da8dSAndroid Build Coastguard Worker        else:
1506*cda5da8dSAndroid Build Coastguard Worker            s = ""
1507*cda5da8dSAndroid Build Coastguard Worker        s= "%s.%s(%d, %d%s)" % (self.__class__.__module__,
1508*cda5da8dSAndroid Build Coastguard Worker                                self.__class__.__qualname__,
1509*cda5da8dSAndroid Build Coastguard Worker                                self._hour, self._minute, s)
1510*cda5da8dSAndroid Build Coastguard Worker        if self._tzinfo is not None:
1511*cda5da8dSAndroid Build Coastguard Worker            assert s[-1:] == ")"
1512*cda5da8dSAndroid Build Coastguard Worker            s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
1513*cda5da8dSAndroid Build Coastguard Worker        if self._fold:
1514*cda5da8dSAndroid Build Coastguard Worker            assert s[-1:] == ")"
1515*cda5da8dSAndroid Build Coastguard Worker            s = s[:-1] + ", fold=1)"
1516*cda5da8dSAndroid Build Coastguard Worker        return s
1517*cda5da8dSAndroid Build Coastguard Worker
1518*cda5da8dSAndroid Build Coastguard Worker    def isoformat(self, timespec='auto'):
1519*cda5da8dSAndroid Build Coastguard Worker        """Return the time formatted according to ISO.
1520*cda5da8dSAndroid Build Coastguard Worker
1521*cda5da8dSAndroid Build Coastguard Worker        The full format is 'HH:MM:SS.mmmmmm+zz:zz'. By default, the fractional
1522*cda5da8dSAndroid Build Coastguard Worker        part is omitted if self.microsecond == 0.
1523*cda5da8dSAndroid Build Coastguard Worker
1524*cda5da8dSAndroid Build Coastguard Worker        The optional argument timespec specifies the number of additional
1525*cda5da8dSAndroid Build Coastguard Worker        terms of the time to include. Valid options are 'auto', 'hours',
1526*cda5da8dSAndroid Build Coastguard Worker        'minutes', 'seconds', 'milliseconds' and 'microseconds'.
1527*cda5da8dSAndroid Build Coastguard Worker        """
1528*cda5da8dSAndroid Build Coastguard Worker        s = _format_time(self._hour, self._minute, self._second,
1529*cda5da8dSAndroid Build Coastguard Worker                          self._microsecond, timespec)
1530*cda5da8dSAndroid Build Coastguard Worker        tz = self._tzstr()
1531*cda5da8dSAndroid Build Coastguard Worker        if tz:
1532*cda5da8dSAndroid Build Coastguard Worker            s += tz
1533*cda5da8dSAndroid Build Coastguard Worker        return s
1534*cda5da8dSAndroid Build Coastguard Worker
1535*cda5da8dSAndroid Build Coastguard Worker    __str__ = isoformat
1536*cda5da8dSAndroid Build Coastguard Worker
1537*cda5da8dSAndroid Build Coastguard Worker    @classmethod
1538*cda5da8dSAndroid Build Coastguard Worker    def fromisoformat(cls, time_string):
1539*cda5da8dSAndroid Build Coastguard Worker        """Construct a time from a string in one of the ISO 8601 formats."""
1540*cda5da8dSAndroid Build Coastguard Worker        if not isinstance(time_string, str):
1541*cda5da8dSAndroid Build Coastguard Worker            raise TypeError('fromisoformat: argument must be str')
1542*cda5da8dSAndroid Build Coastguard Worker
1543*cda5da8dSAndroid Build Coastguard Worker        # The spec actually requires that time-only ISO 8601 strings start with
1544*cda5da8dSAndroid Build Coastguard Worker        # T, but the extended format allows this to be omitted as long as there
1545*cda5da8dSAndroid Build Coastguard Worker        # is no ambiguity with date strings.
1546*cda5da8dSAndroid Build Coastguard Worker        time_string = time_string.removeprefix('T')
1547*cda5da8dSAndroid Build Coastguard Worker
1548*cda5da8dSAndroid Build Coastguard Worker        try:
1549*cda5da8dSAndroid Build Coastguard Worker            return cls(*_parse_isoformat_time(time_string))
1550*cda5da8dSAndroid Build Coastguard Worker        except Exception:
1551*cda5da8dSAndroid Build Coastguard Worker            raise ValueError(f'Invalid isoformat string: {time_string!r}')
1552*cda5da8dSAndroid Build Coastguard Worker
1553*cda5da8dSAndroid Build Coastguard Worker
1554*cda5da8dSAndroid Build Coastguard Worker    def strftime(self, fmt):
1555*cda5da8dSAndroid Build Coastguard Worker        """Format using strftime().  The date part of the timestamp passed
1556*cda5da8dSAndroid Build Coastguard Worker        to underlying strftime should not be used.
1557*cda5da8dSAndroid Build Coastguard Worker        """
1558*cda5da8dSAndroid Build Coastguard Worker        # The year must be >= 1000 else Python's strftime implementation
1559*cda5da8dSAndroid Build Coastguard Worker        # can raise a bogus exception.
1560*cda5da8dSAndroid Build Coastguard Worker        timetuple = (1900, 1, 1,
1561*cda5da8dSAndroid Build Coastguard Worker                     self._hour, self._minute, self._second,
1562*cda5da8dSAndroid Build Coastguard Worker                     0, 1, -1)
1563*cda5da8dSAndroid Build Coastguard Worker        return _wrap_strftime(self, fmt, timetuple)
1564*cda5da8dSAndroid Build Coastguard Worker
1565*cda5da8dSAndroid Build Coastguard Worker    def __format__(self, fmt):
1566*cda5da8dSAndroid Build Coastguard Worker        if not isinstance(fmt, str):
1567*cda5da8dSAndroid Build Coastguard Worker            raise TypeError("must be str, not %s" % type(fmt).__name__)
1568*cda5da8dSAndroid Build Coastguard Worker        if len(fmt) != 0:
1569*cda5da8dSAndroid Build Coastguard Worker            return self.strftime(fmt)
1570*cda5da8dSAndroid Build Coastguard Worker        return str(self)
1571*cda5da8dSAndroid Build Coastguard Worker
1572*cda5da8dSAndroid Build Coastguard Worker    # Timezone functions
1573*cda5da8dSAndroid Build Coastguard Worker
1574*cda5da8dSAndroid Build Coastguard Worker    def utcoffset(self):
1575*cda5da8dSAndroid Build Coastguard Worker        """Return the timezone offset as timedelta, positive east of UTC
1576*cda5da8dSAndroid Build Coastguard Worker         (negative west of UTC)."""
1577*cda5da8dSAndroid Build Coastguard Worker        if self._tzinfo is None:
1578*cda5da8dSAndroid Build Coastguard Worker            return None
1579*cda5da8dSAndroid Build Coastguard Worker        offset = self._tzinfo.utcoffset(None)
1580*cda5da8dSAndroid Build Coastguard Worker        _check_utc_offset("utcoffset", offset)
1581*cda5da8dSAndroid Build Coastguard Worker        return offset
1582*cda5da8dSAndroid Build Coastguard Worker
1583*cda5da8dSAndroid Build Coastguard Worker    def tzname(self):
1584*cda5da8dSAndroid Build Coastguard Worker        """Return the timezone name.
1585*cda5da8dSAndroid Build Coastguard Worker
1586*cda5da8dSAndroid Build Coastguard Worker        Note that the name is 100% informational -- there's no requirement that
1587*cda5da8dSAndroid Build Coastguard Worker        it mean anything in particular. For example, "GMT", "UTC", "-500",
1588*cda5da8dSAndroid Build Coastguard Worker        "-5:00", "EDT", "US/Eastern", "America/New York" are all valid replies.
1589*cda5da8dSAndroid Build Coastguard Worker        """
1590*cda5da8dSAndroid Build Coastguard Worker        if self._tzinfo is None:
1591*cda5da8dSAndroid Build Coastguard Worker            return None
1592*cda5da8dSAndroid Build Coastguard Worker        name = self._tzinfo.tzname(None)
1593*cda5da8dSAndroid Build Coastguard Worker        _check_tzname(name)
1594*cda5da8dSAndroid Build Coastguard Worker        return name
1595*cda5da8dSAndroid Build Coastguard Worker
1596*cda5da8dSAndroid Build Coastguard Worker    def dst(self):
1597*cda5da8dSAndroid Build Coastguard Worker        """Return 0 if DST is not in effect, or the DST offset (as timedelta
1598*cda5da8dSAndroid Build Coastguard Worker        positive eastward) if DST is in effect.
1599*cda5da8dSAndroid Build Coastguard Worker
1600*cda5da8dSAndroid Build Coastguard Worker        This is purely informational; the DST offset has already been added to
1601*cda5da8dSAndroid Build Coastguard Worker        the UTC offset returned by utcoffset() if applicable, so there's no
1602*cda5da8dSAndroid Build Coastguard Worker        need to consult dst() unless you're interested in displaying the DST
1603*cda5da8dSAndroid Build Coastguard Worker        info.
1604*cda5da8dSAndroid Build Coastguard Worker        """
1605*cda5da8dSAndroid Build Coastguard Worker        if self._tzinfo is None:
1606*cda5da8dSAndroid Build Coastguard Worker            return None
1607*cda5da8dSAndroid Build Coastguard Worker        offset = self._tzinfo.dst(None)
1608*cda5da8dSAndroid Build Coastguard Worker        _check_utc_offset("dst", offset)
1609*cda5da8dSAndroid Build Coastguard Worker        return offset
1610*cda5da8dSAndroid Build Coastguard Worker
1611*cda5da8dSAndroid Build Coastguard Worker    def replace(self, hour=None, minute=None, second=None, microsecond=None,
1612*cda5da8dSAndroid Build Coastguard Worker                tzinfo=True, *, fold=None):
1613*cda5da8dSAndroid Build Coastguard Worker        """Return a new time with new values for the specified fields."""
1614*cda5da8dSAndroid Build Coastguard Worker        if hour is None:
1615*cda5da8dSAndroid Build Coastguard Worker            hour = self.hour
1616*cda5da8dSAndroid Build Coastguard Worker        if minute is None:
1617*cda5da8dSAndroid Build Coastguard Worker            minute = self.minute
1618*cda5da8dSAndroid Build Coastguard Worker        if second is None:
1619*cda5da8dSAndroid Build Coastguard Worker            second = self.second
1620*cda5da8dSAndroid Build Coastguard Worker        if microsecond is None:
1621*cda5da8dSAndroid Build Coastguard Worker            microsecond = self.microsecond
1622*cda5da8dSAndroid Build Coastguard Worker        if tzinfo is True:
1623*cda5da8dSAndroid Build Coastguard Worker            tzinfo = self.tzinfo
1624*cda5da8dSAndroid Build Coastguard Worker        if fold is None:
1625*cda5da8dSAndroid Build Coastguard Worker            fold = self._fold
1626*cda5da8dSAndroid Build Coastguard Worker        return type(self)(hour, minute, second, microsecond, tzinfo, fold=fold)
1627*cda5da8dSAndroid Build Coastguard Worker
1628*cda5da8dSAndroid Build Coastguard Worker    # Pickle support.
1629*cda5da8dSAndroid Build Coastguard Worker
1630*cda5da8dSAndroid Build Coastguard Worker    def _getstate(self, protocol=3):
1631*cda5da8dSAndroid Build Coastguard Worker        us2, us3 = divmod(self._microsecond, 256)
1632*cda5da8dSAndroid Build Coastguard Worker        us1, us2 = divmod(us2, 256)
1633*cda5da8dSAndroid Build Coastguard Worker        h = self._hour
1634*cda5da8dSAndroid Build Coastguard Worker        if self._fold and protocol > 3:
1635*cda5da8dSAndroid Build Coastguard Worker            h += 128
1636*cda5da8dSAndroid Build Coastguard Worker        basestate = bytes([h, self._minute, self._second,
1637*cda5da8dSAndroid Build Coastguard Worker                           us1, us2, us3])
1638*cda5da8dSAndroid Build Coastguard Worker        if self._tzinfo is None:
1639*cda5da8dSAndroid Build Coastguard Worker            return (basestate,)
1640*cda5da8dSAndroid Build Coastguard Worker        else:
1641*cda5da8dSAndroid Build Coastguard Worker            return (basestate, self._tzinfo)
1642*cda5da8dSAndroid Build Coastguard Worker
1643*cda5da8dSAndroid Build Coastguard Worker    def __setstate(self, string, tzinfo):
1644*cda5da8dSAndroid Build Coastguard Worker        if tzinfo is not None and not isinstance(tzinfo, _tzinfo_class):
1645*cda5da8dSAndroid Build Coastguard Worker            raise TypeError("bad tzinfo state arg")
1646*cda5da8dSAndroid Build Coastguard Worker        h, self._minute, self._second, us1, us2, us3 = string
1647*cda5da8dSAndroid Build Coastguard Worker        if h > 127:
1648*cda5da8dSAndroid Build Coastguard Worker            self._fold = 1
1649*cda5da8dSAndroid Build Coastguard Worker            self._hour = h - 128
1650*cda5da8dSAndroid Build Coastguard Worker        else:
1651*cda5da8dSAndroid Build Coastguard Worker            self._fold = 0
1652*cda5da8dSAndroid Build Coastguard Worker            self._hour = h
1653*cda5da8dSAndroid Build Coastguard Worker        self._microsecond = (((us1 << 8) | us2) << 8) | us3
1654*cda5da8dSAndroid Build Coastguard Worker        self._tzinfo = tzinfo
1655*cda5da8dSAndroid Build Coastguard Worker
1656*cda5da8dSAndroid Build Coastguard Worker    def __reduce_ex__(self, protocol):
1657*cda5da8dSAndroid Build Coastguard Worker        return (self.__class__, self._getstate(protocol))
1658*cda5da8dSAndroid Build Coastguard Worker
1659*cda5da8dSAndroid Build Coastguard Worker    def __reduce__(self):
1660*cda5da8dSAndroid Build Coastguard Worker        return self.__reduce_ex__(2)
1661*cda5da8dSAndroid Build Coastguard Worker
1662*cda5da8dSAndroid Build Coastguard Worker_time_class = time  # so functions w/ args named "time" can get at the class
1663*cda5da8dSAndroid Build Coastguard Worker
1664*cda5da8dSAndroid Build Coastguard Workertime.min = time(0, 0, 0)
1665*cda5da8dSAndroid Build Coastguard Workertime.max = time(23, 59, 59, 999999)
1666*cda5da8dSAndroid Build Coastguard Workertime.resolution = timedelta(microseconds=1)
1667*cda5da8dSAndroid Build Coastguard Worker
1668*cda5da8dSAndroid Build Coastguard Worker
1669*cda5da8dSAndroid Build Coastguard Workerclass datetime(date):
1670*cda5da8dSAndroid Build Coastguard Worker    """datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])
1671*cda5da8dSAndroid Build Coastguard Worker
1672*cda5da8dSAndroid Build Coastguard Worker    The year, month and day arguments are required. tzinfo may be None, or an
1673*cda5da8dSAndroid Build Coastguard Worker    instance of a tzinfo subclass. The remaining arguments may be ints.
1674*cda5da8dSAndroid Build Coastguard Worker    """
1675*cda5da8dSAndroid Build Coastguard Worker    __slots__ = date.__slots__ + time.__slots__
1676*cda5da8dSAndroid Build Coastguard Worker
1677*cda5da8dSAndroid Build Coastguard Worker    def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0,
1678*cda5da8dSAndroid Build Coastguard Worker                microsecond=0, tzinfo=None, *, fold=0):
1679*cda5da8dSAndroid Build Coastguard Worker        if (isinstance(year, (bytes, str)) and len(year) == 10 and
1680*cda5da8dSAndroid Build Coastguard Worker            1 <= ord(year[2:3])&0x7F <= 12):
1681*cda5da8dSAndroid Build Coastguard Worker            # Pickle support
1682*cda5da8dSAndroid Build Coastguard Worker            if isinstance(year, str):
1683*cda5da8dSAndroid Build Coastguard Worker                try:
1684*cda5da8dSAndroid Build Coastguard Worker                    year = bytes(year, 'latin1')
1685*cda5da8dSAndroid Build Coastguard Worker                except UnicodeEncodeError:
1686*cda5da8dSAndroid Build Coastguard Worker                    # More informative error message.
1687*cda5da8dSAndroid Build Coastguard Worker                    raise ValueError(
1688*cda5da8dSAndroid Build Coastguard Worker                        "Failed to encode latin1 string when unpickling "
1689*cda5da8dSAndroid Build Coastguard Worker                        "a datetime object. "
1690*cda5da8dSAndroid Build Coastguard Worker                        "pickle.load(data, encoding='latin1') is assumed.")
1691*cda5da8dSAndroid Build Coastguard Worker            self = object.__new__(cls)
1692*cda5da8dSAndroid Build Coastguard Worker            self.__setstate(year, month)
1693*cda5da8dSAndroid Build Coastguard Worker            self._hashcode = -1
1694*cda5da8dSAndroid Build Coastguard Worker            return self
1695*cda5da8dSAndroid Build Coastguard Worker        year, month, day = _check_date_fields(year, month, day)
1696*cda5da8dSAndroid Build Coastguard Worker        hour, minute, second, microsecond, fold = _check_time_fields(
1697*cda5da8dSAndroid Build Coastguard Worker            hour, minute, second, microsecond, fold)
1698*cda5da8dSAndroid Build Coastguard Worker        _check_tzinfo_arg(tzinfo)
1699*cda5da8dSAndroid Build Coastguard Worker        self = object.__new__(cls)
1700*cda5da8dSAndroid Build Coastguard Worker        self._year = year
1701*cda5da8dSAndroid Build Coastguard Worker        self._month = month
1702*cda5da8dSAndroid Build Coastguard Worker        self._day = day
1703*cda5da8dSAndroid Build Coastguard Worker        self._hour = hour
1704*cda5da8dSAndroid Build Coastguard Worker        self._minute = minute
1705*cda5da8dSAndroid Build Coastguard Worker        self._second = second
1706*cda5da8dSAndroid Build Coastguard Worker        self._microsecond = microsecond
1707*cda5da8dSAndroid Build Coastguard Worker        self._tzinfo = tzinfo
1708*cda5da8dSAndroid Build Coastguard Worker        self._hashcode = -1
1709*cda5da8dSAndroid Build Coastguard Worker        self._fold = fold
1710*cda5da8dSAndroid Build Coastguard Worker        return self
1711*cda5da8dSAndroid Build Coastguard Worker
1712*cda5da8dSAndroid Build Coastguard Worker    # Read-only field accessors
1713*cda5da8dSAndroid Build Coastguard Worker    @property
1714*cda5da8dSAndroid Build Coastguard Worker    def hour(self):
1715*cda5da8dSAndroid Build Coastguard Worker        """hour (0-23)"""
1716*cda5da8dSAndroid Build Coastguard Worker        return self._hour
1717*cda5da8dSAndroid Build Coastguard Worker
1718*cda5da8dSAndroid Build Coastguard Worker    @property
1719*cda5da8dSAndroid Build Coastguard Worker    def minute(self):
1720*cda5da8dSAndroid Build Coastguard Worker        """minute (0-59)"""
1721*cda5da8dSAndroid Build Coastguard Worker        return self._minute
1722*cda5da8dSAndroid Build Coastguard Worker
1723*cda5da8dSAndroid Build Coastguard Worker    @property
1724*cda5da8dSAndroid Build Coastguard Worker    def second(self):
1725*cda5da8dSAndroid Build Coastguard Worker        """second (0-59)"""
1726*cda5da8dSAndroid Build Coastguard Worker        return self._second
1727*cda5da8dSAndroid Build Coastguard Worker
1728*cda5da8dSAndroid Build Coastguard Worker    @property
1729*cda5da8dSAndroid Build Coastguard Worker    def microsecond(self):
1730*cda5da8dSAndroid Build Coastguard Worker        """microsecond (0-999999)"""
1731*cda5da8dSAndroid Build Coastguard Worker        return self._microsecond
1732*cda5da8dSAndroid Build Coastguard Worker
1733*cda5da8dSAndroid Build Coastguard Worker    @property
1734*cda5da8dSAndroid Build Coastguard Worker    def tzinfo(self):
1735*cda5da8dSAndroid Build Coastguard Worker        """timezone info object"""
1736*cda5da8dSAndroid Build Coastguard Worker        return self._tzinfo
1737*cda5da8dSAndroid Build Coastguard Worker
1738*cda5da8dSAndroid Build Coastguard Worker    @property
1739*cda5da8dSAndroid Build Coastguard Worker    def fold(self):
1740*cda5da8dSAndroid Build Coastguard Worker        return self._fold
1741*cda5da8dSAndroid Build Coastguard Worker
1742*cda5da8dSAndroid Build Coastguard Worker    @classmethod
1743*cda5da8dSAndroid Build Coastguard Worker    def _fromtimestamp(cls, t, utc, tz):
1744*cda5da8dSAndroid Build Coastguard Worker        """Construct a datetime from a POSIX timestamp (like time.time()).
1745*cda5da8dSAndroid Build Coastguard Worker
1746*cda5da8dSAndroid Build Coastguard Worker        A timezone info object may be passed in as well.
1747*cda5da8dSAndroid Build Coastguard Worker        """
1748*cda5da8dSAndroid Build Coastguard Worker        frac, t = _math.modf(t)
1749*cda5da8dSAndroid Build Coastguard Worker        us = round(frac * 1e6)
1750*cda5da8dSAndroid Build Coastguard Worker        if us >= 1000000:
1751*cda5da8dSAndroid Build Coastguard Worker            t += 1
1752*cda5da8dSAndroid Build Coastguard Worker            us -= 1000000
1753*cda5da8dSAndroid Build Coastguard Worker        elif us < 0:
1754*cda5da8dSAndroid Build Coastguard Worker            t -= 1
1755*cda5da8dSAndroid Build Coastguard Worker            us += 1000000
1756*cda5da8dSAndroid Build Coastguard Worker
1757*cda5da8dSAndroid Build Coastguard Worker        converter = _time.gmtime if utc else _time.localtime
1758*cda5da8dSAndroid Build Coastguard Worker        y, m, d, hh, mm, ss, weekday, jday, dst = converter(t)
1759*cda5da8dSAndroid Build Coastguard Worker        ss = min(ss, 59)    # clamp out leap seconds if the platform has them
1760*cda5da8dSAndroid Build Coastguard Worker        result = cls(y, m, d, hh, mm, ss, us, tz)
1761*cda5da8dSAndroid Build Coastguard Worker        if tz is None and not utc:
1762*cda5da8dSAndroid Build Coastguard Worker            # As of version 2015f max fold in IANA database is
1763*cda5da8dSAndroid Build Coastguard Worker            # 23 hours at 1969-09-30 13:00:00 in Kwajalein.
1764*cda5da8dSAndroid Build Coastguard Worker            # Let's probe 24 hours in the past to detect a transition:
1765*cda5da8dSAndroid Build Coastguard Worker            max_fold_seconds = 24 * 3600
1766*cda5da8dSAndroid Build Coastguard Worker
1767*cda5da8dSAndroid Build Coastguard Worker            # On Windows localtime_s throws an OSError for negative values,
1768*cda5da8dSAndroid Build Coastguard Worker            # thus we can't perform fold detection for values of time less
1769*cda5da8dSAndroid Build Coastguard Worker            # than the max time fold. See comments in _datetimemodule's
1770*cda5da8dSAndroid Build Coastguard Worker            # version of this method for more details.
1771*cda5da8dSAndroid Build Coastguard Worker            if t < max_fold_seconds and sys.platform.startswith("win"):
1772*cda5da8dSAndroid Build Coastguard Worker                return result
1773*cda5da8dSAndroid Build Coastguard Worker
1774*cda5da8dSAndroid Build Coastguard Worker            y, m, d, hh, mm, ss = converter(t - max_fold_seconds)[:6]
1775*cda5da8dSAndroid Build Coastguard Worker            probe1 = cls(y, m, d, hh, mm, ss, us, tz)
1776*cda5da8dSAndroid Build Coastguard Worker            trans = result - probe1 - timedelta(0, max_fold_seconds)
1777*cda5da8dSAndroid Build Coastguard Worker            if trans.days < 0:
1778*cda5da8dSAndroid Build Coastguard Worker                y, m, d, hh, mm, ss = converter(t + trans // timedelta(0, 1))[:6]
1779*cda5da8dSAndroid Build Coastguard Worker                probe2 = cls(y, m, d, hh, mm, ss, us, tz)
1780*cda5da8dSAndroid Build Coastguard Worker                if probe2 == result:
1781*cda5da8dSAndroid Build Coastguard Worker                    result._fold = 1
1782*cda5da8dSAndroid Build Coastguard Worker        elif tz is not None:
1783*cda5da8dSAndroid Build Coastguard Worker            result = tz.fromutc(result)
1784*cda5da8dSAndroid Build Coastguard Worker        return result
1785*cda5da8dSAndroid Build Coastguard Worker
1786*cda5da8dSAndroid Build Coastguard Worker    @classmethod
1787*cda5da8dSAndroid Build Coastguard Worker    def fromtimestamp(cls, t, tz=None):
1788*cda5da8dSAndroid Build Coastguard Worker        """Construct a datetime from a POSIX timestamp (like time.time()).
1789*cda5da8dSAndroid Build Coastguard Worker
1790*cda5da8dSAndroid Build Coastguard Worker        A timezone info object may be passed in as well.
1791*cda5da8dSAndroid Build Coastguard Worker        """
1792*cda5da8dSAndroid Build Coastguard Worker        _check_tzinfo_arg(tz)
1793*cda5da8dSAndroid Build Coastguard Worker
1794*cda5da8dSAndroid Build Coastguard Worker        return cls._fromtimestamp(t, tz is not None, tz)
1795*cda5da8dSAndroid Build Coastguard Worker
1796*cda5da8dSAndroid Build Coastguard Worker    @classmethod
1797*cda5da8dSAndroid Build Coastguard Worker    def utcfromtimestamp(cls, t):
1798*cda5da8dSAndroid Build Coastguard Worker        """Construct a naive UTC datetime from a POSIX timestamp."""
1799*cda5da8dSAndroid Build Coastguard Worker        return cls._fromtimestamp(t, True, None)
1800*cda5da8dSAndroid Build Coastguard Worker
1801*cda5da8dSAndroid Build Coastguard Worker    @classmethod
1802*cda5da8dSAndroid Build Coastguard Worker    def now(cls, tz=None):
1803*cda5da8dSAndroid Build Coastguard Worker        "Construct a datetime from time.time() and optional time zone info."
1804*cda5da8dSAndroid Build Coastguard Worker        t = _time.time()
1805*cda5da8dSAndroid Build Coastguard Worker        return cls.fromtimestamp(t, tz)
1806*cda5da8dSAndroid Build Coastguard Worker
1807*cda5da8dSAndroid Build Coastguard Worker    @classmethod
1808*cda5da8dSAndroid Build Coastguard Worker    def utcnow(cls):
1809*cda5da8dSAndroid Build Coastguard Worker        "Construct a UTC datetime from time.time()."
1810*cda5da8dSAndroid Build Coastguard Worker        t = _time.time()
1811*cda5da8dSAndroid Build Coastguard Worker        return cls.utcfromtimestamp(t)
1812*cda5da8dSAndroid Build Coastguard Worker
1813*cda5da8dSAndroid Build Coastguard Worker    @classmethod
1814*cda5da8dSAndroid Build Coastguard Worker    def combine(cls, date, time, tzinfo=True):
1815*cda5da8dSAndroid Build Coastguard Worker        "Construct a datetime from a given date and a given time."
1816*cda5da8dSAndroid Build Coastguard Worker        if not isinstance(date, _date_class):
1817*cda5da8dSAndroid Build Coastguard Worker            raise TypeError("date argument must be a date instance")
1818*cda5da8dSAndroid Build Coastguard Worker        if not isinstance(time, _time_class):
1819*cda5da8dSAndroid Build Coastguard Worker            raise TypeError("time argument must be a time instance")
1820*cda5da8dSAndroid Build Coastguard Worker        if tzinfo is True:
1821*cda5da8dSAndroid Build Coastguard Worker            tzinfo = time.tzinfo
1822*cda5da8dSAndroid Build Coastguard Worker        return cls(date.year, date.month, date.day,
1823*cda5da8dSAndroid Build Coastguard Worker                   time.hour, time.minute, time.second, time.microsecond,
1824*cda5da8dSAndroid Build Coastguard Worker                   tzinfo, fold=time.fold)
1825*cda5da8dSAndroid Build Coastguard Worker
1826*cda5da8dSAndroid Build Coastguard Worker    @classmethod
1827*cda5da8dSAndroid Build Coastguard Worker    def fromisoformat(cls, date_string):
1828*cda5da8dSAndroid Build Coastguard Worker        """Construct a datetime from a string in one of the ISO 8601 formats."""
1829*cda5da8dSAndroid Build Coastguard Worker        if not isinstance(date_string, str):
1830*cda5da8dSAndroid Build Coastguard Worker            raise TypeError('fromisoformat: argument must be str')
1831*cda5da8dSAndroid Build Coastguard Worker
1832*cda5da8dSAndroid Build Coastguard Worker        if len(date_string) < 7:
1833*cda5da8dSAndroid Build Coastguard Worker            raise ValueError(f'Invalid isoformat string: {date_string!r}')
1834*cda5da8dSAndroid Build Coastguard Worker
1835*cda5da8dSAndroid Build Coastguard Worker        # Split this at the separator
1836*cda5da8dSAndroid Build Coastguard Worker        try:
1837*cda5da8dSAndroid Build Coastguard Worker            separator_location = _find_isoformat_datetime_separator(date_string)
1838*cda5da8dSAndroid Build Coastguard Worker            dstr = date_string[0:separator_location]
1839*cda5da8dSAndroid Build Coastguard Worker            tstr = date_string[(separator_location+1):]
1840*cda5da8dSAndroid Build Coastguard Worker
1841*cda5da8dSAndroid Build Coastguard Worker            date_components = _parse_isoformat_date(dstr)
1842*cda5da8dSAndroid Build Coastguard Worker        except ValueError:
1843*cda5da8dSAndroid Build Coastguard Worker            raise ValueError(
1844*cda5da8dSAndroid Build Coastguard Worker                f'Invalid isoformat string: {date_string!r}') from None
1845*cda5da8dSAndroid Build Coastguard Worker
1846*cda5da8dSAndroid Build Coastguard Worker        if tstr:
1847*cda5da8dSAndroid Build Coastguard Worker            try:
1848*cda5da8dSAndroid Build Coastguard Worker                time_components = _parse_isoformat_time(tstr)
1849*cda5da8dSAndroid Build Coastguard Worker            except ValueError:
1850*cda5da8dSAndroid Build Coastguard Worker                raise ValueError(
1851*cda5da8dSAndroid Build Coastguard Worker                    f'Invalid isoformat string: {date_string!r}') from None
1852*cda5da8dSAndroid Build Coastguard Worker        else:
1853*cda5da8dSAndroid Build Coastguard Worker            time_components = [0, 0, 0, 0, None]
1854*cda5da8dSAndroid Build Coastguard Worker
1855*cda5da8dSAndroid Build Coastguard Worker        return cls(*(date_components + time_components))
1856*cda5da8dSAndroid Build Coastguard Worker
1857*cda5da8dSAndroid Build Coastguard Worker    def timetuple(self):
1858*cda5da8dSAndroid Build Coastguard Worker        "Return local time tuple compatible with time.localtime()."
1859*cda5da8dSAndroid Build Coastguard Worker        dst = self.dst()
1860*cda5da8dSAndroid Build Coastguard Worker        if dst is None:
1861*cda5da8dSAndroid Build Coastguard Worker            dst = -1
1862*cda5da8dSAndroid Build Coastguard Worker        elif dst:
1863*cda5da8dSAndroid Build Coastguard Worker            dst = 1
1864*cda5da8dSAndroid Build Coastguard Worker        else:
1865*cda5da8dSAndroid Build Coastguard Worker            dst = 0
1866*cda5da8dSAndroid Build Coastguard Worker        return _build_struct_time(self.year, self.month, self.day,
1867*cda5da8dSAndroid Build Coastguard Worker                                  self.hour, self.minute, self.second,
1868*cda5da8dSAndroid Build Coastguard Worker                                  dst)
1869*cda5da8dSAndroid Build Coastguard Worker
1870*cda5da8dSAndroid Build Coastguard Worker    def _mktime(self):
1871*cda5da8dSAndroid Build Coastguard Worker        """Return integer POSIX timestamp."""
1872*cda5da8dSAndroid Build Coastguard Worker        epoch = datetime(1970, 1, 1)
1873*cda5da8dSAndroid Build Coastguard Worker        max_fold_seconds = 24 * 3600
1874*cda5da8dSAndroid Build Coastguard Worker        t = (self - epoch) // timedelta(0, 1)
1875*cda5da8dSAndroid Build Coastguard Worker        def local(u):
1876*cda5da8dSAndroid Build Coastguard Worker            y, m, d, hh, mm, ss = _time.localtime(u)[:6]
1877*cda5da8dSAndroid Build Coastguard Worker            return (datetime(y, m, d, hh, mm, ss) - epoch) // timedelta(0, 1)
1878*cda5da8dSAndroid Build Coastguard Worker
1879*cda5da8dSAndroid Build Coastguard Worker        # Our goal is to solve t = local(u) for u.
1880*cda5da8dSAndroid Build Coastguard Worker        a = local(t) - t
1881*cda5da8dSAndroid Build Coastguard Worker        u1 = t - a
1882*cda5da8dSAndroid Build Coastguard Worker        t1 = local(u1)
1883*cda5da8dSAndroid Build Coastguard Worker        if t1 == t:
1884*cda5da8dSAndroid Build Coastguard Worker            # We found one solution, but it may not be the one we need.
1885*cda5da8dSAndroid Build Coastguard Worker            # Look for an earlier solution (if `fold` is 0), or a
1886*cda5da8dSAndroid Build Coastguard Worker            # later one (if `fold` is 1).
1887*cda5da8dSAndroid Build Coastguard Worker            u2 = u1 + (-max_fold_seconds, max_fold_seconds)[self.fold]
1888*cda5da8dSAndroid Build Coastguard Worker            b = local(u2) - u2
1889*cda5da8dSAndroid Build Coastguard Worker            if a == b:
1890*cda5da8dSAndroid Build Coastguard Worker                return u1
1891*cda5da8dSAndroid Build Coastguard Worker        else:
1892*cda5da8dSAndroid Build Coastguard Worker            b = t1 - u1
1893*cda5da8dSAndroid Build Coastguard Worker            assert a != b
1894*cda5da8dSAndroid Build Coastguard Worker        u2 = t - b
1895*cda5da8dSAndroid Build Coastguard Worker        t2 = local(u2)
1896*cda5da8dSAndroid Build Coastguard Worker        if t2 == t:
1897*cda5da8dSAndroid Build Coastguard Worker            return u2
1898*cda5da8dSAndroid Build Coastguard Worker        if t1 == t:
1899*cda5da8dSAndroid Build Coastguard Worker            return u1
1900*cda5da8dSAndroid Build Coastguard Worker        # We have found both offsets a and b, but neither t - a nor t - b is
1901*cda5da8dSAndroid Build Coastguard Worker        # a solution.  This means t is in the gap.
1902*cda5da8dSAndroid Build Coastguard Worker        return (max, min)[self.fold](u1, u2)
1903*cda5da8dSAndroid Build Coastguard Worker
1904*cda5da8dSAndroid Build Coastguard Worker
1905*cda5da8dSAndroid Build Coastguard Worker    def timestamp(self):
1906*cda5da8dSAndroid Build Coastguard Worker        "Return POSIX timestamp as float"
1907*cda5da8dSAndroid Build Coastguard Worker        if self._tzinfo is None:
1908*cda5da8dSAndroid Build Coastguard Worker            s = self._mktime()
1909*cda5da8dSAndroid Build Coastguard Worker            return s + self.microsecond / 1e6
1910*cda5da8dSAndroid Build Coastguard Worker        else:
1911*cda5da8dSAndroid Build Coastguard Worker            return (self - _EPOCH).total_seconds()
1912*cda5da8dSAndroid Build Coastguard Worker
1913*cda5da8dSAndroid Build Coastguard Worker    def utctimetuple(self):
1914*cda5da8dSAndroid Build Coastguard Worker        "Return UTC time tuple compatible with time.gmtime()."
1915*cda5da8dSAndroid Build Coastguard Worker        offset = self.utcoffset()
1916*cda5da8dSAndroid Build Coastguard Worker        if offset:
1917*cda5da8dSAndroid Build Coastguard Worker            self -= offset
1918*cda5da8dSAndroid Build Coastguard Worker        y, m, d = self.year, self.month, self.day
1919*cda5da8dSAndroid Build Coastguard Worker        hh, mm, ss = self.hour, self.minute, self.second
1920*cda5da8dSAndroid Build Coastguard Worker        return _build_struct_time(y, m, d, hh, mm, ss, 0)
1921*cda5da8dSAndroid Build Coastguard Worker
1922*cda5da8dSAndroid Build Coastguard Worker    def date(self):
1923*cda5da8dSAndroid Build Coastguard Worker        "Return the date part."
1924*cda5da8dSAndroid Build Coastguard Worker        return date(self._year, self._month, self._day)
1925*cda5da8dSAndroid Build Coastguard Worker
1926*cda5da8dSAndroid Build Coastguard Worker    def time(self):
1927*cda5da8dSAndroid Build Coastguard Worker        "Return the time part, with tzinfo None."
1928*cda5da8dSAndroid Build Coastguard Worker        return time(self.hour, self.minute, self.second, self.microsecond, fold=self.fold)
1929*cda5da8dSAndroid Build Coastguard Worker
1930*cda5da8dSAndroid Build Coastguard Worker    def timetz(self):
1931*cda5da8dSAndroid Build Coastguard Worker        "Return the time part, with same tzinfo."
1932*cda5da8dSAndroid Build Coastguard Worker        return time(self.hour, self.minute, self.second, self.microsecond,
1933*cda5da8dSAndroid Build Coastguard Worker                    self._tzinfo, fold=self.fold)
1934*cda5da8dSAndroid Build Coastguard Worker
1935*cda5da8dSAndroid Build Coastguard Worker    def replace(self, year=None, month=None, day=None, hour=None,
1936*cda5da8dSAndroid Build Coastguard Worker                minute=None, second=None, microsecond=None, tzinfo=True,
1937*cda5da8dSAndroid Build Coastguard Worker                *, fold=None):
1938*cda5da8dSAndroid Build Coastguard Worker        """Return a new datetime with new values for the specified fields."""
1939*cda5da8dSAndroid Build Coastguard Worker        if year is None:
1940*cda5da8dSAndroid Build Coastguard Worker            year = self.year
1941*cda5da8dSAndroid Build Coastguard Worker        if month is None:
1942*cda5da8dSAndroid Build Coastguard Worker            month = self.month
1943*cda5da8dSAndroid Build Coastguard Worker        if day is None:
1944*cda5da8dSAndroid Build Coastguard Worker            day = self.day
1945*cda5da8dSAndroid Build Coastguard Worker        if hour is None:
1946*cda5da8dSAndroid Build Coastguard Worker            hour = self.hour
1947*cda5da8dSAndroid Build Coastguard Worker        if minute is None:
1948*cda5da8dSAndroid Build Coastguard Worker            minute = self.minute
1949*cda5da8dSAndroid Build Coastguard Worker        if second is None:
1950*cda5da8dSAndroid Build Coastguard Worker            second = self.second
1951*cda5da8dSAndroid Build Coastguard Worker        if microsecond is None:
1952*cda5da8dSAndroid Build Coastguard Worker            microsecond = self.microsecond
1953*cda5da8dSAndroid Build Coastguard Worker        if tzinfo is True:
1954*cda5da8dSAndroid Build Coastguard Worker            tzinfo = self.tzinfo
1955*cda5da8dSAndroid Build Coastguard Worker        if fold is None:
1956*cda5da8dSAndroid Build Coastguard Worker            fold = self.fold
1957*cda5da8dSAndroid Build Coastguard Worker        return type(self)(year, month, day, hour, minute, second,
1958*cda5da8dSAndroid Build Coastguard Worker                          microsecond, tzinfo, fold=fold)
1959*cda5da8dSAndroid Build Coastguard Worker
1960*cda5da8dSAndroid Build Coastguard Worker    def _local_timezone(self):
1961*cda5da8dSAndroid Build Coastguard Worker        if self.tzinfo is None:
1962*cda5da8dSAndroid Build Coastguard Worker            ts = self._mktime()
1963*cda5da8dSAndroid Build Coastguard Worker        else:
1964*cda5da8dSAndroid Build Coastguard Worker            ts = (self - _EPOCH) // timedelta(seconds=1)
1965*cda5da8dSAndroid Build Coastguard Worker        localtm = _time.localtime(ts)
1966*cda5da8dSAndroid Build Coastguard Worker        local = datetime(*localtm[:6])
1967*cda5da8dSAndroid Build Coastguard Worker        # Extract TZ data
1968*cda5da8dSAndroid Build Coastguard Worker        gmtoff = localtm.tm_gmtoff
1969*cda5da8dSAndroid Build Coastguard Worker        zone = localtm.tm_zone
1970*cda5da8dSAndroid Build Coastguard Worker        return timezone(timedelta(seconds=gmtoff), zone)
1971*cda5da8dSAndroid Build Coastguard Worker
1972*cda5da8dSAndroid Build Coastguard Worker    def astimezone(self, tz=None):
1973*cda5da8dSAndroid Build Coastguard Worker        if tz is None:
1974*cda5da8dSAndroid Build Coastguard Worker            tz = self._local_timezone()
1975*cda5da8dSAndroid Build Coastguard Worker        elif not isinstance(tz, tzinfo):
1976*cda5da8dSAndroid Build Coastguard Worker            raise TypeError("tz argument must be an instance of tzinfo")
1977*cda5da8dSAndroid Build Coastguard Worker
1978*cda5da8dSAndroid Build Coastguard Worker        mytz = self.tzinfo
1979*cda5da8dSAndroid Build Coastguard Worker        if mytz is None:
1980*cda5da8dSAndroid Build Coastguard Worker            mytz = self._local_timezone()
1981*cda5da8dSAndroid Build Coastguard Worker            myoffset = mytz.utcoffset(self)
1982*cda5da8dSAndroid Build Coastguard Worker        else:
1983*cda5da8dSAndroid Build Coastguard Worker            myoffset = mytz.utcoffset(self)
1984*cda5da8dSAndroid Build Coastguard Worker            if myoffset is None:
1985*cda5da8dSAndroid Build Coastguard Worker                mytz = self.replace(tzinfo=None)._local_timezone()
1986*cda5da8dSAndroid Build Coastguard Worker                myoffset = mytz.utcoffset(self)
1987*cda5da8dSAndroid Build Coastguard Worker
1988*cda5da8dSAndroid Build Coastguard Worker        if tz is mytz:
1989*cda5da8dSAndroid Build Coastguard Worker            return self
1990*cda5da8dSAndroid Build Coastguard Worker
1991*cda5da8dSAndroid Build Coastguard Worker        # Convert self to UTC, and attach the new time zone object.
1992*cda5da8dSAndroid Build Coastguard Worker        utc = (self - myoffset).replace(tzinfo=tz)
1993*cda5da8dSAndroid Build Coastguard Worker
1994*cda5da8dSAndroid Build Coastguard Worker        # Convert from UTC to tz's local time.
1995*cda5da8dSAndroid Build Coastguard Worker        return tz.fromutc(utc)
1996*cda5da8dSAndroid Build Coastguard Worker
1997*cda5da8dSAndroid Build Coastguard Worker    # Ways to produce a string.
1998*cda5da8dSAndroid Build Coastguard Worker
1999*cda5da8dSAndroid Build Coastguard Worker    def ctime(self):
2000*cda5da8dSAndroid Build Coastguard Worker        "Return ctime() style string."
2001*cda5da8dSAndroid Build Coastguard Worker        weekday = self.toordinal() % 7 or 7
2002*cda5da8dSAndroid Build Coastguard Worker        return "%s %s %2d %02d:%02d:%02d %04d" % (
2003*cda5da8dSAndroid Build Coastguard Worker            _DAYNAMES[weekday],
2004*cda5da8dSAndroid Build Coastguard Worker            _MONTHNAMES[self._month],
2005*cda5da8dSAndroid Build Coastguard Worker            self._day,
2006*cda5da8dSAndroid Build Coastguard Worker            self._hour, self._minute, self._second,
2007*cda5da8dSAndroid Build Coastguard Worker            self._year)
2008*cda5da8dSAndroid Build Coastguard Worker
2009*cda5da8dSAndroid Build Coastguard Worker    def isoformat(self, sep='T', timespec='auto'):
2010*cda5da8dSAndroid Build Coastguard Worker        """Return the time formatted according to ISO.
2011*cda5da8dSAndroid Build Coastguard Worker
2012*cda5da8dSAndroid Build Coastguard Worker        The full format looks like 'YYYY-MM-DD HH:MM:SS.mmmmmm'.
2013*cda5da8dSAndroid Build Coastguard Worker        By default, the fractional part is omitted if self.microsecond == 0.
2014*cda5da8dSAndroid Build Coastguard Worker
2015*cda5da8dSAndroid Build Coastguard Worker        If self.tzinfo is not None, the UTC offset is also attached, giving
2016*cda5da8dSAndroid Build Coastguard Worker        giving a full format of 'YYYY-MM-DD HH:MM:SS.mmmmmm+HH:MM'.
2017*cda5da8dSAndroid Build Coastguard Worker
2018*cda5da8dSAndroid Build Coastguard Worker        Optional argument sep specifies the separator between date and
2019*cda5da8dSAndroid Build Coastguard Worker        time, default 'T'.
2020*cda5da8dSAndroid Build Coastguard Worker
2021*cda5da8dSAndroid Build Coastguard Worker        The optional argument timespec specifies the number of additional
2022*cda5da8dSAndroid Build Coastguard Worker        terms of the time to include. Valid options are 'auto', 'hours',
2023*cda5da8dSAndroid Build Coastguard Worker        'minutes', 'seconds', 'milliseconds' and 'microseconds'.
2024*cda5da8dSAndroid Build Coastguard Worker        """
2025*cda5da8dSAndroid Build Coastguard Worker        s = ("%04d-%02d-%02d%c" % (self._year, self._month, self._day, sep) +
2026*cda5da8dSAndroid Build Coastguard Worker             _format_time(self._hour, self._minute, self._second,
2027*cda5da8dSAndroid Build Coastguard Worker                          self._microsecond, timespec))
2028*cda5da8dSAndroid Build Coastguard Worker
2029*cda5da8dSAndroid Build Coastguard Worker        off = self.utcoffset()
2030*cda5da8dSAndroid Build Coastguard Worker        tz = _format_offset(off)
2031*cda5da8dSAndroid Build Coastguard Worker        if tz:
2032*cda5da8dSAndroid Build Coastguard Worker            s += tz
2033*cda5da8dSAndroid Build Coastguard Worker
2034*cda5da8dSAndroid Build Coastguard Worker        return s
2035*cda5da8dSAndroid Build Coastguard Worker
2036*cda5da8dSAndroid Build Coastguard Worker    def __repr__(self):
2037*cda5da8dSAndroid Build Coastguard Worker        """Convert to formal string, for repr()."""
2038*cda5da8dSAndroid Build Coastguard Worker        L = [self._year, self._month, self._day,  # These are never zero
2039*cda5da8dSAndroid Build Coastguard Worker             self._hour, self._minute, self._second, self._microsecond]
2040*cda5da8dSAndroid Build Coastguard Worker        if L[-1] == 0:
2041*cda5da8dSAndroid Build Coastguard Worker            del L[-1]
2042*cda5da8dSAndroid Build Coastguard Worker        if L[-1] == 0:
2043*cda5da8dSAndroid Build Coastguard Worker            del L[-1]
2044*cda5da8dSAndroid Build Coastguard Worker        s = "%s.%s(%s)" % (self.__class__.__module__,
2045*cda5da8dSAndroid Build Coastguard Worker                           self.__class__.__qualname__,
2046*cda5da8dSAndroid Build Coastguard Worker                           ", ".join(map(str, L)))
2047*cda5da8dSAndroid Build Coastguard Worker        if self._tzinfo is not None:
2048*cda5da8dSAndroid Build Coastguard Worker            assert s[-1:] == ")"
2049*cda5da8dSAndroid Build Coastguard Worker            s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
2050*cda5da8dSAndroid Build Coastguard Worker        if self._fold:
2051*cda5da8dSAndroid Build Coastguard Worker            assert s[-1:] == ")"
2052*cda5da8dSAndroid Build Coastguard Worker            s = s[:-1] + ", fold=1)"
2053*cda5da8dSAndroid Build Coastguard Worker        return s
2054*cda5da8dSAndroid Build Coastguard Worker
2055*cda5da8dSAndroid Build Coastguard Worker    def __str__(self):
2056*cda5da8dSAndroid Build Coastguard Worker        "Convert to string, for str()."
2057*cda5da8dSAndroid Build Coastguard Worker        return self.isoformat(sep=' ')
2058*cda5da8dSAndroid Build Coastguard Worker
2059*cda5da8dSAndroid Build Coastguard Worker    @classmethod
2060*cda5da8dSAndroid Build Coastguard Worker    def strptime(cls, date_string, format):
2061*cda5da8dSAndroid Build Coastguard Worker        'string, format -> new datetime parsed from a string (like time.strptime()).'
2062*cda5da8dSAndroid Build Coastguard Worker        import _strptime
2063*cda5da8dSAndroid Build Coastguard Worker        return _strptime._strptime_datetime(cls, date_string, format)
2064*cda5da8dSAndroid Build Coastguard Worker
2065*cda5da8dSAndroid Build Coastguard Worker    def utcoffset(self):
2066*cda5da8dSAndroid Build Coastguard Worker        """Return the timezone offset as timedelta positive east of UTC (negative west of
2067*cda5da8dSAndroid Build Coastguard Worker        UTC)."""
2068*cda5da8dSAndroid Build Coastguard Worker        if self._tzinfo is None:
2069*cda5da8dSAndroid Build Coastguard Worker            return None
2070*cda5da8dSAndroid Build Coastguard Worker        offset = self._tzinfo.utcoffset(self)
2071*cda5da8dSAndroid Build Coastguard Worker        _check_utc_offset("utcoffset", offset)
2072*cda5da8dSAndroid Build Coastguard Worker        return offset
2073*cda5da8dSAndroid Build Coastguard Worker
2074*cda5da8dSAndroid Build Coastguard Worker    def tzname(self):
2075*cda5da8dSAndroid Build Coastguard Worker        """Return the timezone name.
2076*cda5da8dSAndroid Build Coastguard Worker
2077*cda5da8dSAndroid Build Coastguard Worker        Note that the name is 100% informational -- there's no requirement that
2078*cda5da8dSAndroid Build Coastguard Worker        it mean anything in particular. For example, "GMT", "UTC", "-500",
2079*cda5da8dSAndroid Build Coastguard Worker        "-5:00", "EDT", "US/Eastern", "America/New York" are all valid replies.
2080*cda5da8dSAndroid Build Coastguard Worker        """
2081*cda5da8dSAndroid Build Coastguard Worker        if self._tzinfo is None:
2082*cda5da8dSAndroid Build Coastguard Worker            return None
2083*cda5da8dSAndroid Build Coastguard Worker        name = self._tzinfo.tzname(self)
2084*cda5da8dSAndroid Build Coastguard Worker        _check_tzname(name)
2085*cda5da8dSAndroid Build Coastguard Worker        return name
2086*cda5da8dSAndroid Build Coastguard Worker
2087*cda5da8dSAndroid Build Coastguard Worker    def dst(self):
2088*cda5da8dSAndroid Build Coastguard Worker        """Return 0 if DST is not in effect, or the DST offset (as timedelta
2089*cda5da8dSAndroid Build Coastguard Worker        positive eastward) if DST is in effect.
2090*cda5da8dSAndroid Build Coastguard Worker
2091*cda5da8dSAndroid Build Coastguard Worker        This is purely informational; the DST offset has already been added to
2092*cda5da8dSAndroid Build Coastguard Worker        the UTC offset returned by utcoffset() if applicable, so there's no
2093*cda5da8dSAndroid Build Coastguard Worker        need to consult dst() unless you're interested in displaying the DST
2094*cda5da8dSAndroid Build Coastguard Worker        info.
2095*cda5da8dSAndroid Build Coastguard Worker        """
2096*cda5da8dSAndroid Build Coastguard Worker        if self._tzinfo is None:
2097*cda5da8dSAndroid Build Coastguard Worker            return None
2098*cda5da8dSAndroid Build Coastguard Worker        offset = self._tzinfo.dst(self)
2099*cda5da8dSAndroid Build Coastguard Worker        _check_utc_offset("dst", offset)
2100*cda5da8dSAndroid Build Coastguard Worker        return offset
2101*cda5da8dSAndroid Build Coastguard Worker
2102*cda5da8dSAndroid Build Coastguard Worker    # Comparisons of datetime objects with other.
2103*cda5da8dSAndroid Build Coastguard Worker
2104*cda5da8dSAndroid Build Coastguard Worker    def __eq__(self, other):
2105*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, datetime):
2106*cda5da8dSAndroid Build Coastguard Worker            return self._cmp(other, allow_mixed=True) == 0
2107*cda5da8dSAndroid Build Coastguard Worker        elif not isinstance(other, date):
2108*cda5da8dSAndroid Build Coastguard Worker            return NotImplemented
2109*cda5da8dSAndroid Build Coastguard Worker        else:
2110*cda5da8dSAndroid Build Coastguard Worker            return False
2111*cda5da8dSAndroid Build Coastguard Worker
2112*cda5da8dSAndroid Build Coastguard Worker    def __le__(self, other):
2113*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, datetime):
2114*cda5da8dSAndroid Build Coastguard Worker            return self._cmp(other) <= 0
2115*cda5da8dSAndroid Build Coastguard Worker        elif not isinstance(other, date):
2116*cda5da8dSAndroid Build Coastguard Worker            return NotImplemented
2117*cda5da8dSAndroid Build Coastguard Worker        else:
2118*cda5da8dSAndroid Build Coastguard Worker            _cmperror(self, other)
2119*cda5da8dSAndroid Build Coastguard Worker
2120*cda5da8dSAndroid Build Coastguard Worker    def __lt__(self, other):
2121*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, datetime):
2122*cda5da8dSAndroid Build Coastguard Worker            return self._cmp(other) < 0
2123*cda5da8dSAndroid Build Coastguard Worker        elif not isinstance(other, date):
2124*cda5da8dSAndroid Build Coastguard Worker            return NotImplemented
2125*cda5da8dSAndroid Build Coastguard Worker        else:
2126*cda5da8dSAndroid Build Coastguard Worker            _cmperror(self, other)
2127*cda5da8dSAndroid Build Coastguard Worker
2128*cda5da8dSAndroid Build Coastguard Worker    def __ge__(self, other):
2129*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, datetime):
2130*cda5da8dSAndroid Build Coastguard Worker            return self._cmp(other) >= 0
2131*cda5da8dSAndroid Build Coastguard Worker        elif not isinstance(other, date):
2132*cda5da8dSAndroid Build Coastguard Worker            return NotImplemented
2133*cda5da8dSAndroid Build Coastguard Worker        else:
2134*cda5da8dSAndroid Build Coastguard Worker            _cmperror(self, other)
2135*cda5da8dSAndroid Build Coastguard Worker
2136*cda5da8dSAndroid Build Coastguard Worker    def __gt__(self, other):
2137*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, datetime):
2138*cda5da8dSAndroid Build Coastguard Worker            return self._cmp(other) > 0
2139*cda5da8dSAndroid Build Coastguard Worker        elif not isinstance(other, date):
2140*cda5da8dSAndroid Build Coastguard Worker            return NotImplemented
2141*cda5da8dSAndroid Build Coastguard Worker        else:
2142*cda5da8dSAndroid Build Coastguard Worker            _cmperror(self, other)
2143*cda5da8dSAndroid Build Coastguard Worker
2144*cda5da8dSAndroid Build Coastguard Worker    def _cmp(self, other, allow_mixed=False):
2145*cda5da8dSAndroid Build Coastguard Worker        assert isinstance(other, datetime)
2146*cda5da8dSAndroid Build Coastguard Worker        mytz = self._tzinfo
2147*cda5da8dSAndroid Build Coastguard Worker        ottz = other._tzinfo
2148*cda5da8dSAndroid Build Coastguard Worker        myoff = otoff = None
2149*cda5da8dSAndroid Build Coastguard Worker
2150*cda5da8dSAndroid Build Coastguard Worker        if mytz is ottz:
2151*cda5da8dSAndroid Build Coastguard Worker            base_compare = True
2152*cda5da8dSAndroid Build Coastguard Worker        else:
2153*cda5da8dSAndroid Build Coastguard Worker            myoff = self.utcoffset()
2154*cda5da8dSAndroid Build Coastguard Worker            otoff = other.utcoffset()
2155*cda5da8dSAndroid Build Coastguard Worker            # Assume that allow_mixed means that we are called from __eq__
2156*cda5da8dSAndroid Build Coastguard Worker            if allow_mixed:
2157*cda5da8dSAndroid Build Coastguard Worker                if myoff != self.replace(fold=not self.fold).utcoffset():
2158*cda5da8dSAndroid Build Coastguard Worker                    return 2
2159*cda5da8dSAndroid Build Coastguard Worker                if otoff != other.replace(fold=not other.fold).utcoffset():
2160*cda5da8dSAndroid Build Coastguard Worker                    return 2
2161*cda5da8dSAndroid Build Coastguard Worker            base_compare = myoff == otoff
2162*cda5da8dSAndroid Build Coastguard Worker
2163*cda5da8dSAndroid Build Coastguard Worker        if base_compare:
2164*cda5da8dSAndroid Build Coastguard Worker            return _cmp((self._year, self._month, self._day,
2165*cda5da8dSAndroid Build Coastguard Worker                         self._hour, self._minute, self._second,
2166*cda5da8dSAndroid Build Coastguard Worker                         self._microsecond),
2167*cda5da8dSAndroid Build Coastguard Worker                        (other._year, other._month, other._day,
2168*cda5da8dSAndroid Build Coastguard Worker                         other._hour, other._minute, other._second,
2169*cda5da8dSAndroid Build Coastguard Worker                         other._microsecond))
2170*cda5da8dSAndroid Build Coastguard Worker        if myoff is None or otoff is None:
2171*cda5da8dSAndroid Build Coastguard Worker            if allow_mixed:
2172*cda5da8dSAndroid Build Coastguard Worker                return 2 # arbitrary non-zero value
2173*cda5da8dSAndroid Build Coastguard Worker            else:
2174*cda5da8dSAndroid Build Coastguard Worker                raise TypeError("cannot compare naive and aware datetimes")
2175*cda5da8dSAndroid Build Coastguard Worker        # XXX What follows could be done more efficiently...
2176*cda5da8dSAndroid Build Coastguard Worker        diff = self - other     # this will take offsets into account
2177*cda5da8dSAndroid Build Coastguard Worker        if diff.days < 0:
2178*cda5da8dSAndroid Build Coastguard Worker            return -1
2179*cda5da8dSAndroid Build Coastguard Worker        return diff and 1 or 0
2180*cda5da8dSAndroid Build Coastguard Worker
2181*cda5da8dSAndroid Build Coastguard Worker    def __add__(self, other):
2182*cda5da8dSAndroid Build Coastguard Worker        "Add a datetime and a timedelta."
2183*cda5da8dSAndroid Build Coastguard Worker        if not isinstance(other, timedelta):
2184*cda5da8dSAndroid Build Coastguard Worker            return NotImplemented
2185*cda5da8dSAndroid Build Coastguard Worker        delta = timedelta(self.toordinal(),
2186*cda5da8dSAndroid Build Coastguard Worker                          hours=self._hour,
2187*cda5da8dSAndroid Build Coastguard Worker                          minutes=self._minute,
2188*cda5da8dSAndroid Build Coastguard Worker                          seconds=self._second,
2189*cda5da8dSAndroid Build Coastguard Worker                          microseconds=self._microsecond)
2190*cda5da8dSAndroid Build Coastguard Worker        delta += other
2191*cda5da8dSAndroid Build Coastguard Worker        hour, rem = divmod(delta.seconds, 3600)
2192*cda5da8dSAndroid Build Coastguard Worker        minute, second = divmod(rem, 60)
2193*cda5da8dSAndroid Build Coastguard Worker        if 0 < delta.days <= _MAXORDINAL:
2194*cda5da8dSAndroid Build Coastguard Worker            return type(self).combine(date.fromordinal(delta.days),
2195*cda5da8dSAndroid Build Coastguard Worker                                      time(hour, minute, second,
2196*cda5da8dSAndroid Build Coastguard Worker                                           delta.microseconds,
2197*cda5da8dSAndroid Build Coastguard Worker                                           tzinfo=self._tzinfo))
2198*cda5da8dSAndroid Build Coastguard Worker        raise OverflowError("result out of range")
2199*cda5da8dSAndroid Build Coastguard Worker
2200*cda5da8dSAndroid Build Coastguard Worker    __radd__ = __add__
2201*cda5da8dSAndroid Build Coastguard Worker
2202*cda5da8dSAndroid Build Coastguard Worker    def __sub__(self, other):
2203*cda5da8dSAndroid Build Coastguard Worker        "Subtract two datetimes, or a datetime and a timedelta."
2204*cda5da8dSAndroid Build Coastguard Worker        if not isinstance(other, datetime):
2205*cda5da8dSAndroid Build Coastguard Worker            if isinstance(other, timedelta):
2206*cda5da8dSAndroid Build Coastguard Worker                return self + -other
2207*cda5da8dSAndroid Build Coastguard Worker            return NotImplemented
2208*cda5da8dSAndroid Build Coastguard Worker
2209*cda5da8dSAndroid Build Coastguard Worker        days1 = self.toordinal()
2210*cda5da8dSAndroid Build Coastguard Worker        days2 = other.toordinal()
2211*cda5da8dSAndroid Build Coastguard Worker        secs1 = self._second + self._minute * 60 + self._hour * 3600
2212*cda5da8dSAndroid Build Coastguard Worker        secs2 = other._second + other._minute * 60 + other._hour * 3600
2213*cda5da8dSAndroid Build Coastguard Worker        base = timedelta(days1 - days2,
2214*cda5da8dSAndroid Build Coastguard Worker                         secs1 - secs2,
2215*cda5da8dSAndroid Build Coastguard Worker                         self._microsecond - other._microsecond)
2216*cda5da8dSAndroid Build Coastguard Worker        if self._tzinfo is other._tzinfo:
2217*cda5da8dSAndroid Build Coastguard Worker            return base
2218*cda5da8dSAndroid Build Coastguard Worker        myoff = self.utcoffset()
2219*cda5da8dSAndroid Build Coastguard Worker        otoff = other.utcoffset()
2220*cda5da8dSAndroid Build Coastguard Worker        if myoff == otoff:
2221*cda5da8dSAndroid Build Coastguard Worker            return base
2222*cda5da8dSAndroid Build Coastguard Worker        if myoff is None or otoff is None:
2223*cda5da8dSAndroid Build Coastguard Worker            raise TypeError("cannot mix naive and timezone-aware time")
2224*cda5da8dSAndroid Build Coastguard Worker        return base + otoff - myoff
2225*cda5da8dSAndroid Build Coastguard Worker
2226*cda5da8dSAndroid Build Coastguard Worker    def __hash__(self):
2227*cda5da8dSAndroid Build Coastguard Worker        if self._hashcode == -1:
2228*cda5da8dSAndroid Build Coastguard Worker            if self.fold:
2229*cda5da8dSAndroid Build Coastguard Worker                t = self.replace(fold=0)
2230*cda5da8dSAndroid Build Coastguard Worker            else:
2231*cda5da8dSAndroid Build Coastguard Worker                t = self
2232*cda5da8dSAndroid Build Coastguard Worker            tzoff = t.utcoffset()
2233*cda5da8dSAndroid Build Coastguard Worker            if tzoff is None:
2234*cda5da8dSAndroid Build Coastguard Worker                self._hashcode = hash(t._getstate()[0])
2235*cda5da8dSAndroid Build Coastguard Worker            else:
2236*cda5da8dSAndroid Build Coastguard Worker                days = _ymd2ord(self.year, self.month, self.day)
2237*cda5da8dSAndroid Build Coastguard Worker                seconds = self.hour * 3600 + self.minute * 60 + self.second
2238*cda5da8dSAndroid Build Coastguard Worker                self._hashcode = hash(timedelta(days, seconds, self.microsecond) - tzoff)
2239*cda5da8dSAndroid Build Coastguard Worker        return self._hashcode
2240*cda5da8dSAndroid Build Coastguard Worker
2241*cda5da8dSAndroid Build Coastguard Worker    # Pickle support.
2242*cda5da8dSAndroid Build Coastguard Worker
2243*cda5da8dSAndroid Build Coastguard Worker    def _getstate(self, protocol=3):
2244*cda5da8dSAndroid Build Coastguard Worker        yhi, ylo = divmod(self._year, 256)
2245*cda5da8dSAndroid Build Coastguard Worker        us2, us3 = divmod(self._microsecond, 256)
2246*cda5da8dSAndroid Build Coastguard Worker        us1, us2 = divmod(us2, 256)
2247*cda5da8dSAndroid Build Coastguard Worker        m = self._month
2248*cda5da8dSAndroid Build Coastguard Worker        if self._fold and protocol > 3:
2249*cda5da8dSAndroid Build Coastguard Worker            m += 128
2250*cda5da8dSAndroid Build Coastguard Worker        basestate = bytes([yhi, ylo, m, self._day,
2251*cda5da8dSAndroid Build Coastguard Worker                           self._hour, self._minute, self._second,
2252*cda5da8dSAndroid Build Coastguard Worker                           us1, us2, us3])
2253*cda5da8dSAndroid Build Coastguard Worker        if self._tzinfo is None:
2254*cda5da8dSAndroid Build Coastguard Worker            return (basestate,)
2255*cda5da8dSAndroid Build Coastguard Worker        else:
2256*cda5da8dSAndroid Build Coastguard Worker            return (basestate, self._tzinfo)
2257*cda5da8dSAndroid Build Coastguard Worker
2258*cda5da8dSAndroid Build Coastguard Worker    def __setstate(self, string, tzinfo):
2259*cda5da8dSAndroid Build Coastguard Worker        if tzinfo is not None and not isinstance(tzinfo, _tzinfo_class):
2260*cda5da8dSAndroid Build Coastguard Worker            raise TypeError("bad tzinfo state arg")
2261*cda5da8dSAndroid Build Coastguard Worker        (yhi, ylo, m, self._day, self._hour,
2262*cda5da8dSAndroid Build Coastguard Worker         self._minute, self._second, us1, us2, us3) = string
2263*cda5da8dSAndroid Build Coastguard Worker        if m > 127:
2264*cda5da8dSAndroid Build Coastguard Worker            self._fold = 1
2265*cda5da8dSAndroid Build Coastguard Worker            self._month = m - 128
2266*cda5da8dSAndroid Build Coastguard Worker        else:
2267*cda5da8dSAndroid Build Coastguard Worker            self._fold = 0
2268*cda5da8dSAndroid Build Coastguard Worker            self._month = m
2269*cda5da8dSAndroid Build Coastguard Worker        self._year = yhi * 256 + ylo
2270*cda5da8dSAndroid Build Coastguard Worker        self._microsecond = (((us1 << 8) | us2) << 8) | us3
2271*cda5da8dSAndroid Build Coastguard Worker        self._tzinfo = tzinfo
2272*cda5da8dSAndroid Build Coastguard Worker
2273*cda5da8dSAndroid Build Coastguard Worker    def __reduce_ex__(self, protocol):
2274*cda5da8dSAndroid Build Coastguard Worker        return (self.__class__, self._getstate(protocol))
2275*cda5da8dSAndroid Build Coastguard Worker
2276*cda5da8dSAndroid Build Coastguard Worker    def __reduce__(self):
2277*cda5da8dSAndroid Build Coastguard Worker        return self.__reduce_ex__(2)
2278*cda5da8dSAndroid Build Coastguard Worker
2279*cda5da8dSAndroid Build Coastguard Worker
2280*cda5da8dSAndroid Build Coastguard Workerdatetime.min = datetime(1, 1, 1)
2281*cda5da8dSAndroid Build Coastguard Workerdatetime.max = datetime(9999, 12, 31, 23, 59, 59, 999999)
2282*cda5da8dSAndroid Build Coastguard Workerdatetime.resolution = timedelta(microseconds=1)
2283*cda5da8dSAndroid Build Coastguard Worker
2284*cda5da8dSAndroid Build Coastguard Worker
2285*cda5da8dSAndroid Build Coastguard Workerdef _isoweek1monday(year):
2286*cda5da8dSAndroid Build Coastguard Worker    # Helper to calculate the day number of the Monday starting week 1
2287*cda5da8dSAndroid Build Coastguard Worker    # XXX This could be done more efficiently
2288*cda5da8dSAndroid Build Coastguard Worker    THURSDAY = 3
2289*cda5da8dSAndroid Build Coastguard Worker    firstday = _ymd2ord(year, 1, 1)
2290*cda5da8dSAndroid Build Coastguard Worker    firstweekday = (firstday + 6) % 7  # See weekday() above
2291*cda5da8dSAndroid Build Coastguard Worker    week1monday = firstday - firstweekday
2292*cda5da8dSAndroid Build Coastguard Worker    if firstweekday > THURSDAY:
2293*cda5da8dSAndroid Build Coastguard Worker        week1monday += 7
2294*cda5da8dSAndroid Build Coastguard Worker    return week1monday
2295*cda5da8dSAndroid Build Coastguard Worker
2296*cda5da8dSAndroid Build Coastguard Worker
2297*cda5da8dSAndroid Build Coastguard Workerclass timezone(tzinfo):
2298*cda5da8dSAndroid Build Coastguard Worker    __slots__ = '_offset', '_name'
2299*cda5da8dSAndroid Build Coastguard Worker
2300*cda5da8dSAndroid Build Coastguard Worker    # Sentinel value to disallow None
2301*cda5da8dSAndroid Build Coastguard Worker    _Omitted = object()
2302*cda5da8dSAndroid Build Coastguard Worker    def __new__(cls, offset, name=_Omitted):
2303*cda5da8dSAndroid Build Coastguard Worker        if not isinstance(offset, timedelta):
2304*cda5da8dSAndroid Build Coastguard Worker            raise TypeError("offset must be a timedelta")
2305*cda5da8dSAndroid Build Coastguard Worker        if name is cls._Omitted:
2306*cda5da8dSAndroid Build Coastguard Worker            if not offset:
2307*cda5da8dSAndroid Build Coastguard Worker                return cls.utc
2308*cda5da8dSAndroid Build Coastguard Worker            name = None
2309*cda5da8dSAndroid Build Coastguard Worker        elif not isinstance(name, str):
2310*cda5da8dSAndroid Build Coastguard Worker            raise TypeError("name must be a string")
2311*cda5da8dSAndroid Build Coastguard Worker        if not cls._minoffset <= offset <= cls._maxoffset:
2312*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("offset must be a timedelta "
2313*cda5da8dSAndroid Build Coastguard Worker                             "strictly between -timedelta(hours=24) and "
2314*cda5da8dSAndroid Build Coastguard Worker                             "timedelta(hours=24).")
2315*cda5da8dSAndroid Build Coastguard Worker        return cls._create(offset, name)
2316*cda5da8dSAndroid Build Coastguard Worker
2317*cda5da8dSAndroid Build Coastguard Worker    @classmethod
2318*cda5da8dSAndroid Build Coastguard Worker    def _create(cls, offset, name=None):
2319*cda5da8dSAndroid Build Coastguard Worker        self = tzinfo.__new__(cls)
2320*cda5da8dSAndroid Build Coastguard Worker        self._offset = offset
2321*cda5da8dSAndroid Build Coastguard Worker        self._name = name
2322*cda5da8dSAndroid Build Coastguard Worker        return self
2323*cda5da8dSAndroid Build Coastguard Worker
2324*cda5da8dSAndroid Build Coastguard Worker    def __getinitargs__(self):
2325*cda5da8dSAndroid Build Coastguard Worker        """pickle support"""
2326*cda5da8dSAndroid Build Coastguard Worker        if self._name is None:
2327*cda5da8dSAndroid Build Coastguard Worker            return (self._offset,)
2328*cda5da8dSAndroid Build Coastguard Worker        return (self._offset, self._name)
2329*cda5da8dSAndroid Build Coastguard Worker
2330*cda5da8dSAndroid Build Coastguard Worker    def __eq__(self, other):
2331*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, timezone):
2332*cda5da8dSAndroid Build Coastguard Worker            return self._offset == other._offset
2333*cda5da8dSAndroid Build Coastguard Worker        return NotImplemented
2334*cda5da8dSAndroid Build Coastguard Worker
2335*cda5da8dSAndroid Build Coastguard Worker    def __hash__(self):
2336*cda5da8dSAndroid Build Coastguard Worker        return hash(self._offset)
2337*cda5da8dSAndroid Build Coastguard Worker
2338*cda5da8dSAndroid Build Coastguard Worker    def __repr__(self):
2339*cda5da8dSAndroid Build Coastguard Worker        """Convert to formal string, for repr().
2340*cda5da8dSAndroid Build Coastguard Worker
2341*cda5da8dSAndroid Build Coastguard Worker        >>> tz = timezone.utc
2342*cda5da8dSAndroid Build Coastguard Worker        >>> repr(tz)
2343*cda5da8dSAndroid Build Coastguard Worker        'datetime.timezone.utc'
2344*cda5da8dSAndroid Build Coastguard Worker        >>> tz = timezone(timedelta(hours=-5), 'EST')
2345*cda5da8dSAndroid Build Coastguard Worker        >>> repr(tz)
2346*cda5da8dSAndroid Build Coastguard Worker        "datetime.timezone(datetime.timedelta(-1, 68400), 'EST')"
2347*cda5da8dSAndroid Build Coastguard Worker        """
2348*cda5da8dSAndroid Build Coastguard Worker        if self is self.utc:
2349*cda5da8dSAndroid Build Coastguard Worker            return 'datetime.timezone.utc'
2350*cda5da8dSAndroid Build Coastguard Worker        if self._name is None:
2351*cda5da8dSAndroid Build Coastguard Worker            return "%s.%s(%r)" % (self.__class__.__module__,
2352*cda5da8dSAndroid Build Coastguard Worker                                  self.__class__.__qualname__,
2353*cda5da8dSAndroid Build Coastguard Worker                                  self._offset)
2354*cda5da8dSAndroid Build Coastguard Worker        return "%s.%s(%r, %r)" % (self.__class__.__module__,
2355*cda5da8dSAndroid Build Coastguard Worker                                  self.__class__.__qualname__,
2356*cda5da8dSAndroid Build Coastguard Worker                                  self._offset, self._name)
2357*cda5da8dSAndroid Build Coastguard Worker
2358*cda5da8dSAndroid Build Coastguard Worker    def __str__(self):
2359*cda5da8dSAndroid Build Coastguard Worker        return self.tzname(None)
2360*cda5da8dSAndroid Build Coastguard Worker
2361*cda5da8dSAndroid Build Coastguard Worker    def utcoffset(self, dt):
2362*cda5da8dSAndroid Build Coastguard Worker        if isinstance(dt, datetime) or dt is None:
2363*cda5da8dSAndroid Build Coastguard Worker            return self._offset
2364*cda5da8dSAndroid Build Coastguard Worker        raise TypeError("utcoffset() argument must be a datetime instance"
2365*cda5da8dSAndroid Build Coastguard Worker                        " or None")
2366*cda5da8dSAndroid Build Coastguard Worker
2367*cda5da8dSAndroid Build Coastguard Worker    def tzname(self, dt):
2368*cda5da8dSAndroid Build Coastguard Worker        if isinstance(dt, datetime) or dt is None:
2369*cda5da8dSAndroid Build Coastguard Worker            if self._name is None:
2370*cda5da8dSAndroid Build Coastguard Worker                return self._name_from_offset(self._offset)
2371*cda5da8dSAndroid Build Coastguard Worker            return self._name
2372*cda5da8dSAndroid Build Coastguard Worker        raise TypeError("tzname() argument must be a datetime instance"
2373*cda5da8dSAndroid Build Coastguard Worker                        " or None")
2374*cda5da8dSAndroid Build Coastguard Worker
2375*cda5da8dSAndroid Build Coastguard Worker    def dst(self, dt):
2376*cda5da8dSAndroid Build Coastguard Worker        if isinstance(dt, datetime) or dt is None:
2377*cda5da8dSAndroid Build Coastguard Worker            return None
2378*cda5da8dSAndroid Build Coastguard Worker        raise TypeError("dst() argument must be a datetime instance"
2379*cda5da8dSAndroid Build Coastguard Worker                        " or None")
2380*cda5da8dSAndroid Build Coastguard Worker
2381*cda5da8dSAndroid Build Coastguard Worker    def fromutc(self, dt):
2382*cda5da8dSAndroid Build Coastguard Worker        if isinstance(dt, datetime):
2383*cda5da8dSAndroid Build Coastguard Worker            if dt.tzinfo is not self:
2384*cda5da8dSAndroid Build Coastguard Worker                raise ValueError("fromutc: dt.tzinfo "
2385*cda5da8dSAndroid Build Coastguard Worker                                 "is not self")
2386*cda5da8dSAndroid Build Coastguard Worker            return dt + self._offset
2387*cda5da8dSAndroid Build Coastguard Worker        raise TypeError("fromutc() argument must be a datetime instance"
2388*cda5da8dSAndroid Build Coastguard Worker                        " or None")
2389*cda5da8dSAndroid Build Coastguard Worker
2390*cda5da8dSAndroid Build Coastguard Worker    _maxoffset = timedelta(hours=24, microseconds=-1)
2391*cda5da8dSAndroid Build Coastguard Worker    _minoffset = -_maxoffset
2392*cda5da8dSAndroid Build Coastguard Worker
2393*cda5da8dSAndroid Build Coastguard Worker    @staticmethod
2394*cda5da8dSAndroid Build Coastguard Worker    def _name_from_offset(delta):
2395*cda5da8dSAndroid Build Coastguard Worker        if not delta:
2396*cda5da8dSAndroid Build Coastguard Worker            return 'UTC'
2397*cda5da8dSAndroid Build Coastguard Worker        if delta < timedelta(0):
2398*cda5da8dSAndroid Build Coastguard Worker            sign = '-'
2399*cda5da8dSAndroid Build Coastguard Worker            delta = -delta
2400*cda5da8dSAndroid Build Coastguard Worker        else:
2401*cda5da8dSAndroid Build Coastguard Worker            sign = '+'
2402*cda5da8dSAndroid Build Coastguard Worker        hours, rest = divmod(delta, timedelta(hours=1))
2403*cda5da8dSAndroid Build Coastguard Worker        minutes, rest = divmod(rest, timedelta(minutes=1))
2404*cda5da8dSAndroid Build Coastguard Worker        seconds = rest.seconds
2405*cda5da8dSAndroid Build Coastguard Worker        microseconds = rest.microseconds
2406*cda5da8dSAndroid Build Coastguard Worker        if microseconds:
2407*cda5da8dSAndroid Build Coastguard Worker            return (f'UTC{sign}{hours:02d}:{minutes:02d}:{seconds:02d}'
2408*cda5da8dSAndroid Build Coastguard Worker                    f'.{microseconds:06d}')
2409*cda5da8dSAndroid Build Coastguard Worker        if seconds:
2410*cda5da8dSAndroid Build Coastguard Worker            return f'UTC{sign}{hours:02d}:{minutes:02d}:{seconds:02d}'
2411*cda5da8dSAndroid Build Coastguard Worker        return f'UTC{sign}{hours:02d}:{minutes:02d}'
2412*cda5da8dSAndroid Build Coastguard Worker
2413*cda5da8dSAndroid Build Coastguard WorkerUTC = timezone.utc = timezone._create(timedelta(0))
2414*cda5da8dSAndroid Build Coastguard Worker
2415*cda5da8dSAndroid Build Coastguard Worker# bpo-37642: These attributes are rounded to the nearest minute for backwards
2416*cda5da8dSAndroid Build Coastguard Worker# compatibility, even though the constructor will accept a wider range of
2417*cda5da8dSAndroid Build Coastguard Worker# values. This may change in the future.
2418*cda5da8dSAndroid Build Coastguard Workertimezone.min = timezone._create(-timedelta(hours=23, minutes=59))
2419*cda5da8dSAndroid Build Coastguard Workertimezone.max = timezone._create(timedelta(hours=23, minutes=59))
2420*cda5da8dSAndroid Build Coastguard Worker_EPOCH = datetime(1970, 1, 1, tzinfo=timezone.utc)
2421*cda5da8dSAndroid Build Coastguard Worker
2422*cda5da8dSAndroid Build Coastguard Worker# Some time zone algebra.  For a datetime x, let
2423*cda5da8dSAndroid Build Coastguard Worker#     x.n = x stripped of its timezone -- its naive time.
2424*cda5da8dSAndroid Build Coastguard Worker#     x.o = x.utcoffset(), and assuming that doesn't raise an exception or
2425*cda5da8dSAndroid Build Coastguard Worker#           return None
2426*cda5da8dSAndroid Build Coastguard Worker#     x.d = x.dst(), and assuming that doesn't raise an exception or
2427*cda5da8dSAndroid Build Coastguard Worker#           return None
2428*cda5da8dSAndroid Build Coastguard Worker#     x.s = x's standard offset, x.o - x.d
2429*cda5da8dSAndroid Build Coastguard Worker#
2430*cda5da8dSAndroid Build Coastguard Worker# Now some derived rules, where k is a duration (timedelta).
2431*cda5da8dSAndroid Build Coastguard Worker#
2432*cda5da8dSAndroid Build Coastguard Worker# 1. x.o = x.s + x.d
2433*cda5da8dSAndroid Build Coastguard Worker#    This follows from the definition of x.s.
2434*cda5da8dSAndroid Build Coastguard Worker#
2435*cda5da8dSAndroid Build Coastguard Worker# 2. If x and y have the same tzinfo member, x.s = y.s.
2436*cda5da8dSAndroid Build Coastguard Worker#    This is actually a requirement, an assumption we need to make about
2437*cda5da8dSAndroid Build Coastguard Worker#    sane tzinfo classes.
2438*cda5da8dSAndroid Build Coastguard Worker#
2439*cda5da8dSAndroid Build Coastguard Worker# 3. The naive UTC time corresponding to x is x.n - x.o.
2440*cda5da8dSAndroid Build Coastguard Worker#    This is again a requirement for a sane tzinfo class.
2441*cda5da8dSAndroid Build Coastguard Worker#
2442*cda5da8dSAndroid Build Coastguard Worker# 4. (x+k).s = x.s
2443*cda5da8dSAndroid Build Coastguard Worker#    This follows from #2, and that datetime.timetz+timedelta preserves tzinfo.
2444*cda5da8dSAndroid Build Coastguard Worker#
2445*cda5da8dSAndroid Build Coastguard Worker# 5. (x+k).n = x.n + k
2446*cda5da8dSAndroid Build Coastguard Worker#    Again follows from how arithmetic is defined.
2447*cda5da8dSAndroid Build Coastguard Worker#
2448*cda5da8dSAndroid Build Coastguard Worker# Now we can explain tz.fromutc(x).  Let's assume it's an interesting case
2449*cda5da8dSAndroid Build Coastguard Worker# (meaning that the various tzinfo methods exist, and don't blow up or return
2450*cda5da8dSAndroid Build Coastguard Worker# None when called).
2451*cda5da8dSAndroid Build Coastguard Worker#
2452*cda5da8dSAndroid Build Coastguard Worker# The function wants to return a datetime y with timezone tz, equivalent to x.
2453*cda5da8dSAndroid Build Coastguard Worker# x is already in UTC.
2454*cda5da8dSAndroid Build Coastguard Worker#
2455*cda5da8dSAndroid Build Coastguard Worker# By #3, we want
2456*cda5da8dSAndroid Build Coastguard Worker#
2457*cda5da8dSAndroid Build Coastguard Worker#     y.n - y.o = x.n                             [1]
2458*cda5da8dSAndroid Build Coastguard Worker#
2459*cda5da8dSAndroid Build Coastguard Worker# The algorithm starts by attaching tz to x.n, and calling that y.  So
2460*cda5da8dSAndroid Build Coastguard Worker# x.n = y.n at the start.  Then it wants to add a duration k to y, so that [1]
2461*cda5da8dSAndroid Build Coastguard Worker# becomes true; in effect, we want to solve [2] for k:
2462*cda5da8dSAndroid Build Coastguard Worker#
2463*cda5da8dSAndroid Build Coastguard Worker#    (y+k).n - (y+k).o = x.n                      [2]
2464*cda5da8dSAndroid Build Coastguard Worker#
2465*cda5da8dSAndroid Build Coastguard Worker# By #1, this is the same as
2466*cda5da8dSAndroid Build Coastguard Worker#
2467*cda5da8dSAndroid Build Coastguard Worker#    (y+k).n - ((y+k).s + (y+k).d) = x.n          [3]
2468*cda5da8dSAndroid Build Coastguard Worker#
2469*cda5da8dSAndroid Build Coastguard Worker# By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
2470*cda5da8dSAndroid Build Coastguard Worker# Substituting that into [3],
2471*cda5da8dSAndroid Build Coastguard Worker#
2472*cda5da8dSAndroid Build Coastguard Worker#    x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
2473*cda5da8dSAndroid Build Coastguard Worker#    k - (y+k).s - (y+k).d = 0; rearranging,
2474*cda5da8dSAndroid Build Coastguard Worker#    k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
2475*cda5da8dSAndroid Build Coastguard Worker#    k = y.s - (y+k).d
2476*cda5da8dSAndroid Build Coastguard Worker#
2477*cda5da8dSAndroid Build Coastguard Worker# On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
2478*cda5da8dSAndroid Build Coastguard Worker# approximate k by ignoring the (y+k).d term at first.  Note that k can't be
2479*cda5da8dSAndroid Build Coastguard Worker# very large, since all offset-returning methods return a duration of magnitude
2480*cda5da8dSAndroid Build Coastguard Worker# less than 24 hours.  For that reason, if y is firmly in std time, (y+k).d must
2481*cda5da8dSAndroid Build Coastguard Worker# be 0, so ignoring it has no consequence then.
2482*cda5da8dSAndroid Build Coastguard Worker#
2483*cda5da8dSAndroid Build Coastguard Worker# In any case, the new value is
2484*cda5da8dSAndroid Build Coastguard Worker#
2485*cda5da8dSAndroid Build Coastguard Worker#     z = y + y.s                                 [4]
2486*cda5da8dSAndroid Build Coastguard Worker#
2487*cda5da8dSAndroid Build Coastguard Worker# It's helpful to step back at look at [4] from a higher level:  it's simply
2488*cda5da8dSAndroid Build Coastguard Worker# mapping from UTC to tz's standard time.
2489*cda5da8dSAndroid Build Coastguard Worker#
2490*cda5da8dSAndroid Build Coastguard Worker# At this point, if
2491*cda5da8dSAndroid Build Coastguard Worker#
2492*cda5da8dSAndroid Build Coastguard Worker#     z.n - z.o = x.n                             [5]
2493*cda5da8dSAndroid Build Coastguard Worker#
2494*cda5da8dSAndroid Build Coastguard Worker# we have an equivalent time, and are almost done.  The insecurity here is
2495*cda5da8dSAndroid Build Coastguard Worker# at the start of daylight time.  Picture US Eastern for concreteness.  The wall
2496*cda5da8dSAndroid Build Coastguard Worker# time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good
2497*cda5da8dSAndroid Build Coastguard Worker# sense then.  The docs ask that an Eastern tzinfo class consider such a time to
2498*cda5da8dSAndroid Build Coastguard Worker# be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
2499*cda5da8dSAndroid Build Coastguard Worker# on the day DST starts.  We want to return the 1:MM EST spelling because that's
2500*cda5da8dSAndroid Build Coastguard Worker# the only spelling that makes sense on the local wall clock.
2501*cda5da8dSAndroid Build Coastguard Worker#
2502*cda5da8dSAndroid Build Coastguard Worker# In fact, if [5] holds at this point, we do have the standard-time spelling,
2503*cda5da8dSAndroid Build Coastguard Worker# but that takes a bit of proof.  We first prove a stronger result.  What's the
2504*cda5da8dSAndroid Build Coastguard Worker# difference between the LHS and RHS of [5]?  Let
2505*cda5da8dSAndroid Build Coastguard Worker#
2506*cda5da8dSAndroid Build Coastguard Worker#     diff = x.n - (z.n - z.o)                    [6]
2507*cda5da8dSAndroid Build Coastguard Worker#
2508*cda5da8dSAndroid Build Coastguard Worker# Now
2509*cda5da8dSAndroid Build Coastguard Worker#     z.n =                       by [4]
2510*cda5da8dSAndroid Build Coastguard Worker#     (y + y.s).n =               by #5
2511*cda5da8dSAndroid Build Coastguard Worker#     y.n + y.s =                 since y.n = x.n
2512*cda5da8dSAndroid Build Coastguard Worker#     x.n + y.s =                 since z and y are have the same tzinfo member,
2513*cda5da8dSAndroid Build Coastguard Worker#                                     y.s = z.s by #2
2514*cda5da8dSAndroid Build Coastguard Worker#     x.n + z.s
2515*cda5da8dSAndroid Build Coastguard Worker#
2516*cda5da8dSAndroid Build Coastguard Worker# Plugging that back into [6] gives
2517*cda5da8dSAndroid Build Coastguard Worker#
2518*cda5da8dSAndroid Build Coastguard Worker#     diff =
2519*cda5da8dSAndroid Build Coastguard Worker#     x.n - ((x.n + z.s) - z.o) =     expanding
2520*cda5da8dSAndroid Build Coastguard Worker#     x.n - x.n - z.s + z.o =         cancelling
2521*cda5da8dSAndroid Build Coastguard Worker#     - z.s + z.o =                   by #2
2522*cda5da8dSAndroid Build Coastguard Worker#     z.d
2523*cda5da8dSAndroid Build Coastguard Worker#
2524*cda5da8dSAndroid Build Coastguard Worker# So diff = z.d.
2525*cda5da8dSAndroid Build Coastguard Worker#
2526*cda5da8dSAndroid Build Coastguard Worker# If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
2527*cda5da8dSAndroid Build Coastguard Worker# spelling we wanted in the endcase described above.  We're done.  Contrarily,
2528*cda5da8dSAndroid Build Coastguard Worker# if z.d = 0, then we have a UTC equivalent, and are also done.
2529*cda5da8dSAndroid Build Coastguard Worker#
2530*cda5da8dSAndroid Build Coastguard Worker# If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
2531*cda5da8dSAndroid Build Coastguard Worker# add to z (in effect, z is in tz's standard time, and we need to shift the
2532*cda5da8dSAndroid Build Coastguard Worker# local clock into tz's daylight time).
2533*cda5da8dSAndroid Build Coastguard Worker#
2534*cda5da8dSAndroid Build Coastguard Worker# Let
2535*cda5da8dSAndroid Build Coastguard Worker#
2536*cda5da8dSAndroid Build Coastguard Worker#     z' = z + z.d = z + diff                     [7]
2537*cda5da8dSAndroid Build Coastguard Worker#
2538*cda5da8dSAndroid Build Coastguard Worker# and we can again ask whether
2539*cda5da8dSAndroid Build Coastguard Worker#
2540*cda5da8dSAndroid Build Coastguard Worker#     z'.n - z'.o = x.n                           [8]
2541*cda5da8dSAndroid Build Coastguard Worker#
2542*cda5da8dSAndroid Build Coastguard Worker# If so, we're done.  If not, the tzinfo class is insane, according to the
2543*cda5da8dSAndroid Build Coastguard Worker# assumptions we've made.  This also requires a bit of proof.  As before, let's
2544*cda5da8dSAndroid Build Coastguard Worker# compute the difference between the LHS and RHS of [8] (and skipping some of
2545*cda5da8dSAndroid Build Coastguard Worker# the justifications for the kinds of substitutions we've done several times
2546*cda5da8dSAndroid Build Coastguard Worker# already):
2547*cda5da8dSAndroid Build Coastguard Worker#
2548*cda5da8dSAndroid Build Coastguard Worker#     diff' = x.n - (z'.n - z'.o) =           replacing z'.n via [7]
2549*cda5da8dSAndroid Build Coastguard Worker#             x.n  - (z.n + diff - z'.o) =    replacing diff via [6]
2550*cda5da8dSAndroid Build Coastguard Worker#             x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
2551*cda5da8dSAndroid Build Coastguard Worker#             x.n - z.n - x.n + z.n - z.o + z'.o =    cancel x.n
2552*cda5da8dSAndroid Build Coastguard Worker#             - z.n + z.n - z.o + z'.o =              cancel z.n
2553*cda5da8dSAndroid Build Coastguard Worker#             - z.o + z'.o =                      #1 twice
2554*cda5da8dSAndroid Build Coastguard Worker#             -z.s - z.d + z'.s + z'.d =          z and z' have same tzinfo
2555*cda5da8dSAndroid Build Coastguard Worker#             z'.d - z.d
2556*cda5da8dSAndroid Build Coastguard Worker#
2557*cda5da8dSAndroid Build Coastguard Worker# So z' is UTC-equivalent to x iff z'.d = z.d at this point.  If they are equal,
2558*cda5da8dSAndroid Build Coastguard Worker# we've found the UTC-equivalent so are done.  In fact, we stop with [7] and
2559*cda5da8dSAndroid Build Coastguard Worker# return z', not bothering to compute z'.d.
2560*cda5da8dSAndroid Build Coastguard Worker#
2561*cda5da8dSAndroid Build Coastguard Worker# How could z.d and z'd differ?  z' = z + z.d [7], so merely moving z' by
2562*cda5da8dSAndroid Build Coastguard Worker# a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
2563*cda5da8dSAndroid Build Coastguard Worker# would have to change the result dst() returns:  we start in DST, and moving
2564*cda5da8dSAndroid Build Coastguard Worker# a little further into it takes us out of DST.
2565*cda5da8dSAndroid Build Coastguard Worker#
2566*cda5da8dSAndroid Build Coastguard Worker# There isn't a sane case where this can happen.  The closest it gets is at
2567*cda5da8dSAndroid Build Coastguard Worker# the end of DST, where there's an hour in UTC with no spelling in a hybrid
2568*cda5da8dSAndroid Build Coastguard Worker# tzinfo class.  In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT.  During
2569*cda5da8dSAndroid Build Coastguard Worker# that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
2570*cda5da8dSAndroid Build Coastguard Worker# UTC) because the docs insist on that, but 0:MM is taken as being in daylight
2571*cda5da8dSAndroid Build Coastguard Worker# time (4:MM UTC).  There is no local time mapping to 5:MM UTC.  The local
2572*cda5da8dSAndroid Build Coastguard Worker# clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
2573*cda5da8dSAndroid Build Coastguard Worker# standard time.  Since that's what the local clock *does*, we want to map both
2574*cda5da8dSAndroid Build Coastguard Worker# UTC hours 5:MM and 6:MM to 1:MM Eastern.  The result is ambiguous
2575*cda5da8dSAndroid Build Coastguard Worker# in local time, but so it goes -- it's the way the local clock works.
2576*cda5da8dSAndroid Build Coastguard Worker#
2577*cda5da8dSAndroid Build Coastguard Worker# When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
2578*cda5da8dSAndroid Build Coastguard Worker# so z=0:MM.  z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
2579*cda5da8dSAndroid Build Coastguard Worker# z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8]
2580*cda5da8dSAndroid Build Coastguard Worker# (correctly) concludes that z' is not UTC-equivalent to x.
2581*cda5da8dSAndroid Build Coastguard Worker#
2582*cda5da8dSAndroid Build Coastguard Worker# Because we know z.d said z was in daylight time (else [5] would have held and
2583*cda5da8dSAndroid Build Coastguard Worker# we would have stopped then), and we know z.d != z'.d (else [8] would have held
2584*cda5da8dSAndroid Build Coastguard Worker# and we have stopped then), and there are only 2 possible values dst() can
2585*cda5da8dSAndroid Build Coastguard Worker# return in Eastern, it follows that z'.d must be 0 (which it is in the example,
2586*cda5da8dSAndroid Build Coastguard Worker# but the reasoning doesn't depend on the example -- it depends on there being
2587*cda5da8dSAndroid Build Coastguard Worker# two possible dst() outcomes, one zero and the other non-zero).  Therefore
2588*cda5da8dSAndroid Build Coastguard Worker# z' must be in standard time, and is the spelling we want in this case.
2589*cda5da8dSAndroid Build Coastguard Worker#
2590*cda5da8dSAndroid Build Coastguard Worker# Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
2591*cda5da8dSAndroid Build Coastguard Worker# concerned (because it takes z' as being in standard time rather than the
2592*cda5da8dSAndroid Build Coastguard Worker# daylight time we intend here), but returning it gives the real-life "local
2593*cda5da8dSAndroid Build Coastguard Worker# clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
2594*cda5da8dSAndroid Build Coastguard Worker# tz.
2595*cda5da8dSAndroid Build Coastguard Worker#
2596*cda5da8dSAndroid Build Coastguard Worker# When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
2597*cda5da8dSAndroid Build Coastguard Worker# the 1:MM standard time spelling we want.
2598*cda5da8dSAndroid Build Coastguard Worker#
2599*cda5da8dSAndroid Build Coastguard Worker# So how can this break?  One of the assumptions must be violated.  Two
2600*cda5da8dSAndroid Build Coastguard Worker# possibilities:
2601*cda5da8dSAndroid Build Coastguard Worker#
2602*cda5da8dSAndroid Build Coastguard Worker# 1) [2] effectively says that y.s is invariant across all y belong to a given
2603*cda5da8dSAndroid Build Coastguard Worker#    time zone.  This isn't true if, for political reasons or continental drift,
2604*cda5da8dSAndroid Build Coastguard Worker#    a region decides to change its base offset from UTC.
2605*cda5da8dSAndroid Build Coastguard Worker#
2606*cda5da8dSAndroid Build Coastguard Worker# 2) There may be versions of "double daylight" time where the tail end of
2607*cda5da8dSAndroid Build Coastguard Worker#    the analysis gives up a step too early.  I haven't thought about that
2608*cda5da8dSAndroid Build Coastguard Worker#    enough to say.
2609*cda5da8dSAndroid Build Coastguard Worker#
2610*cda5da8dSAndroid Build Coastguard Worker# In any case, it's clear that the default fromutc() is strong enough to handle
2611*cda5da8dSAndroid Build Coastguard Worker# "almost all" time zones:  so long as the standard offset is invariant, it
2612*cda5da8dSAndroid Build Coastguard Worker# doesn't matter if daylight time transition points change from year to year, or
2613*cda5da8dSAndroid Build Coastguard Worker# if daylight time is skipped in some years; it doesn't matter how large or
2614*cda5da8dSAndroid Build Coastguard Worker# small dst() may get within its bounds; and it doesn't even matter if some
2615*cda5da8dSAndroid Build Coastguard Worker# perverse time zone returns a negative dst()).  So a breaking case must be
2616*cda5da8dSAndroid Build Coastguard Worker# pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
2617*cda5da8dSAndroid Build Coastguard Worker
2618*cda5da8dSAndroid Build Coastguard Workertry:
2619*cda5da8dSAndroid Build Coastguard Worker    from _datetime import *
2620*cda5da8dSAndroid Build Coastguard Workerexcept ImportError:
2621*cda5da8dSAndroid Build Coastguard Worker    pass
2622*cda5da8dSAndroid Build Coastguard Workerelse:
2623*cda5da8dSAndroid Build Coastguard Worker    # Clean up unused names
2624*cda5da8dSAndroid Build Coastguard Worker    del (_DAYNAMES, _DAYS_BEFORE_MONTH, _DAYS_IN_MONTH, _DI100Y, _DI400Y,
2625*cda5da8dSAndroid Build Coastguard Worker         _DI4Y, _EPOCH, _MAXORDINAL, _MONTHNAMES, _build_struct_time,
2626*cda5da8dSAndroid Build Coastguard Worker         _check_date_fields, _check_time_fields,
2627*cda5da8dSAndroid Build Coastguard Worker         _check_tzinfo_arg, _check_tzname, _check_utc_offset, _cmp, _cmperror,
2628*cda5da8dSAndroid Build Coastguard Worker         _date_class, _days_before_month, _days_before_year, _days_in_month,
2629*cda5da8dSAndroid Build Coastguard Worker         _format_time, _format_offset, _index, _is_leap, _isoweek1monday, _math,
2630*cda5da8dSAndroid Build Coastguard Worker         _ord2ymd, _time, _time_class, _tzinfo_class, _wrap_strftime, _ymd2ord,
2631*cda5da8dSAndroid Build Coastguard Worker         _divide_and_round, _parse_isoformat_date, _parse_isoformat_time,
2632*cda5da8dSAndroid Build Coastguard Worker         _parse_hh_mm_ss_ff, _IsoCalendarDate, _isoweek_to_gregorian,
2633*cda5da8dSAndroid Build Coastguard Worker         _find_isoformat_datetime_separator, _FRACTION_CORRECTION,
2634*cda5da8dSAndroid Build Coastguard Worker         _is_ascii_digit)
2635*cda5da8dSAndroid Build Coastguard Worker    # XXX Since import * above excludes names that start with _,
2636*cda5da8dSAndroid Build Coastguard Worker    # docstring does not get overwritten. In the future, it may be
2637*cda5da8dSAndroid Build Coastguard Worker    # appropriate to maintain a single module level docstring and
2638*cda5da8dSAndroid Build Coastguard Worker    # remove the following line.
2639*cda5da8dSAndroid Build Coastguard Worker    from _datetime import __doc__
2640