예제 #1
0
    def range_check_date(cls, YYYY=None, MM=None, DD=None,
                         Www=None, D=None, DDD=None, rangedict=None):
        if rangedict is None:
            rangedict = cls.DATE_RANGE_DICT

        if 'YYYY' in rangedict:
            YYYY = rangedict['YYYY'].rangefunc(YYYY, rangedict['YYYY'])

        if 'MM' in rangedict:
            MM = rangedict['MM'].rangefunc(MM, rangedict['MM'])

        if 'DD' in rangedict:
            DD = rangedict['DD'].rangefunc(DD, rangedict['DD'])

        if 'Www' in rangedict:
            Www = rangedict['Www'].rangefunc(Www, rangedict['Www'])

        if 'D' in rangedict:
            D = rangedict['D'].rangefunc(D, rangedict['D'])

        if 'DDD' in rangedict:
            DDD = rangedict['DDD'].rangefunc(DDD, rangedict['DDD'])

        if DD is not None:
            #Check calendar
            if DD > calendar.monthrange(YYYY, MM)[1]:
                raise DayOutOfBoundsError('{0} is out of range for {1}-{2}'.format(DD, YYYY, MM))

        if DDD is not None:
            if calendar.isleap(YYYY) is False and DDD == 366:
                raise DayOutOfBoundsError('{0} is only valid for leap year.'.format(DDD))

        return (YYYY, MM, DD, Www, D, DDD)
예제 #2
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)
예제 #3
0
파일: python.py 프로젝트: otr0624/StoreApp
    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)
예제 #4
0
    def range_check_date(cls,
                         YYYY=None,
                         MM=None,
                         DD=None,
                         Www=None,
                         D=None,
                         DDD=None,
                         rangedict=None):
        if rangedict is None:
            rangedict = cls.DATE_RANGE_DICT

        if "YYYY" in rangedict:
            YYYY = rangedict["YYYY"].rangefunc(YYYY, rangedict["YYYY"])

        if "MM" in rangedict:
            MM = rangedict["MM"].rangefunc(MM, rangedict["MM"])

        if "DD" in rangedict:
            DD = rangedict["DD"].rangefunc(DD, rangedict["DD"])

        if "Www" in rangedict:
            Www = rangedict["Www"].rangefunc(Www, rangedict["Www"])

        if "D" in rangedict:
            D = rangedict["D"].rangefunc(D, rangedict["D"])

        if "DDD" in rangedict:
            DDD = rangedict["DDD"].rangefunc(DDD, rangedict["DDD"])

        if DD is not None:
            # Check calendar
            if DD > calendar.monthrange(YYYY, MM)[1]:
                raise DayOutOfBoundsError(
                    "{0} is out of range for {1}-{2}".format(DD, YYYY, MM))

        if DDD is not None:
            if calendar.isleap(YYYY) is False and DDD == 366:
                raise DayOutOfBoundsError(
                    "{0} is only valid for leap year.".format(DDD))

        return (YYYY, MM, DD, Www, D, DDD)
예제 #5
0
    def _build_ordinal_date(isoyear, isoday):
        # Day of year to a date
        # https://stackoverflow.com/questions/2427555/python-question-year-and-day-of-year-to-date
        builtdate = datetime.date(isoyear, 1,
                                  1) + datetime.timedelta(days=isoday - 1)

        # Enforce ordinal day limitation
        # https://bitbucket.org/nielsenb/aniso8601/issues/14/parsing-ordinal-dates-should-only-allow
        if isoday == 0 or builtdate.year != isoyear:
            raise DayOutOfBoundsError("Day of year must be from 1..365, "
                                      "1..366 for leap year.")

        return builtdate
예제 #6
0
def _parse_ordinal_date(datestr):
    #datestr is of the format YYYY-DDD or YYYYDDD
    #DDD can be from 1 - 36[5,6], this matches Python's definition

    isoyear = int(datestr[0:4])

    if datestr.find('-') != -1:
        #YYYY-DDD
        isoday = int(datestr[(datestr.find('-') + 1):])
    else:
        #YYYYDDD
        isoday = int(datestr[4:])

    parseddate = datetime.date(isoyear, 1,
                               1) + datetime.timedelta(days=isoday - 1)

    #Enforce ordinal day limitation
    #https://bitbucket.org/nielsenb/aniso8601/issues/14/parsing-ordinal-dates-should-only-allow
    if isoday == 0 or parseddate.year != isoyear:
        raise DayOutOfBoundsError(
            'Day of year must be from 1..365, 1..366 for leap year.')

    return parseddate
예제 #7
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))