示例#1
0
def _parse_minute_time(timestr):
    #Format must be hhmm, hhmm., hh:mm or hh:mm.
    if timestr.count(':') == 1:
        #hh:mm or hh:mm.
        timestrarray = timestr.split(':')

        isohour = int(timestrarray[0])
        isominute = float(timestrarray[1])  #Minute may now be a fraction
    else:
        #hhmm or hhmm.
        isohour = int(timestr[0:2])
        isominute = float(timestr[2:])

    if isominute >= 60:
        raise MinutesOutOfBoundsError('Minutes must be less than 60.')

    if isohour == 24:
        if isominute != 0:
            raise MidnightBoundsError('Hour 24 may only represent midnight.')

        return datetime.time(hour=0, minute=0)

    #Since the time constructor doesn't handle fractional minutes, we put
    #the minutes in to a timedelta, and add it to the time before returning
    minutesdelta = datetime.timedelta(minutes=isominute)

    return _build_time(datetime.time(hour=isohour), minutesdelta)
示例#2
0
def _parse_second_time(timestr):
    #Format must be hhmmss, hhmmss., hh:mm:ss or hh:mm:ss.
    if timestr.count(':') == 2:
        #hh:mm:ss or hh:mm:ss.
        timestrarray = timestr.split(':')

        isohour = int(timestrarray[0])
        isominute = int(timestrarray[1])

        #Since the time constructor doesn't handle fractional seconds, we put
        #the seconds in to a timedelta, and add it to the time before returning
        #The seconds value is truncated to microsecond resolution before
        #conversion:
        #https://bitbucket.org/nielsenb/aniso8601/issues/10/sub-microsecond-precision-in-durations-is
        secondsdelta = datetime.timedelta(seconds=float(timestrarray[2][:9]))
    else:
        #hhmmss or hhmmss.
        isohour = int(timestr[0:2])
        isominute = int(timestr[2:4])

        #Since the time constructor doesn't handle fractional seconds, we put
        #the seconds in to a timedelta, and add it to the time before returning
        #The seconds value is truncated to microsecond resolution before
        #conversion:
        #https://bitbucket.org/nielsenb/aniso8601/issues/10/sub-microsecond-precision-in-durations-is
        secondsdelta = datetime.timedelta(seconds=float(timestr[4:13]))

    if isohour == 23 and isominute == 59 and secondsdelta.seconds == 60:
        #https://bitbucket.org/nielsenb/aniso8601/issues/10/sub-microsecond-precision-in-durations-is
        raise LeapSecondError('Leap seconds are not supported.')
    elif secondsdelta.seconds >= 60:
        #https://bitbucket.org/nielsenb/aniso8601/issues/13/parsing-of-leap-second-gives-wildly
        raise SecondsOutOfBoundsError('Seconds must be less than 60.')

    if isominute >= 60:
        raise MinutesOutOfBoundsError('Minutes must be less than 60.')

    if isohour == 24:
        #Midnight, see 4.2.1, 4.2.3
        if isominute != 0 or secondsdelta.total_seconds() != 0:
            raise MidnightBoundsError('Hour 24 may only represent midnight.')

        return datetime.time(hour=0, minute=0)

    return _build_time(datetime.time(hour=isohour, minute=isominute),
                       secondsdelta)
示例#3
0
    def build_time(cls, hh=None, mm=None, ss=None, tz=None):
        # Builds a time from the given parts, handling fractional arguments
        # where necessary
        hours = 0
        minutes = 0
        seconds = 0
        microseconds = 0

        if hh is not None:
            if "." in hh:
                hours, remainingmicroseconds = cls._split_to_microseconds(
                    hh, MICROSECONDS_PER_HOUR, "Invalid hour string.")
                microseconds += remainingmicroseconds
            else:
                hours = cls.cast(hh, int, thrownmessage="Invalid hour string.")

        if mm is not None:
            if "." in mm:
                minutes, remainingmicroseconds = cls._split_to_microseconds(
                    mm, MICROSECONDS_PER_MINUTE, "Invalid minute string.")
                microseconds += remainingmicroseconds
            else:
                minutes = cls.cast(mm,
                                   int,
                                   thrownmessage="Invalid minute string.")

        if ss is not None:
            if "." in ss:
                seconds, remainingmicroseconds = cls._split_to_microseconds(
                    ss, MICROSECONDS_PER_SECOND, "Invalid second string.")
                microseconds += remainingmicroseconds
            else:
                seconds = cls.cast(ss,
                                   int,
                                   thrownmessage="Invalid second string.")

        (
            hours,
            minutes,
            seconds,
            microseconds,
        ) = PythonTimeBuilder._distribute_microseconds(
            microseconds,
            (hours, minutes, seconds),
            (MICROSECONDS_PER_HOUR, MICROSECONDS_PER_MINUTE,
             MICROSECONDS_PER_SECOND),
        )

        # Range checks
        if hours == 23 and minutes == 59 and seconds == 60:
            # https://bitbucket.org/nielsenb/aniso8601/issues/10/sub-microsecond-precision-in-durations-is
            raise LeapSecondError("Leap seconds are not supported.")

        if hours == 24 and (minutes != 0 or seconds != 0):
            raise MidnightBoundsError("Hour 24 may only represent midnight.")

        if hours > 24:
            raise HoursOutOfBoundsError("Hour must be between 0..24 with "
                                        "24 representing midnight.")

        if minutes >= 60:
            raise MinutesOutOfBoundsError("Minutes must be less than 60.")

        if seconds >= 60:
            raise SecondsOutOfBoundsError("Seconds must be less than 60.")

        # Fix ranges that have passed range checks
        if hours == 24:
            hours = 0
            minutes = 0
            seconds = 0

        # Datetimes don't handle fractional components, so we use a timedelta
        if tz is not None:
            return (datetime.datetime(1,
                                      1,
                                      1,
                                      hour=hours,
                                      minute=minutes,
                                      tzinfo=cls._build_object(tz)) +
                    datetime.timedelta(seconds=seconds,
                                       microseconds=microseconds)).timetz()

        return (datetime.datetime(1, 1, 1, hour=hours, minute=minutes) +
                datetime.timedelta(seconds=seconds,
                                   microseconds=microseconds)).time()
示例#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))
示例#5
0
    def build_time(cls, hh=None, mm=None, ss=None, tz=None):
        # Builds a time from the given parts, handling fractional arguments
        # where necessary
        hours = 0
        minutes = 0
        seconds = 0

        floathours = float(0)
        floatminutes = float(0)
        floatseconds = float(0)

        if hh is not None:
            if "." in hh:
                floathours = BaseTimeBuilder.cast(
                    hh, float, thrownmessage="Invalid hour string.")
                hours = 0
            else:
                hours = BaseTimeBuilder.cast(
                    hh, int, thrownmessage="Invalid hour string.")

        if mm is not None:
            if "." in mm:
                floatminutes = BaseTimeBuilder.cast(
                    mm, float, thrownmessage="Invalid minute string.")
                minutes = 0
            else:
                minutes = BaseTimeBuilder.cast(
                    mm, int, thrownmessage="Invalid minute string.")

        if ss is not None:
            if "." in ss:
                # Truncate to maximum supported precision
                floatseconds = BaseTimeBuilder.cast(
                    ss[0:ss.index(".") + 7],
                    float,
                    thrownmessage="Invalid second string.",
                )
                seconds = 0
            else:
                seconds = BaseTimeBuilder.cast(
                    ss, int, thrownmessage="Invalid second string.")

        # Range checks
        if (hours == 23 and floathours == 0 and minutes == 59
                and floatminutes == 0 and seconds == 60 and floatseconds == 0):
            # https://bitbucket.org/nielsenb/aniso8601/issues/10/sub-microsecond-precision-in-durations-is
            raise LeapSecondError("Leap seconds are not supported.")

        if (hours == 24 and floathours == 0
                and (minutes != 0 or floatminutes != 0 or seconds != 0
                     or floatseconds != 0)):
            raise MidnightBoundsError("Hour 24 may only represent midnight.")

        if hours > 24 or floathours > 24:
            raise HoursOutOfBoundsError("Hour must be between 0..24 with "
                                        "24 representing midnight.")

        if minutes >= 60 or floatminutes >= 60:
            raise MinutesOutOfBoundsError("Minutes must be less than 60.")

        if seconds >= 60 or floatseconds >= 60:
            raise SecondsOutOfBoundsError("Seconds must be less than 60.")

        # Fix ranges that have passed range checks
        if hours == 24:
            hours = 0
            minutes = 0
            seconds = 0

        # Datetimes don't handle fractional components, so we use a timedelta
        if tz is not None:
            return (datetime.datetime(
                1,
                1,
                1,
                hour=hours,
                minute=minutes,
                second=seconds,
                tzinfo=cls._build_object(tz),
            ) + datetime.timedelta(hours=floathours,
                                   minutes=floatminutes,
                                   seconds=floatseconds)).timetz()

        return (datetime.datetime(
            1, 1, 1, hour=hours, minute=minutes, second=seconds) +
                datetime.timedelta(hours=floathours,
                                   minutes=floatminutes,
                                   seconds=floatseconds)).time()
示例#6
0
    def build_time(cls, hh=None, mm=None, ss=None, tz=None):
        #Builds a time from the given parts, handling fractional arguments
        #where necessary
        hours = 0
        minutes = 0
        seconds = 0

        floathours = float(0)
        floatminutes = float(0)
        floatseconds = float(0)

        if hh is not None:
            if '.' in hh:
                hours, floathours = cls._split_and_cast(
                    hh, 'Invalid hour string.')
            else:
                hours = cls.cast(hh, int, thrownmessage='Invalid hour string.')

        if mm is not None:
            if '.' in mm:
                minutes, floatminutes = cls._split_and_cast(
                    mm, 'Invalid minute string.')
            else:
                minutes = cls.cast(mm,
                                   int,
                                   thrownmessage='Invalid minute string.')

        if ss is not None:
            if '.' in ss:
                seconds, floatseconds = cls._split_and_cast(
                    ss, 'Invalid second string.')
            else:
                seconds = cls.cast(ss,
                                   int,
                                   thrownmessage='Invalid second string.')

        if floathours != 0:
            remainderhours, remainderminutes = cls._split_and_convert(
                floathours, 60)

            hours += remainderhours
            floatminutes += remainderminutes

        if floatminutes != 0:
            remainderminutes, remainderseconds = cls._split_and_convert(
                floatminutes, 60)

            minutes += remainderminutes
            floatseconds += remainderseconds

        if floatseconds != 0:
            totalseconds = float(seconds) + floatseconds

            #Truncate to maximum supported precision
            seconds = cls._truncate(totalseconds, 6)

        #Range checks
        if hours == 23 and minutes == 59 and seconds == 60:
            #https://bitbucket.org/nielsenb/aniso8601/issues/10/sub-microsecond-precision-in-durations-is
            raise LeapSecondError('Leap seconds are not supported.')

        if (hours == 24 and (minutes != 0 or seconds != 0)):
            raise MidnightBoundsError('Hour 24 may only represent midnight.')

        if hours > 24:
            raise HoursOutOfBoundsError('Hour must be between 0..24 with '
                                        '24 representing midnight.')

        if minutes >= 60:
            raise MinutesOutOfBoundsError('Minutes must be less than 60.')

        if seconds >= 60:
            raise SecondsOutOfBoundsError('Seconds must be less than 60.')

        #Fix ranges that have passed range checks
        if hours == 24:
            hours = 0
            minutes = 0
            seconds = 0

        #Datetimes don't handle fractional components, so we use a timedelta
        if tz is not None:
            return (datetime.datetime(1,
                                      1,
                                      1,
                                      hour=hours,
                                      minute=minutes,
                                      tzinfo=cls._build_object(tz)) +
                    datetime.timedelta(seconds=seconds)).timetz()

        return (datetime.datetime(1, 1, 1, hour=hours, minute=minutes) +
                datetime.timedelta(seconds=seconds)).time()