示例#1
0
def _parse_week_day(datestr):
    #datestr is of the format YYYY-Www-D, YYYYWwwD
    #
    #W is the week number prefix, ww is the week number, between 1 and 53
    #0 is not a valid week number, which differs from the Python implementation
    #
    #D is the weekday number, between 1 and 7, which differs from the Python
    #implementation which is between 0 and 6

    isoyear = int(datestr[0:4])
    gregorianyearstart = _iso_year_start(isoyear)

    #Week number will be the two characters after the W
    windex = datestr.find('W')
    isoweeknumber = int(datestr[windex + 1:windex + 3])

    if isoweeknumber == 0 or isoweeknumber > 53:
        raise WeekOutOfBoundsError('Week number must be between 1..53.')

    if datestr.find('-') != -1 and len(datestr) == 10:
        #YYYY-Www-D
        isoday = int(datestr[9:10])
    elif len(datestr) == 8:
        #YYYYWwwD
        isoday = int(datestr[7:8])
    else:
        raise ISOFormatError(
            '"{0}" is not a valid ISO 8601 week date.'.format(datestr))

    if isoday == 0 or isoday > 7:
        raise DayOutOfBoundsError('Weekday number must be between 1..7.')

    return gregorianyearstart + datetime.timedelta(weeks=isoweeknumber - 1,
                                                   days=isoday - 1)
示例#2
0
    def build_date(cls, YYYY=None, MM=None, DD=None, Www=None, D=None, DDD=None):

        if YYYY is not None:
            # Truncated dates, like '19', refer to 1900-1999 inclusive,
            # we simply parse to 1900
            if len(YYYY) < 4:
                # Shift 0s in from the left to form complete year
                YYYY = YYYY.ljust(4, "0")

            year = cls.cast(YYYY, int, thrownmessage="Invalid year string.")

        if MM is not None:
            month = cls.cast(MM, int, thrownmessage="Invalid month string.")
        else:
            month = 1

        if DD is not None:
            day = cls.cast(DD, int, thrownmessage="Invalid day string.")
        else:
            day = 1

        if Www is not None:
            weeknumber = cls.cast(Www, int, thrownmessage="Invalid week string.")

            if weeknumber == 0 or weeknumber > 53:
                raise WeekOutOfBoundsError("Week number must be between " "1..53.")
        else:
            weeknumber = None

        if DDD is not None:
            dayofyear = cls.cast(DDD, int, thrownmessage="Invalid day string.")
        else:
            dayofyear = None

        if D is not None:
            dayofweek = cls.cast(D, int, thrownmessage="Invalid day string.")

            if dayofweek == 0 or dayofweek > 7:
                raise DayOutOfBoundsError("Weekday number must be between " "1..7.")
        else:
            dayofweek = None

        # 0000 (1 BC) is not representable as a Python date so a ValueError is
        # raised
        if year == 0:
            raise YearOutOfBoundsError("Year must be between 1..9999.")

        if dayofyear is not None:
            return PythonTimeBuilder._build_ordinal_date(year, dayofyear)

        if weeknumber is not None:
            return PythonTimeBuilder._build_week_date(
                year, weeknumber, isoday=dayofweek
            )

        return datetime.date(year, month, day)
示例#3
0
def _parse_week(datestr):
    #datestr is of the format YYYY-Www, YYYYWww
    #
    #W is the week number prefix, ww is the week number, between 1 and 53
    #0 is not a valid week number, which differs from the Python implementation

    isoyear = int(datestr[0:4])
    gregorianyearstart = _iso_year_start(isoyear)

    #Week number will be the two characters after the W
    windex = datestr.find('W')
    isoweeknumber = int(datestr[windex + 1:windex + 3])

    if isoweeknumber == 0 or isoweeknumber > 53:
        raise WeekOutOfBoundsError('Week number must be between 1..53.')

    return gregorianyearstart + datetime.timedelta(weeks=isoweeknumber - 1,
                                                   days=0)
示例#4
0
    def range_check_duration(cls,
                             PnY=None,
                             PnM=None,
                             PnW=None,
                             PnD=None,
                             TnH=None,
                             TnM=None,
                             TnS=None,
                             rangedict=None):
        years = 0
        months = 0
        days = 0
        weeks = 0
        hours = 0
        minutes = 0
        seconds = 0
        microseconds = 0

        PnY, PnM, PnW, PnD, TnH, TnM, TnS = BaseTimeBuilder.range_check_duration(
            PnY,
            PnM,
            PnW,
            PnD,
            TnH,
            TnM,
            TnS,
            rangedict=cls.DURATION_RANGE_DICT)

        if PnY is not None:
            if type(PnY) is FractionalComponent:
                years = PnY.principal
                microseconds = PnY.microsecondremainder
            else:
                years = PnY

            if years * DAYS_PER_YEAR > TIMEDELTA_MAX_DAYS:
                raise YearOutOfBoundsError(
                    'Duration exceeds maximum timedelta size.')

        if PnM is not None:
            if type(PnM) is FractionalComponent:
                months = PnM.principal
                microseconds = PnM.microsecondremainder
            else:
                months = PnM

            if months * DAYS_PER_MONTH > TIMEDELTA_MAX_DAYS:
                raise MonthOutOfBoundsError(
                    'Duration exceeds maximum timedelta size.')

        if PnW is not None:
            if type(PnW) is FractionalComponent:
                weeks = PnW.principal
                microseconds = PnW.microsecondremainder
            else:
                weeks = PnW

            if weeks * DAYS_PER_WEEK > TIMEDELTA_MAX_DAYS:
                raise WeekOutOfBoundsError(
                    'Duration exceeds maximum timedelta size.')

        if PnD is not None:
            if type(PnD) is FractionalComponent:
                days = PnD.principal
                microseconds = PnD.microsecondremainder
            else:
                days = PnD

            if days > TIMEDELTA_MAX_DAYS:
                raise DayOutOfBoundsError(
                    'Duration exceeds maximum timedelta size.')

        if TnH is not None:
            if type(TnH) is FractionalComponent:
                hours = TnH.principal
                microseconds = TnH.microsecondremainder
            else:
                hours = TnH

            if hours // HOURS_PER_DAY > TIMEDELTA_MAX_DAYS:
                raise HoursOutOfBoundsError(
                    'Duration exceeds maximum timedelta size.')

        if TnM is not None:
            if type(TnM) is FractionalComponent:
                minutes = TnM.principal
                microseconds = TnM.microsecondremainder
            else:
                minutes = TnM

            if minutes // MINUTES_PER_DAY > TIMEDELTA_MAX_DAYS:
                raise MinutesOutOfBoundsError(
                    'Duration exceeds maximum timedelta size.')

        if TnS is not None:
            if type(TnS) is FractionalComponent:
                seconds = TnS.principal
                microseconds = TnS.microsecondremainder
            else:
                seconds = TnS

            if seconds // SECONDS_PER_DAY > TIMEDELTA_MAX_DAYS:
                raise SecondsOutOfBoundsError(
                    'Duration exceeds maximum timedelta size.')

        years, months, weeks, days, hours, minutes, seconds, microseconds = PythonTimeBuilder._distribute_microseconds(
            microseconds,
            (years, months, weeks, days, hours, minutes, seconds),
            (MICROSECONDS_PER_YEAR, MICROSECONDS_PER_MONTH,
             MICROSECONDS_PER_WEEK, MICROSECONDS_PER_DAY,
             MICROSECONDS_PER_HOUR, MICROSECONDS_PER_MINUTE,
             MICROSECONDS_PER_SECOND))

        #Note that weeks can be handled without conversion to days
        totaldays = years * DAYS_PER_YEAR + months * DAYS_PER_MONTH + days

        #Check against timedelta limits
        if totaldays + weeks * DAYS_PER_WEEK + hours // HOURS_PER_DAY + minutes // MINUTES_PER_DAY + seconds // SECONDS_PER_DAY > TIMEDELTA_MAX_DAYS:
            raise DayOutOfBoundsError(
                'Duration exceeds maximum timedelta size.')

        return (None, None, weeks, totaldays, hours, minutes,
                FractionalComponent(seconds, microseconds))