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