You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			600 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			Python
		
	
			
		
		
	
	
			600 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			Python
		
	
# -*- coding: utf-8 -*-
 | 
						|
import datetime
 | 
						|
import calendar
 | 
						|
 | 
						|
import operator
 | 
						|
from math import copysign
 | 
						|
 | 
						|
from six import integer_types
 | 
						|
from warnings import warn
 | 
						|
 | 
						|
from ._common import weekday
 | 
						|
 | 
						|
MO, TU, WE, TH, FR, SA, SU = weekdays = tuple(weekday(x) for x in range(7))
 | 
						|
 | 
						|
__all__ = ["relativedelta", "MO", "TU", "WE", "TH", "FR", "SA", "SU"]
 | 
						|
 | 
						|
 | 
						|
class relativedelta(object):
 | 
						|
    """
 | 
						|
    The relativedelta type is designed to be applied to an existing datetime and
 | 
						|
    can replace specific components of that datetime, or represents an interval
 | 
						|
    of time.
 | 
						|
 | 
						|
    It is based on the specification of the excellent work done by M.-A. Lemburg
 | 
						|
    in his
 | 
						|
    `mx.DateTime <https://www.egenix.com/products/python/mxBase/mxDateTime/>`_ extension.
 | 
						|
    However, notice that this type does *NOT* implement the same algorithm as
 | 
						|
    his work. Do *NOT* expect it to behave like mx.DateTime's counterpart.
 | 
						|
 | 
						|
    There are two different ways to build a relativedelta instance. The
 | 
						|
    first one is passing it two date/datetime classes::
 | 
						|
 | 
						|
        relativedelta(datetime1, datetime2)
 | 
						|
 | 
						|
    The second one is passing it any number of the following keyword arguments::
 | 
						|
 | 
						|
        relativedelta(arg1=x,arg2=y,arg3=z...)
 | 
						|
 | 
						|
        year, month, day, hour, minute, second, microsecond:
 | 
						|
            Absolute information (argument is singular); adding or subtracting a
 | 
						|
            relativedelta with absolute information does not perform an arithmetic
 | 
						|
            operation, but rather REPLACES the corresponding value in the
 | 
						|
            original datetime with the value(s) in relativedelta.
 | 
						|
 | 
						|
        years, months, weeks, days, hours, minutes, seconds, microseconds:
 | 
						|
            Relative information, may be negative (argument is plural); adding
 | 
						|
            or subtracting a relativedelta with relative information performs
 | 
						|
            the corresponding arithmetic operation on the original datetime value
 | 
						|
            with the information in the relativedelta.
 | 
						|
 | 
						|
        weekday:
 | 
						|
            One of the weekday instances (MO, TU, etc) available in the
 | 
						|
            relativedelta module. These instances may receive a parameter N,
 | 
						|
            specifying the Nth weekday, which could be positive or negative
 | 
						|
            (like MO(+1) or MO(-2)). Not specifying it is the same as specifying
 | 
						|
            +1. You can also use an integer, where 0=MO. This argument is always
 | 
						|
            relative e.g. if the calculated date is already Monday, using MO(1)
 | 
						|
            or MO(-1) won't change the day. To effectively make it absolute, use
 | 
						|
            it in combination with the day argument (e.g. day=1, MO(1) for first
 | 
						|
            Monday of the month).
 | 
						|
 | 
						|
        leapdays:
 | 
						|
            Will add given days to the date found, if year is a leap
 | 
						|
            year, and the date found is post 28 of february.
 | 
						|
 | 
						|
        yearday, nlyearday:
 | 
						|
            Set the yearday or the non-leap year day (jump leap days).
 | 
						|
            These are converted to day/month/leapdays information.
 | 
						|
 | 
						|
    There are relative and absolute forms of the keyword
 | 
						|
    arguments. The plural is relative, and the singular is
 | 
						|
    absolute. For each argument in the order below, the absolute form
 | 
						|
    is applied first (by setting each attribute to that value) and
 | 
						|
    then the relative form (by adding the value to the attribute).
 | 
						|
 | 
						|
    The order of attributes considered when this relativedelta is
 | 
						|
    added to a datetime is:
 | 
						|
 | 
						|
    1. Year
 | 
						|
    2. Month
 | 
						|
    3. Day
 | 
						|
    4. Hours
 | 
						|
    5. Minutes
 | 
						|
    6. Seconds
 | 
						|
    7. Microseconds
 | 
						|
 | 
						|
    Finally, weekday is applied, using the rule described above.
 | 
						|
 | 
						|
    For example
 | 
						|
 | 
						|
    >>> from datetime import datetime
 | 
						|
    >>> from dateutil.relativedelta import relativedelta, MO
 | 
						|
    >>> dt = datetime(2018, 4, 9, 13, 37, 0)
 | 
						|
    >>> delta = relativedelta(hours=25, day=1, weekday=MO(1))
 | 
						|
    >>> dt + delta
 | 
						|
    datetime.datetime(2018, 4, 2, 14, 37)
 | 
						|
 | 
						|
    First, the day is set to 1 (the first of the month), then 25 hours
 | 
						|
    are added, to get to the 2nd day and 14th hour, finally the
 | 
						|
    weekday is applied, but since the 2nd is already a Monday there is
 | 
						|
    no effect.
 | 
						|
 | 
						|
    """
 | 
						|
 | 
						|
    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):
 | 
						|
 | 
						|
        if dt1 and dt2:
 | 
						|
            # datetime is a subclass of date. So both must be date
 | 
						|
            if not (isinstance(dt1, datetime.date) and
 | 
						|
                    isinstance(dt2, datetime.date)):
 | 
						|
                raise TypeError("relativedelta only diffs datetime/date")
 | 
						|
 | 
						|
            # We allow two dates, or two datetimes, so we coerce them to be
 | 
						|
            # of the same type
 | 
						|
            if (isinstance(dt1, datetime.datetime) !=
 | 
						|
                    isinstance(dt2, datetime.datetime)):
 | 
						|
                if not isinstance(dt1, datetime.datetime):
 | 
						|
                    dt1 = datetime.datetime.fromordinal(dt1.toordinal())
 | 
						|
                elif not isinstance(dt2, datetime.datetime):
 | 
						|
                    dt2 = datetime.datetime.fromordinal(dt2.toordinal())
 | 
						|
 | 
						|
            self.years = 0
 | 
						|
            self.months = 0
 | 
						|
            self.days = 0
 | 
						|
            self.leapdays = 0
 | 
						|
            self.hours = 0
 | 
						|
            self.minutes = 0
 | 
						|
            self.seconds = 0
 | 
						|
            self.microseconds = 0
 | 
						|
            self.year = None
 | 
						|
            self.month = None
 | 
						|
            self.day = None
 | 
						|
            self.weekday = None
 | 
						|
            self.hour = None
 | 
						|
            self.minute = None
 | 
						|
            self.second = None
 | 
						|
            self.microsecond = None
 | 
						|
            self._has_time = 0
 | 
						|
 | 
						|
            # Get year / month delta between the two
 | 
						|
            months = (dt1.year - dt2.year) * 12 + (dt1.month - dt2.month)
 | 
						|
            self._set_months(months)
 | 
						|
 | 
						|
            # Remove the year/month delta so the timedelta is just well-defined
 | 
						|
            # time units (seconds, days and microseconds)
 | 
						|
            dtm = self.__radd__(dt2)
 | 
						|
 | 
						|
            # If we've overshot our target, make an adjustment
 | 
						|
            if dt1 < dt2:
 | 
						|
                compare = operator.gt
 | 
						|
                increment = 1
 | 
						|
            else:
 | 
						|
                compare = operator.lt
 | 
						|
                increment = -1
 | 
						|
 | 
						|
            while compare(dt1, dtm):
 | 
						|
                months += increment
 | 
						|
                self._set_months(months)
 | 
						|
                dtm = self.__radd__(dt2)
 | 
						|
 | 
						|
            # Get the timedelta between the "months-adjusted" date and dt1
 | 
						|
            delta = dt1 - dtm
 | 
						|
            self.seconds = delta.seconds + delta.days * 86400
 | 
						|
            self.microseconds = delta.microseconds
 | 
						|
        else:
 | 
						|
            # Check for non-integer values in integer-only quantities
 | 
						|
            if any(x is not None and x != int(x) for x in (years, months)):
 | 
						|
                raise ValueError("Non-integer years and months are "
 | 
						|
                                 "ambiguous and not currently supported.")
 | 
						|
 | 
						|
            # Relative information
 | 
						|
            self.years = int(years)
 | 
						|
            self.months = int(months)
 | 
						|
            self.days = days + weeks * 7
 | 
						|
            self.leapdays = leapdays
 | 
						|
            self.hours = hours
 | 
						|
            self.minutes = minutes
 | 
						|
            self.seconds = seconds
 | 
						|
            self.microseconds = microseconds
 | 
						|
 | 
						|
            # Absolute information
 | 
						|
            self.year = year
 | 
						|
            self.month = month
 | 
						|
            self.day = day
 | 
						|
            self.hour = hour
 | 
						|
            self.minute = minute
 | 
						|
            self.second = second
 | 
						|
            self.microsecond = microsecond
 | 
						|
 | 
						|
            if any(x is not None and int(x) != x
 | 
						|
                   for x in (year, month, day, hour,
 | 
						|
                             minute, second, microsecond)):
 | 
						|
                # For now we'll deprecate floats - later it'll be an error.
 | 
						|
                warn("Non-integer value passed as absolute information. " +
 | 
						|
                     "This is not a well-defined condition and will raise " +
 | 
						|
                     "errors in future versions.", DeprecationWarning)
 | 
						|
 | 
						|
            if isinstance(weekday, integer_types):
 | 
						|
                self.weekday = weekdays[weekday]
 | 
						|
            else:
 | 
						|
                self.weekday = weekday
 | 
						|
 | 
						|
            yday = 0
 | 
						|
            if nlyearday:
 | 
						|
                yday = nlyearday
 | 
						|
            elif yearday:
 | 
						|
                yday = yearday
 | 
						|
                if yearday > 59:
 | 
						|
                    self.leapdays = -1
 | 
						|
            if yday:
 | 
						|
                ydayidx = [31, 59, 90, 120, 151, 181, 212,
 | 
						|
                           243, 273, 304, 334, 366]
 | 
						|
                for idx, ydays in enumerate(ydayidx):
 | 
						|
                    if yday <= ydays:
 | 
						|
                        self.month = idx+1
 | 
						|
                        if idx == 0:
 | 
						|
                            self.day = yday
 | 
						|
                        else:
 | 
						|
                            self.day = yday-ydayidx[idx-1]
 | 
						|
                        break
 | 
						|
                else:
 | 
						|
                    raise ValueError("invalid year day (%d)" % yday)
 | 
						|
 | 
						|
        self._fix()
 | 
						|
 | 
						|
    def _fix(self):
 | 
						|
        if abs(self.microseconds) > 999999:
 | 
						|
            s = _sign(self.microseconds)
 | 
						|
            div, mod = divmod(self.microseconds * s, 1000000)
 | 
						|
            self.microseconds = mod * s
 | 
						|
            self.seconds += div * s
 | 
						|
        if abs(self.seconds) > 59:
 | 
						|
            s = _sign(self.seconds)
 | 
						|
            div, mod = divmod(self.seconds * s, 60)
 | 
						|
            self.seconds = mod * s
 | 
						|
            self.minutes += div * s
 | 
						|
        if abs(self.minutes) > 59:
 | 
						|
            s = _sign(self.minutes)
 | 
						|
            div, mod = divmod(self.minutes * s, 60)
 | 
						|
            self.minutes = mod * s
 | 
						|
            self.hours += div * s
 | 
						|
        if abs(self.hours) > 23:
 | 
						|
            s = _sign(self.hours)
 | 
						|
            div, mod = divmod(self.hours * s, 24)
 | 
						|
            self.hours = mod * s
 | 
						|
            self.days += div * s
 | 
						|
        if abs(self.months) > 11:
 | 
						|
            s = _sign(self.months)
 | 
						|
            div, mod = divmod(self.months * s, 12)
 | 
						|
            self.months = mod * s
 | 
						|
            self.years += div * s
 | 
						|
        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):
 | 
						|
            self._has_time = 1
 | 
						|
        else:
 | 
						|
            self._has_time = 0
 | 
						|
 | 
						|
    @property
 | 
						|
    def weeks(self):
 | 
						|
        return int(self.days / 7.0)
 | 
						|
 | 
						|
    @weeks.setter
 | 
						|
    def weeks(self, value):
 | 
						|
        self.days = self.days - (self.weeks * 7) + value * 7
 | 
						|
 | 
						|
    def _set_months(self, months):
 | 
						|
        self.months = months
 | 
						|
        if abs(self.months) > 11:
 | 
						|
            s = _sign(self.months)
 | 
						|
            div, mod = divmod(self.months * s, 12)
 | 
						|
            self.months = mod * s
 | 
						|
            self.years = div * s
 | 
						|
        else:
 | 
						|
            self.years = 0
 | 
						|
 | 
						|
    def normalized(self):
 | 
						|
        """
 | 
						|
        Return a version of this object represented entirely using integer
 | 
						|
        values for the relative attributes.
 | 
						|
 | 
						|
        >>> relativedelta(days=1.5, hours=2).normalized()
 | 
						|
        relativedelta(days=+1, hours=+14)
 | 
						|
 | 
						|
        :return:
 | 
						|
            Returns a :class:`dateutil.relativedelta.relativedelta` object.
 | 
						|
        """
 | 
						|
        # Cascade remainders down (rounding each to roughly nearest microsecond)
 | 
						|
        days = int(self.days)
 | 
						|
 | 
						|
        hours_f = round(self.hours + 24 * (self.days - days), 11)
 | 
						|
        hours = int(hours_f)
 | 
						|
 | 
						|
        minutes_f = round(self.minutes + 60 * (hours_f - hours), 10)
 | 
						|
        minutes = int(minutes_f)
 | 
						|
 | 
						|
        seconds_f = round(self.seconds + 60 * (minutes_f - minutes), 8)
 | 
						|
        seconds = int(seconds_f)
 | 
						|
 | 
						|
        microseconds = round(self.microseconds + 1e6 * (seconds_f - seconds))
 | 
						|
 | 
						|
        # Constructor carries overflow back up with call to _fix()
 | 
						|
        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)
 | 
						|
 | 
						|
    def __add__(self, other):
 | 
						|
        if isinstance(other, relativedelta):
 | 
						|
            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 if other.year is not None
 | 
						|
                                       else self.year),
 | 
						|
                                 month=(other.month if other.month is not None
 | 
						|
                                        else self.month),
 | 
						|
                                 day=(other.day if other.day is not None
 | 
						|
                                      else self.day),
 | 
						|
                                 weekday=(other.weekday if other.weekday is not None
 | 
						|
                                          else self.weekday),
 | 
						|
                                 hour=(other.hour if other.hour is not None
 | 
						|
                                       else self.hour),
 | 
						|
                                 minute=(other.minute if other.minute is not None
 | 
						|
                                         else self.minute),
 | 
						|
                                 second=(other.second if other.second is not None
 | 
						|
                                         else self.second),
 | 
						|
                                 microsecond=(other.microsecond if other.microsecond
 | 
						|
                                              is not None else
 | 
						|
                                              self.microsecond))
 | 
						|
        if isinstance(other, datetime.timedelta):
 | 
						|
            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)
 | 
						|
        if not isinstance(other, datetime.date):
 | 
						|
            return NotImplemented
 | 
						|
        elif self._has_time and not isinstance(other, datetime.datetime):
 | 
						|
            other = datetime.datetime.fromordinal(other.toordinal())
 | 
						|
        year = (self.year or other.year)+self.years
 | 
						|
        month = self.month or other.month
 | 
						|
        if self.months:
 | 
						|
            assert 1 <= abs(self.months) <= 12
 | 
						|
            month += self.months
 | 
						|
            if month > 12:
 | 
						|
                year += 1
 | 
						|
                month -= 12
 | 
						|
            elif month < 1:
 | 
						|
                year -= 1
 | 
						|
                month += 12
 | 
						|
        day = min(calendar.monthrange(year, month)[1],
 | 
						|
                  self.day or other.day)
 | 
						|
        repl = {"year": year, "month": month, "day": day}
 | 
						|
        for attr in ["hour", "minute", "second", "microsecond"]:
 | 
						|
            value = getattr(self, attr)
 | 
						|
            if value is not None:
 | 
						|
                repl[attr] = value
 | 
						|
        days = self.days
 | 
						|
        if self.leapdays and month > 2 and calendar.isleap(year):
 | 
						|
            days += self.leapdays
 | 
						|
        ret = (other.replace(**repl)
 | 
						|
               + datetime.timedelta(days=days,
 | 
						|
                                    hours=self.hours,
 | 
						|
                                    minutes=self.minutes,
 | 
						|
                                    seconds=self.seconds,
 | 
						|
                                    microseconds=self.microseconds))
 | 
						|
        if self.weekday:
 | 
						|
            weekday, nth = self.weekday.weekday, self.weekday.n or 1
 | 
						|
            jumpdays = (abs(nth) - 1) * 7
 | 
						|
            if nth > 0:
 | 
						|
                jumpdays += (7 - ret.weekday() + weekday) % 7
 | 
						|
            else:
 | 
						|
                jumpdays += (ret.weekday() - weekday) % 7
 | 
						|
                jumpdays *= -1
 | 
						|
            ret += datetime.timedelta(days=jumpdays)
 | 
						|
        return ret
 | 
						|
 | 
						|
    def __radd__(self, other):
 | 
						|
        return self.__add__(other)
 | 
						|
 | 
						|
    def __rsub__(self, other):
 | 
						|
        return self.__neg__().__radd__(other)
 | 
						|
 | 
						|
    def __sub__(self, other):
 | 
						|
        if not isinstance(other, relativedelta):
 | 
						|
            return NotImplemented   # In case the other object defines __rsub__
 | 
						|
        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 if self.year is not None
 | 
						|
                                   else other.year),
 | 
						|
                             month=(self.month if self.month is not None else
 | 
						|
                                    other.month),
 | 
						|
                             day=(self.day if self.day is not None else
 | 
						|
                                  other.day),
 | 
						|
                             weekday=(self.weekday if self.weekday is not None else
 | 
						|
                                      other.weekday),
 | 
						|
                             hour=(self.hour if self.hour is not None else
 | 
						|
                                   other.hour),
 | 
						|
                             minute=(self.minute if self.minute is not None else
 | 
						|
                                     other.minute),
 | 
						|
                             second=(self.second if self.second is not None else
 | 
						|
                                     other.second),
 | 
						|
                             microsecond=(self.microsecond if self.microsecond
 | 
						|
                                          is not None else
 | 
						|
                                          other.microsecond))
 | 
						|
 | 
						|
    def __abs__(self):
 | 
						|
        return self.__class__(years=abs(self.years),
 | 
						|
                              months=abs(self.months),
 | 
						|
                              days=abs(self.days),
 | 
						|
                              hours=abs(self.hours),
 | 
						|
                              minutes=abs(self.minutes),
 | 
						|
                              seconds=abs(self.seconds),
 | 
						|
                              microseconds=abs(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)
 | 
						|
 | 
						|
    def __neg__(self):
 | 
						|
        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)
 | 
						|
 | 
						|
    def __bool__(self):
 | 
						|
        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)
 | 
						|
    # Compatibility with Python 2.x
 | 
						|
    __nonzero__ = __bool__
 | 
						|
 | 
						|
    def __mul__(self, other):
 | 
						|
        try:
 | 
						|
            f = float(other)
 | 
						|
        except TypeError:
 | 
						|
            return NotImplemented
 | 
						|
 | 
						|
        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)
 | 
						|
 | 
						|
    __rmul__ = __mul__
 | 
						|
 | 
						|
    def __eq__(self, other):
 | 
						|
        if not isinstance(other, relativedelta):
 | 
						|
            return NotImplemented
 | 
						|
        if self.weekday or other.weekday:
 | 
						|
            if not self.weekday or not other.weekday:
 | 
						|
                return False
 | 
						|
            if self.weekday.weekday != other.weekday.weekday:
 | 
						|
                return False
 | 
						|
            n1, n2 = self.weekday.n, other.weekday.n
 | 
						|
            if n1 != n2 and not ((not n1 or n1 == 1) and (not n2 or n2 == 1)):
 | 
						|
                return False
 | 
						|
        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)
 | 
						|
 | 
						|
    def __hash__(self):
 | 
						|
        return hash((
 | 
						|
            self.weekday,
 | 
						|
            self.years,
 | 
						|
            self.months,
 | 
						|
            self.days,
 | 
						|
            self.hours,
 | 
						|
            self.minutes,
 | 
						|
            self.seconds,
 | 
						|
            self.microseconds,
 | 
						|
            self.leapdays,
 | 
						|
            self.year,
 | 
						|
            self.month,
 | 
						|
            self.day,
 | 
						|
            self.hour,
 | 
						|
            self.minute,
 | 
						|
            self.second,
 | 
						|
            self.microsecond,
 | 
						|
        ))
 | 
						|
 | 
						|
    def __ne__(self, other):
 | 
						|
        return not self.__eq__(other)
 | 
						|
 | 
						|
    def __div__(self, other):
 | 
						|
        try:
 | 
						|
            reciprocal = 1 / float(other)
 | 
						|
        except TypeError:
 | 
						|
            return NotImplemented
 | 
						|
 | 
						|
        return self.__mul__(reciprocal)
 | 
						|
 | 
						|
    __truediv__ = __div__
 | 
						|
 | 
						|
    def __repr__(self):
 | 
						|
        l = []
 | 
						|
        for attr in ["years", "months", "days", "leapdays",
 | 
						|
                     "hours", "minutes", "seconds", "microseconds"]:
 | 
						|
            value = getattr(self, attr)
 | 
						|
            if value:
 | 
						|
                l.append("{attr}={value:+g}".format(attr=attr, value=value))
 | 
						|
        for attr in ["year", "month", "day", "weekday",
 | 
						|
                     "hour", "minute", "second", "microsecond"]:
 | 
						|
            value = getattr(self, attr)
 | 
						|
            if value is not None:
 | 
						|
                l.append("{attr}={value}".format(attr=attr, value=repr(value)))
 | 
						|
        return "{classname}({attrs})".format(classname=self.__class__.__name__,
 | 
						|
                                             attrs=", ".join(l))
 | 
						|
 | 
						|
 | 
						|
def _sign(x):
 | 
						|
    return int(copysign(1, x))
 | 
						|
 | 
						|
# vim:ts=4:sw=4:et
 |