ยปCore Development>Code coverage>Lib/datetime.py

# Python code coverage for Lib/datetime.py

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