Beispiel #1
0
    def range_check_interval(cls, start=None, end=None, duration=None):
        #Handles concise format, range checks any potential durations
        if start is not None and end is not None:
            #<start>/<end>
            #Handle concise format
            if cls._is_interval_end_concise(end) is True:
                end = cls._combine_concise_interval_tuples(start, end)

            return (start, end, duration)

        durationobject = cls._build_object(duration)

        if end is not None:
            #<duration>/<end>
            endobject = cls._build_object(end)

            #Range check
            if type(end) is DateTuple:
                enddatetime = cls.build_datetime(end,
                                                 TupleBuilder.build_time())

                if enddatetime - datetime.datetime.min < durationobject:
                    raise YearOutOfBoundsError(
                        'Interval end less than minimium date.')
            else:
                mindatetime = datetime.datetime.min

                if end.time.tz is not None:
                    mindatetime = mindatetime.replace(tzinfo=endobject.tzinfo)

                if endobject - mindatetime < durationobject:
                    raise YearOutOfBoundsError(
                        'Interval end less than minimium date.')
        else:
            #<start>/<duration>
            startobject = cls._build_object(start)

            #Range check
            if type(start) is DateTuple:
                startdatetime = cls.build_datetime(start,
                                                   TupleBuilder.build_time())

                if datetime.datetime.max - startdatetime < durationobject:
                    raise YearOutOfBoundsError(
                        'Interval end greater than maximum date.')
            else:
                maxdatetime = datetime.datetime.max

                if start.time.tz is not None:
                    maxdatetime = maxdatetime.replace(
                        tzinfo=startobject.tzinfo)

                if maxdatetime - startobject < durationobject:
                    raise YearOutOfBoundsError(
                        'Interval end greater than maximum date.')

        return (start, end, duration)
Beispiel #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)
Beispiel #3
0
def _parse_year(yearstr):
    #yearstr is of the format Y[YYY]
    #
    #0000 (1 BC) is not representible as a Python date so a ValueError is
    #raised
    #
    #Truncated dates, like '19', refer to 1900-1999 inclusive, we simply parse
    #to 1900-01-01
    #
    #Since no additional resolution is provided, the month is set to 1, and
    #day is set to 1

    if len(yearstr) == 4:
        isoyear = int(yearstr)
    else:
        #Shift 0s in from the left to form complete year
        isoyear = int(yearstr.ljust(4, '0'))

    if isoyear == 0:
        raise YearOutOfBoundsError('Year must be between 1..9999.')

    return datetime.date(isoyear, 1, 1)
Beispiel #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))