NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

relativedelta.py (14252B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\dateutil\relativedelta.py
      2 import datetime
      3 import calendar
      4 import operator
      5 from math import copysign
      6 from six import integer_types
      7 from warnings import warn
      8 from ._common import weekday
      9 MO, TU, WE, TH, FR, SA, SU = weekdays = tuple([ weekday(x) for x in range(7) ])
     10 __all__ = ['relativedelta',
     11  'MO',
     12  'TU',
     13  'WE',
     14  'TH',
     15  'FR',
     16  'SA',
     17  'SU']
     18 
     19 class relativedelta(object):
     20 
     21     def __init__(self, dt1 = None, dt2 = None, years = 0, months = 0, days = 0, leapdays = 0, weeks = 0, hours = 0, minutes = 0, seconds = 0, microseconds = 0, year = None, month = None, day = None, weekday = None, yearday = None, nlyearday = None, hour = None, minute = None, second = None, microsecond = None):
     22         if any((x is not None and x != int(x) for x in (years, months))):
     23             raise ValueError('Non-integer years and months are ambiguous and not currently supported.')
     24         if dt1 and dt2:
     25             if not (isinstance(dt1, datetime.date) and isinstance(dt2, datetime.date)):
     26                 raise TypeError('relativedelta only diffs datetime/date')
     27             if isinstance(dt1, datetime.datetime) != isinstance(dt2, datetime.datetime):
     28                 if not isinstance(dt1, datetime.datetime):
     29                     dt1 = datetime.datetime.fromordinal(dt1.toordinal())
     30                 elif not isinstance(dt2, datetime.datetime):
     31                     dt2 = datetime.datetime.fromordinal(dt2.toordinal())
     32             self.years = 0
     33             self.months = 0
     34             self.days = 0
     35             self.leapdays = 0
     36             self.hours = 0
     37             self.minutes = 0
     38             self.seconds = 0
     39             self.microseconds = 0
     40             self.year = None
     41             self.month = None
     42             self.day = None
     43             self.weekday = None
     44             self.hour = None
     45             self.minute = None
     46             self.second = None
     47             self.microsecond = None
     48             self._has_time = 0
     49             months = (dt1.year - dt2.year) * 12 + (dt1.month - dt2.month)
     50             self._set_months(months)
     51             dtm = self.__radd__(dt2)
     52             if dt1 < dt2:
     53                 compare = operator.gt
     54                 increment = 1
     55             else:
     56                 compare = operator.lt
     57                 increment = -1
     58             while compare(dt1, dtm):
     59                 months += increment
     60                 self._set_months(months)
     61                 dtm = self.__radd__(dt2)
     62 
     63             delta = dt1 - dtm
     64             self.seconds = delta.seconds + delta.days * 86400
     65             self.microseconds = delta.microseconds
     66         else:
     67             self.years = years
     68             self.months = months
     69             self.days = days + weeks * 7
     70             self.leapdays = leapdays
     71             self.hours = hours
     72             self.minutes = minutes
     73             self.seconds = seconds
     74             self.microseconds = microseconds
     75             self.year = year
     76             self.month = month
     77             self.day = day
     78             self.hour = hour
     79             self.minute = minute
     80             self.second = second
     81             self.microsecond = microsecond
     82             if any((x is not None and int(x) != x for x in (year,
     83              month,
     84              day,
     85              hour,
     86              minute,
     87              second,
     88              microsecond))):
     89                 warn('Non-integer value passed as absolute information. ' + 'This is not a well-defined condition and will raise ' + 'errors in future versions.', DeprecationWarning)
     90             if isinstance(weekday, integer_types):
     91                 self.weekday = weekdays[weekday]
     92             else:
     93                 self.weekday = weekday
     94             yday = 0
     95             if nlyearday:
     96                 yday = nlyearday
     97             elif yearday:
     98                 yday = yearday
     99                 if yearday > 59:
    100                     self.leapdays = -1
    101             if yday:
    102                 ydayidx = [31,
    103                  59,
    104                  90,
    105                  120,
    106                  151,
    107                  181,
    108                  212,
    109                  243,
    110                  273,
    111                  304,
    112                  334,
    113                  366]
    114                 for idx, ydays in enumerate(ydayidx):
    115                     if yday <= ydays:
    116                         self.month = idx + 1
    117                         if idx == 0:
    118                             self.day = yday
    119                         else:
    120                             self.day = yday - ydayidx[idx - 1]
    121                         break
    122                 else:
    123                     raise ValueError('invalid year day (%d)' % yday)
    124 
    125         self._fix()
    126 
    127     def _fix(self):
    128         if abs(self.microseconds) > 999999:
    129             s = _sign(self.microseconds)
    130             div, mod = divmod(self.microseconds * s, 1000000)
    131             self.microseconds = mod * s
    132             self.seconds += div * s
    133         if abs(self.seconds) > 59:
    134             s = _sign(self.seconds)
    135             div, mod = divmod(self.seconds * s, 60)
    136             self.seconds = mod * s
    137             self.minutes += div * s
    138         if abs(self.minutes) > 59:
    139             s = _sign(self.minutes)
    140             div, mod = divmod(self.minutes * s, 60)
    141             self.minutes = mod * s
    142             self.hours += div * s
    143         if abs(self.hours) > 23:
    144             s = _sign(self.hours)
    145             div, mod = divmod(self.hours * s, 24)
    146             self.hours = mod * s
    147             self.days += div * s
    148         if abs(self.months) > 11:
    149             s = _sign(self.months)
    150             div, mod = divmod(self.months * s, 12)
    151             self.months = mod * s
    152             self.years += div * s
    153         if self.hours or self.minutes or self.seconds or self.microseconds or self.hour is not None or self.minute is not None or self.second is not None or self.microsecond is not None:
    154             self._has_time = 1
    155         else:
    156             self._has_time = 0
    157 
    158     @property
    159     def weeks(self):
    160         return self.days // 7
    161 
    162     @weeks.setter
    163     def weeks(self, value):
    164         self.days = self.days - self.weeks * 7 + value * 7
    165 
    166     def _set_months(self, months):
    167         self.months = months
    168         if abs(self.months) > 11:
    169             s = _sign(self.months)
    170             div, mod = divmod(self.months * s, 12)
    171             self.months = mod * s
    172             self.years = div * s
    173         else:
    174             self.years = 0
    175 
    176     def normalized(self):
    177         days = int(self.days)
    178         hours_f = round(self.hours + 24 * (self.days - days), 11)
    179         hours = int(hours_f)
    180         minutes_f = round(self.minutes + 60 * (hours_f - hours), 10)
    181         minutes = int(minutes_f)
    182         seconds_f = round(self.seconds + 60 * (minutes_f - minutes), 8)
    183         seconds = int(seconds_f)
    184         microseconds = round(self.microseconds + 1000000.0 * (seconds_f - seconds))
    185         return self.__class__(years=self.years, months=self.months, days=days, hours=hours, minutes=minutes, seconds=seconds, microseconds=microseconds, leapdays=self.leapdays, year=self.year, month=self.month, day=self.day, weekday=self.weekday, hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond)
    186 
    187     def __add__(self, other):
    188         if isinstance(other, relativedelta):
    189             return self.__class__(years=other.years + self.years, months=other.months + self.months, days=other.days + self.days, hours=other.hours + self.hours, minutes=other.minutes + self.minutes, seconds=other.seconds + self.seconds, microseconds=other.microseconds + self.microseconds, leapdays=other.leapdays or self.leapdays, year=other.year or self.year, month=other.month or self.month, day=other.day or self.day, weekday=other.weekday or self.weekday, hour=other.hour or self.hour, minute=other.minute or self.minute, second=other.second or self.second, microsecond=other.microsecond or self.microsecond)
    190         if isinstance(other, datetime.timedelta):
    191             return self.__class__(years=self.years, months=self.months, days=self.days + other.days, hours=self.hours, minutes=self.minutes, seconds=self.seconds + other.seconds, microseconds=self.microseconds + other.microseconds, leapdays=self.leapdays, year=self.year, month=self.month, day=self.day, weekday=self.weekday, hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond)
    192         if not isinstance(other, datetime.date):
    193             return NotImplemented
    194         if self._has_time and not isinstance(other, datetime.datetime):
    195             other = datetime.datetime.fromordinal(other.toordinal())
    196         year = (self.year or other.year) + self.years
    197         month = self.month or other.month
    198         if self.months:
    199             month += self.months
    200             if month > 12:
    201                 year += 1
    202                 month -= 12
    203             elif month < 1:
    204                 year -= 1
    205                 month += 12
    206         day = min(calendar.monthrange(year, month)[1], self.day or other.day)
    207         repl = {'year': year,
    208          'month': month,
    209          'day': day}
    210         for attr in ['hour',
    211          'minute',
    212          'second',
    213          'microsecond']:
    214             value = getattr(self, attr)
    215             if value is not None:
    216                 repl[attr] = value
    217 
    218         days = self.days
    219         if self.leapdays and month > 2 and calendar.isleap(year):
    220             days += self.leapdays
    221         ret = other.replace(**repl) + datetime.timedelta(days=days, hours=self.hours, minutes=self.minutes, seconds=self.seconds, microseconds=self.microseconds)
    222         if self.weekday:
    223             weekday, nth = self.weekday.weekday, self.weekday.n or 1
    224             jumpdays = (abs(nth) - 1) * 7
    225             if nth > 0:
    226                 jumpdays += (7 - ret.weekday() + weekday) % 7
    227             else:
    228                 jumpdays += (ret.weekday() - weekday) % 7
    229                 jumpdays *= -1
    230             ret += datetime.timedelta(days=jumpdays)
    231         return ret
    232 
    233     def __radd__(self, other):
    234         return self.__add__(other)
    235 
    236     def __rsub__(self, other):
    237         return self.__neg__().__radd__(other)
    238 
    239     def __sub__(self, other):
    240         if not isinstance(other, relativedelta):
    241             return NotImplemented
    242         return self.__class__(years=self.years - other.years, months=self.months - other.months, days=self.days - other.days, hours=self.hours - other.hours, minutes=self.minutes - other.minutes, seconds=self.seconds - other.seconds, microseconds=self.microseconds - other.microseconds, leapdays=self.leapdays or other.leapdays, year=self.year or other.year, month=self.month or other.month, day=self.day or other.day, weekday=self.weekday or other.weekday, hour=self.hour or other.hour, minute=self.minute or other.minute, second=self.second or other.second, microsecond=self.microsecond or other.microsecond)
    243 
    244     def __neg__(self):
    245         return self.__class__(years=-self.years, months=-self.months, days=-self.days, hours=-self.hours, minutes=-self.minutes, seconds=-self.seconds, microseconds=-self.microseconds, leapdays=self.leapdays, year=self.year, month=self.month, day=self.day, weekday=self.weekday, hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond)
    246 
    247     def __bool__(self):
    248         return not (not self.years and not self.months and not self.days and not self.hours and not self.minutes and not self.seconds and not self.microseconds and not self.leapdays and self.year is None and self.month is None and self.day is None and self.weekday is None and self.hour is None and self.minute is None and self.second is None and self.microsecond is None)
    249 
    250     __nonzero__ = __bool__
    251 
    252     def __mul__(self, other):
    253         try:
    254             f = float(other)
    255         except TypeError:
    256             return NotImplemented
    257 
    258         return self.__class__(years=int(self.years * f), months=int(self.months * f), days=int(self.days * f), hours=int(self.hours * f), minutes=int(self.minutes * f), seconds=int(self.seconds * f), microseconds=int(self.microseconds * f), leapdays=self.leapdays, year=self.year, month=self.month, day=self.day, weekday=self.weekday, hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond)
    259 
    260     __rmul__ = __mul__
    261 
    262     def __eq__(self, other):
    263         if not isinstance(other, relativedelta):
    264             return NotImplemented
    265         if self.weekday or other.weekday:
    266             if not self.weekday or not other.weekday:
    267                 return False
    268             if self.weekday.weekday != other.weekday.weekday:
    269                 return False
    270             n1, n2 = self.weekday.n, other.weekday.n
    271             if n1 != n2 and not ((not n1 or n1 == 1) and (not n2 or n2 == 1)):
    272                 return False
    273         return self.years == other.years and self.months == other.months and self.days == other.days and self.hours == other.hours and self.minutes == other.minutes and self.seconds == other.seconds and self.microseconds == other.microseconds and self.leapdays == other.leapdays and self.year == other.year and self.month == other.month and self.day == other.day and self.hour == other.hour and self.minute == other.minute and self.second == other.second and self.microsecond == other.microsecond
    274 
    275     __hash__ = None
    276 
    277     def __ne__(self, other):
    278         return not self.__eq__(other)
    279 
    280     def __div__(self, other):
    281         try:
    282             reciprocal = 1 / float(other)
    283         except TypeError:
    284             return NotImplemented
    285 
    286         return self.__mul__(reciprocal)
    287 
    288     __truediv__ = __div__
    289 
    290     def __repr__(self):
    291         l = []
    292         for attr in ['years',
    293          'months',
    294          'days',
    295          'leapdays',
    296          'hours',
    297          'minutes',
    298          'seconds',
    299          'microseconds']:
    300             value = getattr(self, attr)
    301             if value:
    302                 l.append('{attr}={value:+g}'.format(attr=attr, value=value))
    303 
    304         for attr in ['year',
    305          'month',
    306          'day',
    307          'weekday',
    308          'hour',
    309          'minute',
    310          'second',
    311          'microsecond']:
    312             value = getattr(self, attr)
    313             if value is not None:
    314                 l.append('{attr}={value}'.format(attr=attr, value=repr(value)))
    315 
    316         return '{classname}({attrs})'.format(classname=self.__class__.__name__, attrs=', '.join(l))
    317 
    318 
    319 def _sign(x):
    320     return int(copysign(1, x))