Exemplo n.º 1
0
    def test_parse_date_badstr(self):
        testtuples = ('W53', '2004-W', '2014-01-230', '2014-012-23',
                      '201-01-23', '201401230', '201401', 'bad', '')

        for testtuple in testtuples:
            with self.assertRaises(ISOFormatError):
                parse_date(testtuple, builder=None)
Exemplo n.º 2
0
def _parse_interval(isointervalstr,
                    builder,
                    intervaldelimiter='/',
                    datetimedelimiter='T'):
    #Returns a tuple containing the start of the interval, the end of the
    #interval, and or the interval duration

    firstpart, secondpart = isointervalstr.split(intervaldelimiter)

    if len(firstpart) == 0 or len(secondpart) == 0:
        raise ISOFormatError(
            '{0} is not a valid ISO 8601 interval'.format(isointervalstr))

    if firstpart[0] == 'P':
        #<duration>/<end>
        #Notice that these are not returned 'in order' (earlier to later), this
        #is to maintain consistency with parsing <start>/<end> durations, as
        #well as making repeating interval code cleaner. Users who desire
        #durations to be in order can use the 'sorted' operator.
        duration = parse_duration(firstpart, builder=TupleBuilder)

        #We need to figure out if <end> is a date, or a datetime
        if secondpart.find(datetimedelimiter) != -1:
            #<end> is a datetime
            endtuple = parse_datetime(secondpart,
                                      delimiter=datetimedelimiter,
                                      builder=TupleBuilder)
        else:
            endtuple = parse_date(secondpart, builder=TupleBuilder)

        return builder.build_interval(end=endtuple, duration=duration)
    elif secondpart[0] == 'P':
        #<start>/<duration>
        #We need to figure out if <start> is a date, or a datetime
        duration = parse_duration(secondpart, builder=TupleBuilder)

        if firstpart.find(datetimedelimiter) != -1:
            #<start> is a datetime
            starttuple = parse_datetime(firstpart,
                                        delimiter=datetimedelimiter,
                                        builder=TupleBuilder)
        else:
            #<start> must just be a date
            starttuple = parse_date(firstpart, builder=TupleBuilder)

        return builder.build_interval(start=starttuple, duration=duration)

    #<start>/<end>
    if firstpart.find(datetimedelimiter) != -1:
        #Both parts are datetimes
        starttuple = parse_datetime(firstpart,
                                    delimiter=datetimedelimiter,
                                    builder=TupleBuilder)
    else:
        starttuple = parse_date(firstpart, builder=TupleBuilder)

    endtuple = _parse_interval_end(secondpart, starttuple, datetimedelimiter)

    return builder.build_interval(start=starttuple, end=endtuple)
Exemplo n.º 3
0
    def test_parse_date(self):
        testtuples = (
            ("2013", {"YYYY": "2013"}),
            ("0001", {"YYYY": "0001"}),
            ("19", {"YYYY": "19"}),
            ("1981-04-05", {"YYYY": "1981", "MM": "04", "DD": "05"}),
            ("19810405", {"YYYY": "1981", "MM": "04", "DD": "05"}),
            ("1981-04", {"YYYY": "1981", "MM": "04"}),
            ("2004-W53", {"YYYY": "2004", "Www": "53"}),
            ("2009-W01", {"YYYY": "2009", "Www": "01"}),
            ("2004-W53-6", {"YYYY": "2004", "Www": "53", "D": "6"}),
            ("2004W53", {"YYYY": "2004", "Www": "53"}),
            ("2004W536", {"YYYY": "2004", "Www": "53", "D": "6"}),
            ("1981-095", {"YYYY": "1981", "DDD": "095"}),
            ("1981095", {"YYYY": "1981", "DDD": "095"}),
        )

        for testtuple in testtuples:
            with mock.patch.object(
                aniso8601.date.PythonTimeBuilder, "build_date"
            ) as mockBuildDate:
                mockBuildDate.return_value = testtuple[1]

                result = parse_date(testtuple[0])

                self.assertEqual(result, testtuple[1])
                mockBuildDate.assert_called_once_with(**testtuple[1])
Exemplo n.º 4
0
def _parse_duration_combined(durationstr, relative):
    #Period of the form P<date>T<time>

    #Split the string in to its component parts
    datepart, timepart = durationstr[1:].split('T')  #We skip the 'P'

    datevalue = parse_date(datepart)
    timevalue = parse_time(timepart)

    if relative is True:
        try:
            import dateutil.relativedelta

            return dateutil.relativedelta.relativedelta(
                years=datevalue.year,
                months=datevalue.month,
                days=datevalue.day,
                hours=timevalue.hour,
                minutes=timevalue.minute,
                seconds=timevalue.second,
                microseconds=timevalue.microsecond)
        except ImportError:
            raise RuntimeError(
                'dateutil must be installed for relative duration support.')
    else:
        totaldays = datevalue.year * 365 + datevalue.month * 30 + datevalue.day

        return datetime.timedelta(days=totaldays,
                                  hours=timevalue.hour,
                                  minutes=timevalue.minute,
                                  seconds=timevalue.second,
                                  microseconds=timevalue.microsecond)
Exemplo n.º 5
0
    def test_parse_date_badstr(self):
        testtuples = (
            "W53",
            "2004-W",
            "2014-01-230",
            "2014-012-23",
            "201-01-23",
            "201401230",
            "201401",
            "9999 W53",
            "20.50230",
            "198104",
            "bad",
            "",
        )

        for testtuple in testtuples:
            with self.assertRaises(ISOFormatError):
                parse_date(testtuple, builder=None)
Exemplo n.º 6
0
    def test_parse_date_mockbuilder(self):
        mockBuilder = mock.Mock()

        expectedargs = {"YYYY": "1981", "MM": "04", "DD": "05"}

        mockBuilder.build_date.return_value = expectedargs

        result = parse_date("1981-04-05", builder=mockBuilder)

        self.assertEqual(result, expectedargs)
        mockBuilder.build_date.assert_called_once_with(**expectedargs)
Exemplo n.º 7
0
    def test_parse_date_mockbuilder(self):
        mockBuilder = mock.Mock()

        expectedargs = {'YYYY': '1981', 'MM': '04', 'DD': '05'}

        mockBuilder.build_date.return_value = expectedargs

        result = parse_date('1981-04-05', builder=mockBuilder)

        self.assertEqual(result, expectedargs)
        mockBuilder.build_date.assert_called_once_with(**expectedargs)
Exemplo n.º 8
0
def _parse_duration_combined(durationstr, builder):
    #Period of the form P<date>T<time>

    #Split the string in to its component parts
    datepart, timepart = durationstr[1:].split('T') #We skip the 'P'

    datevalue = parse_date(datepart, builder=TupleBuilder)
    timevalue = parse_time(timepart, builder=TupleBuilder)

    return builder.build_duration(PnY=datevalue[0], PnM=datevalue[1],
                                  PnD=datevalue[2], TnH=timevalue[0],
                                  TnM=timevalue[1], TnS=timevalue[2])
Exemplo n.º 9
0
def _parse_duration_combined(durationstr):
    #Period of the form P<date>T<time>

    #Split the string in to its component parts
    datepart, timepart = durationstr[1:].split('T') #We skip the 'P'

    datevalue = parse_date(datepart)
    timevalue = parse_time(timepart)

    totaldays = datevalue.year * 365 + datevalue.month * 30 + datevalue.day

    return datetime.timedelta(days=totaldays, hours=timevalue.hour, minutes=timevalue.minute, seconds=timevalue.second, microseconds=timevalue.microsecond)
Exemplo n.º 10
0
def _parse_duration_combined(durationstr, builder):
    #Period of the form P<date>T<time>

    #Split the string in to its component parts
    datepart, timepart = durationstr[1:].split('T') #We skip the 'P'

    datevalue = parse_date(datepart, builder=TupleBuilder)
    timevalue = parse_time(timepart, builder=TupleBuilder)

    return builder.build_duration(PnY=datevalue[0], PnM=datevalue[1],
                                  PnD=datevalue[2], TnH=timevalue[0],
                                  TnM=timevalue[1], TnS=timevalue[2])
Exemplo n.º 11
0
    def test_parse_date(self):
        testtuples = (('2013', {
            'YYYY': '2013'
        }), ('0001', {
            'YYYY': '0001'
        }), ('19', {
            'YYYY': '19'
        }), ('1981-04-05', {
            'YYYY': '1981',
            'MM': '04',
            'DD': '05'
        }), ('19810405', {
            'YYYY': '1981',
            'MM': '04',
            'DD': '05'
        }), ('1981-04', {
            'YYYY': '1981',
            'MM': '04'
        }), ('2004-W53', {
            'YYYY': '2004',
            'Www': '53'
        }), ('2009-W01', {
            'YYYY': '2009',
            'Www': '01'
        }), ('2004-W53-6', {
            'YYYY': '2004',
            'Www': '53',
            'D': '6'
        }), ('2004W53', {
            'YYYY': '2004',
            'Www': '53'
        }), ('2004W536', {
            'YYYY': '2004',
            'Www': '53',
            'D': '6'
        }), ('1981-095', {
            'YYYY': '1981',
            'DDD': '095'
        }), ('1981095', {
            'YYYY': '1981',
            'DDD': '095'
        }))

        for testtuple in testtuples:
            with mock.patch.object(aniso8601.builder.PythonTimeBuilder,
                                   'build_date') as mockBuildDate:
                mockBuildDate.return_value = testtuple[1]

                result = parse_date(testtuple[0])

                self.assertEqual(result, testtuple[1])
                mockBuildDate.assert_called_once_with(**testtuple[1])
Exemplo n.º 12
0
def parse_datetime(isodatetimestr, delimiter='T'):
    #Given a string in ISO 8601 date time format, return a datetime.datetime
    #object that corresponds to the given date time.
    #By default, the ISO 8601 specified T delimiter is used to split the
    #date and time (<date>T<time>). Fixed offset tzdata will be included
    #if UTC offset is given in the input string.

    isodatestr, isotimestr = isodatetimestr.split(delimiter)

    datepart = parse_date(isodatestr)
    timepart = parse_time(isotimestr)

    return datetime.datetime.combine(datepart, timepart)
Exemplo n.º 13
0
def parse_datetime(isodatetimestr, delimiter='T'):
    #Given a string in ISO 8601 date time format, return a datetime.datetime
    #object that corresponds to the given date time.
    #By default, the ISO 8601 specified T delimiter is used to split the
    #date and time (<date>T<time>). Fixed offset tzdata will be included
    #if UTC offset is given in the input string.

    isodatestr, isotimestr = isodatetimestr.split(delimiter)

    datepart = parse_date(isodatestr)
    timepart = parse_time(isotimestr)

    return datetime.datetime.combine(datepart, timepart)
def _parse_duration_combined(durationstr):
    #Period of the form P<date>T<time>

    #Split the string in to its component parts
    datepart, timepart = durationstr[1:].split('T')  #We skip the 'P'

    datevalue = parse_date(datepart)
    timevalue = parse_time(timepart)

    totaldays = datevalue.year * 365 + datevalue.month * 30 + datevalue.day

    return datetime.timedelta(days=totaldays,
                              hours=timevalue.hour,
                              minutes=timevalue.minute,
                              seconds=timevalue.second,
                              microseconds=timevalue.microsecond)
Exemplo n.º 15
0
def _parse_duration_combined(durationstr):
    #Period of the form P<date>T<time>

    #Split the string in to its component parts
    datepart, timepart = durationstr[1:].split('T', 1)  #We skip the 'P'

    datevalue = parse_date(datepart, builder=TupleBuilder)
    timevalue = parse_time(timepart, builder=TupleBuilder)

    return {
        'PnY': datevalue.YYYY,
        'PnM': datevalue.MM,
        'PnD': datevalue.DD,
        'TnH': timevalue.hh,
        'TnM': timevalue.mm,
        'TnS': timevalue.ss
    }
Exemplo n.º 16
0
def _parse_duration_combined(durationstr):
    # Period of the form P<date>T<time>

    # Split the string in to its component parts
    datepart, timepart = durationstr[1:].split("T", 1)  # We skip the 'P'

    datevalue = parse_date(datepart, builder=TupleBuilder)
    timevalue = parse_time(timepart, builder=TupleBuilder)

    return {
        "PnY": datevalue.YYYY,
        "PnM": datevalue.MM,
        "PnD": datevalue.DD,
        "TnH": timevalue.hh,
        "TnM": timevalue.mm,
        "TnS": timevalue.ss,
    }
Exemplo n.º 17
0
def parse_datetime(isodatetimestr, delimiter="T", builder=PythonTimeBuilder):
    # Given a string in ISO 8601 date time format, return a datetime.datetime
    # object that corresponds to the given date time.
    # By default, the ISO 8601 specified T delimiter is used to split the
    # date and time (<date>T<time>). Fixed offset tzdata will be included
    # if UTC offset is given in the input string.
    if is_string(isodatetimestr) is False:
        raise ValueError("Date time must be string.")

    if delimiter not in isodatetimestr:
        raise ISOFormatError('Delimiter "{0}" is not in combined date time '
                             'string "{1}".'.format(delimiter, isodatetimestr))

    isodatestr, isotimestr = isodatetimestr.split(delimiter, 1)

    datepart = parse_date(isodatestr, builder=TupleBuilder)

    timepart = parse_time(isotimestr, builder=TupleBuilder)

    return builder.build_datetime(datepart, timepart)
Exemplo n.º 18
0
def _parse_duration_combined(durationstr, relative):
    #Period of the form P<date>T<time>

    #Split the string in to its component parts
    datepart, timepart = durationstr[1:].split('T') #We skip the 'P'

    datevalue = parse_date(datepart)
    timevalue = parse_time(timepart)

    if relative is True:
        try:
            import dateutil.relativedelta

            return dateutil.relativedelta.relativedelta(years=datevalue.year, months=datevalue.month, days=datevalue.day, hours=timevalue.hour, minutes=timevalue.minute, seconds=timevalue.second, microseconds=timevalue.microsecond)
        except ImportError:
            raise RuntimeError('dateutil must be installed for relative duration support.')
    else:
        totaldays = datevalue.year * 365 + datevalue.month * 30 + datevalue.day

        return datetime.timedelta(days=totaldays, hours=timevalue.hour, minutes=timevalue.minute, seconds=timevalue.second, microseconds=timevalue.microsecond)
Exemplo n.º 19
0
def parse_interval(isointervalstr,
                   intervaldelimiter='/',
                   datetimedelimiter='T',
                   relative=False):
    #Given a string representing an ISO 8601 interval, return a
    #tuple of datetime.date or date.datetime objects representing the beginning
    #and end of the specified interval. Valid formats are:
    #
    #<start>/<end>
    #<start>/<duration>
    #<duration>/<end>
    #
    #The <start> and <end> values can represent dates, or datetimes,
    #not times.
    #
    #The format:
    #
    #<duration>
    #
    #Is expressly not supported as there is no way to provide the addtional
    #required context.

    firstpart, secondpart = isointervalstr.split(intervaldelimiter)

    if firstpart[0] == 'P':
        #<duration>/<end>
        #Notice that these are not returned 'in order' (earlier to later), this
        #is to maintain consistency with parsing <start>/<end> durations, as
        #well as making repeating interval code cleaner. Users who desire
        #durations to be in order can use the 'sorted' operator.

        #We need to figure out if <end> is a date, or a datetime
        if secondpart.find(datetimedelimiter) != -1:
            #<end> is a datetime
            duration = parse_duration(firstpart, relative=relative)
            enddatetime = parse_datetime(secondpart,
                                         delimiter=datetimedelimiter)

            return (enddatetime, enddatetime - duration)
        else:
            #<end> must just be a date
            duration = parse_duration(firstpart, relative=relative)
            enddate = parse_date(secondpart)

            #See if we need to upconvert to datetime to preserve resolution
            if firstpart.find(datetimedelimiter) != -1:
                return (enddate,
                        datetime.combine(enddate, datetime.min.time()) -
                        duration)
            else:
                return (enddate, enddate - duration)
    elif secondpart[0] == 'P':
        #<start>/<duration>
        #We need to figure out if <start> is a date, or a datetime
        if firstpart.find(datetimedelimiter) != -1:
            #<end> is a datetime
            duration = parse_duration(secondpart, relative=relative)
            startdatetime = parse_datetime(firstpart,
                                           delimiter=datetimedelimiter)

            return (startdatetime, startdatetime + duration)
        else:
            #<start> must just be a date
            duration = parse_duration(secondpart, relative=relative)
            startdate = parse_date(firstpart)

            #See if we need to upconvert to datetime to preserve resolution
            if secondpart.find(datetimedelimiter) != -1:
                return (startdate,
                        datetime.combine(startdate, datetime.min.time()) +
                        duration)
            else:
                return (startdate, startdate + duration)
    else:
        #<start>/<end>
        if firstpart.find(datetimedelimiter) != -1 and secondpart.find(
                datetimedelimiter) != -1:
            #Both parts are datetimes
            return (parse_datetime(firstpart, delimiter=datetimedelimiter),
                    parse_datetime(secondpart, delimiter=datetimedelimiter))
        elif firstpart.find(datetimedelimiter) != -1 and secondpart.find(
                datetimedelimiter) == -1:
            #First part is a datetime, second part is a date
            return (parse_datetime(firstpart, delimiter=datetimedelimiter),
                    parse_date(secondpart))
        elif firstpart.find(datetimedelimiter) == -1 and secondpart.find(
                datetimedelimiter) != -1:
            #First part is a date, second part is a datetime
            return (parse_date(firstpart),
                    parse_datetime(secondpart, delimiter=datetimedelimiter))
        else:
            #Both parts are dates
            return (parse_date(firstpart), parse_date(secondpart))
Exemplo n.º 20
0
    def test_parse_date(self):
        date = parse_date('2013')
        self.assertEqual(date.year, 2013)
        self.assertEqual(date.month, 1)
        self.assertEqual(date.day, 1)

        date = parse_date('0001')
        self.assertEqual(date.year, 1)
        self.assertEqual(date.month, 1)
        self.assertEqual(date.day, 1)

        date = parse_date('19')
        self.assertEqual(date.year, 1900)
        self.assertEqual(date.month, 1)
        self.assertEqual(date.day, 1)

        date = parse_date('1981-04-05')
        self.assertEqual(date.year, 1981)
        self.assertEqual(date.month, 4)
        self.assertEqual(date.day, 5)

        date = parse_date('19810405')
        self.assertEqual(date.year, 1981)
        self.assertEqual(date.month, 4)
        self.assertEqual(date.day, 5)

        date = parse_date('1981-04')
        self.assertEqual(date.year, 1981)
        self.assertEqual(date.month, 4)
        self.assertEqual(date.day, 1)

        date = parse_date('2004-W53')
        self.assertEqual(date.year, 2004)
        self.assertEqual(date.month, 12)
        self.assertEqual(date.weekday(), 0)

        date = parse_date('2009-W01')
        self.assertEqual(date.year, 2008)
        self.assertEqual(date.month, 12)
        self.assertEqual(date.weekday(), 0)

        date = parse_date('2004-W53-6')
        self.assertEqual(date.year, 2005)
        self.assertEqual(date.month, 1)
        self.assertEqual(date.day, 1)

        date = parse_date('2004W53')
        self.assertEqual(date.year, 2004)
        self.assertEqual(date.month, 12)
        self.assertEqual(date.weekday(), 0)

        date = parse_date('2004W536')
        self.assertEqual(date.year, 2005)
        self.assertEqual(date.month, 1)
        self.assertEqual(date.day, 1)

        date = parse_date('1981-095')
        self.assertEqual(date.year, 1981)
        self.assertEqual(date.month, 4)
        self.assertEqual(date.day, 5)

        date = parse_date('1981095')
        self.assertEqual(date.year, 1981)
        self.assertEqual(date.month, 4)
        self.assertEqual(date.day, 5)
Exemplo n.º 21
0
    def test_parse_date(self):
        date = parse_date('2013')
        self.assertEqual(date, datetime.date(2013, 1, 1))

        date = parse_date('0001')
        self.assertEqual(date, datetime.date(1, 1, 1))

        date = parse_date('19')
        self.assertEqual(date, datetime.date(1900, 1, 1))

        date = parse_date('1981-04-05')
        self.assertEqual(date, datetime.date(1981, 4, 5))

        date = parse_date('19810405')
        self.assertEqual(date, datetime.date(1981, 4, 5))

        date = parse_date('1981-04')
        self.assertEqual(date, datetime.date(1981, 4, 1))

        date = parse_date('2004-W53')
        self.assertEqual(date, datetime.date(2004, 12, 27))
        self.assertEqual(date.weekday(), 0)

        date = parse_date('2009-W01')
        self.assertEqual(date, datetime.date(2008, 12, 29))
        self.assertEqual(date.weekday(), 0)

        date = parse_date('2004-W53-6')
        self.assertEqual(date, datetime.date(2005, 1, 1))
        self.assertEqual(date.weekday(), 5)

        date = parse_date('2004W53')
        self.assertEqual(date, datetime.date(2004, 12, 27))
        self.assertEqual(date.weekday(), 0)

        date = parse_date('2004W536')
        self.assertEqual(date, datetime.date(2005, 1, 1))
        self.assertEqual(date.weekday(), 5)

        date = parse_date('1981-095')
        self.assertEqual(date, datetime.date(1981, 4, 5))

        date = parse_date('1981095')
        self.assertEqual(date, datetime.date(1981, 4, 5))
Exemplo n.º 22
0
    def test_parse_date_badtype(self):
        testtuples = (None, 1, False, 1.234)

        for testtuple in testtuples:
            with self.assertRaises(ValueError):
                parse_date(testtuple, builder=None)
Exemplo n.º 23
0
    def test_parse_date(self):
        date = parse_date('2013')
        self.assertEqual(date.year, 2013)
        self.assertEqual(date.month, 1)
        self.assertEqual(date.day, 1)

        date = parse_date('0001')
        self.assertEqual(date.year, 1)
        self.assertEqual(date.month, 1)
        self.assertEqual(date.day, 1)

        date = parse_date('19')
        self.assertEqual(date.year, 1900)
        self.assertEqual(date.month, 1)
        self.assertEqual(date.day, 1)

        date = parse_date('1981-04-05')
        self.assertEqual(date.year, 1981)
        self.assertEqual(date.month, 4)
        self.assertEqual(date.day, 5)

        date = parse_date('19810405')
        self.assertEqual(date.year, 1981)
        self.assertEqual(date.month, 4)
        self.assertEqual(date.day, 5)

        date = parse_date('1981-04')
        self.assertEqual(date.year, 1981)
        self.assertEqual(date.month, 4)
        self.assertEqual(date.day, 1)

        date = parse_date('2004-W53')
        self.assertEqual(date.year, 2004)
        self.assertEqual(date.month, 12)
        self.assertEqual(date.weekday(), 0)

        date = parse_date('2009-W01')
        self.assertEqual(date.year, 2008)
        self.assertEqual(date.month, 12)
        self.assertEqual(date.weekday(), 0)

        date = parse_date('2004-W53-6')
        self.assertEqual(date.year, 2005)
        self.assertEqual(date.month, 1)
        self.assertEqual(date.day, 1)

        date = parse_date('2004W53')
        self.assertEqual(date.year, 2004)
        self.assertEqual(date.month, 12)
        self.assertEqual(date.weekday(), 0)

        date = parse_date('2004W536')
        self.assertEqual(date.year, 2005)
        self.assertEqual(date.month, 1)
        self.assertEqual(date.day, 1)

        date = parse_date('1981-095')
        self.assertEqual(date.year, 1981)
        self.assertEqual(date.month, 4)
        self.assertEqual(date.day, 5)

        date = parse_date('1981095')
        self.assertEqual(date.year, 1981)
        self.assertEqual(date.month, 4)
        self.assertEqual(date.day, 5)
Exemplo n.º 24
0
    def test_parse_date_bounds(self):
        #0 isn't a valid week number
        with self.assertRaises(WeekOutOfBoundsError):
            parse_date('2003-W00')

        with self.assertRaises(WeekOutOfBoundsError):
            parse_date('2003W00')

        #Week must not be larger than 53
        with self.assertRaises(WeekOutOfBoundsError):
            parse_date('2004-W54')

        with self.assertRaises(WeekOutOfBoundsError):
            parse_date('2004W54')

        #0 isn't a valid day number
        with self.assertRaises(DayOutOfBoundsError):
            parse_date('2001-W02-0')

        with self.assertRaises(DayOutOfBoundsError):
            parse_date('2001W020')

        #Day must not be larger than 7
        with self.assertRaises(DayOutOfBoundsError):
            parse_date('2001-W02-8')

        with self.assertRaises(DayOutOfBoundsError):
            parse_date('2001W028')
Exemplo n.º 25
0
def _parse_interval(
    isointervalstr, builder, intervaldelimiter="/", datetimedelimiter="T"
):
    # Returns a tuple containing the start of the interval, the end of the
    # interval, and or the interval duration

    firstpart, secondpart = isointervalstr.split(intervaldelimiter)

    if firstpart[0] == "P":
        # <duration>/<end>
        # Notice that these are not returned 'in order' (earlier to later), this
        # is to maintain consistency with parsing <start>/<end> durations, as
        # well as making repeating interval code cleaner. Users who desire
        # durations to be in order can use the 'sorted' operator.

        # We need to figure out if <end> is a date, or a datetime
        if secondpart.find(datetimedelimiter) != -1:
            # <end> is a datetime
            duration = parse_duration(firstpart, builder=TupleBuilder)
            enddatetime = parse_datetime(
                secondpart, delimiter=datetimedelimiter, builder=TupleBuilder
            )

            return builder.build_interval(end=enddatetime, duration=duration)

        # <end> must just be a date
        duration = parse_duration(firstpart, builder=TupleBuilder)
        enddate = parse_date(secondpart, builder=TupleBuilder)

        return builder.build_interval(end=enddate, duration=duration)
    elif secondpart[0] == "P":
        # <start>/<duration>
        # We need to figure out if <start> is a date, or a datetime
        if firstpart.find(datetimedelimiter) != -1:
            # <start> is a datetime
            duration = parse_duration(secondpart, builder=TupleBuilder)
            startdatetime = parse_datetime(
                firstpart, delimiter=datetimedelimiter, builder=TupleBuilder
            )

            return builder.build_interval(start=startdatetime, duration=duration)

        # <start> must just be a date
        duration = parse_duration(secondpart, builder=TupleBuilder)
        startdate = parse_date(firstpart, builder=TupleBuilder)

        return builder.build_interval(start=startdate, duration=duration)

    # <start>/<end>
    if (
        firstpart.find(datetimedelimiter) != -1
        and secondpart.find(datetimedelimiter) != -1
    ):
        # Both parts are datetimes
        start_datetime = parse_datetime(
            firstpart, delimiter=datetimedelimiter, builder=TupleBuilder
        )

        end_datetime = parse_datetime(
            secondpart, delimiter=datetimedelimiter, builder=TupleBuilder
        )

        return builder.build_interval(start=start_datetime, end=end_datetime)
    elif (
        firstpart.find(datetimedelimiter) != -1
        and secondpart.find(datetimedelimiter) == -1
    ):
        # First part is a datetime, second part is a date
        start_datetime = parse_datetime(
            firstpart, delimiter=datetimedelimiter, builder=TupleBuilder
        )

        end_date = parse_date(secondpart, builder=TupleBuilder)

        return builder.build_interval(start=start_datetime, end=end_date)
    elif (
        firstpart.find(datetimedelimiter) == -1
        and secondpart.find(datetimedelimiter) != -1
    ):
        # First part is a date, second part is a datetime
        start_date = parse_date(firstpart, builder=TupleBuilder)
        end_datetime = parse_datetime(
            secondpart, delimiter=datetimedelimiter, builder=TupleBuilder
        )

        return builder.build_interval(start=start_date, end=end_datetime)

    # Both parts are dates
    start_date = parse_date(firstpart, builder=TupleBuilder)
    end_date = parse_date(secondpart, builder=TupleBuilder)

    return builder.build_interval(start=start_date, end=end_date)
Exemplo n.º 26
0
def _parse_interval_parts(isointervalstr,
                          intervaldelimiter='/',
                          datetimedelimiter='T',
                          relative=False):
    #Returns a tuple containing the start of the interval, the end of the interval, and the interval timedelta
    firstpart, secondpart = isointervalstr.split(intervaldelimiter)

    if firstpart[0] == 'P':
        #<duration>/<end>
        #Notice that these are not returned 'in order' (earlier to later), this
        #is to maintain consistency with parsing <start>/<end> durations, as
        #well as making repeating interval code cleaner. users_dispatcher who desire
        #durations to be in order can use the 'sorted' operator.

        #We need to figure out if <end> is a date, or a datetime
        if secondpart.find(datetimedelimiter) != -1:
            #<end> is a datetime
            duration = parse_duration(firstpart, relative=relative)
            enddatetime = parse_datetime(secondpart,
                                         delimiter=datetimedelimiter)

            return (enddatetime, enddatetime - duration, -duration)
        else:
            #<end> must just be a date
            duration = parse_duration(firstpart, relative=relative)
            enddate = parse_date(secondpart)

            #See if we need to upconvert to datetime to preserve resolution
            if firstpart.find(datetimedelimiter) != -1:
                return (enddate,
                        datetime.combine(enddate, datetime.min.time()) -
                        duration, -duration)
            else:
                return (enddate, enddate - duration, -duration)
    elif secondpart[0] == 'P':
        #<start>/<duration>
        #We need to figure out if <start> is a date, or a datetime
        if firstpart.find(datetimedelimiter) != -1:
            #<start> is a datetime
            duration = parse_duration(secondpart, relative=relative)
            startdatetime = parse_datetime(firstpart,
                                           delimiter=datetimedelimiter)

            return (startdatetime, startdatetime + duration, duration)
        else:
            #<start> must just be a date
            duration = parse_duration(secondpart, relative=relative)
            startdate = parse_date(firstpart)

            #See if we need to upconvert to datetime to preserve resolution
            if secondpart.find(datetimedelimiter) != -1:
                return (startdate,
                        datetime.combine(startdate, datetime.min.time()) +
                        duration, duration)
            else:
                return (startdate, startdate + duration, duration)
    else:
        #<start>/<end>
        if firstpart.find(datetimedelimiter) != -1 and secondpart.find(
                datetimedelimiter) != -1:
            #Both parts are datetimes
            start_datetime = parse_datetime(firstpart,
                                            delimiter=datetimedelimiter)
            end_datetime = parse_datetime(secondpart,
                                          delimiter=datetimedelimiter)

            return (start_datetime, end_datetime,
                    end_datetime - start_datetime)
        elif firstpart.find(datetimedelimiter) != -1 and secondpart.find(
                datetimedelimiter) == -1:
            #First part is a datetime, second part is a date
            start_datetime = parse_datetime(firstpart,
                                            delimiter=datetimedelimiter)
            end_date = parse_date(secondpart)

            return (start_datetime, end_date,
                    datetime.combine(end_date, datetime.min.time()) -
                    start_datetime)
        elif firstpart.find(datetimedelimiter) == -1 and secondpart.find(
                datetimedelimiter) != -1:
            #First part is a date, second part is a datetime
            start_date = parse_date(firstpart)
            end_datetime = parse_datetime(secondpart,
                                          delimiter=datetimedelimiter)

            return (start_date, end_datetime, end_datetime -
                    datetime.combine(start_date, datetime.min.time()))
        else:
            #Both parts are dates
            start_date = parse_date(firstpart)
            end_date = parse_date(secondpart)

            return (start_date, end_date, end_date - start_date)
Exemplo n.º 27
0
def _parse_interval_parts(isointervalstr, intervaldelimiter='/', datetimedelimiter='T', relative=False):
    #Returns a tuple containing the start of the interval, the end of the interval, and the interval timedelta
    firstpart, secondpart = isointervalstr.split(intervaldelimiter)

    if firstpart[0] == 'P':
        #<duration>/<end>
        #Notice that these are not returned 'in order' (earlier to later), this
        #is to maintain consistency with parsing <start>/<end> durations, as
        #well as making repeating interval code cleaner. Users who desire
        #durations to be in order can use the 'sorted' operator.

        #We need to figure out if <end> is a date, or a datetime
        if secondpart.find(datetimedelimiter) != -1:
            #<end> is a datetime
            duration = parse_duration(firstpart, relative=relative)
            enddatetime = parse_datetime(secondpart, delimiter=datetimedelimiter)

            return (enddatetime, enddatetime - duration, -duration)
        else:
            #<end> must just be a date
            duration = parse_duration(firstpart, relative=relative)
            enddate = parse_date(secondpart)

            #See if we need to upconvert to datetime to preserve resolution
            if firstpart.find(datetimedelimiter) != -1:
                return (enddate, datetime.combine(enddate, datetime.min.time()) - duration, -duration)
            else:
                return (enddate, enddate - duration, -duration)
    elif secondpart[0] == 'P':
        #<start>/<duration>
        #We need to figure out if <start> is a date, or a datetime
        if firstpart.find(datetimedelimiter) != -1:
            #<start> is a datetime
            duration = parse_duration(secondpart, relative=relative)
            startdatetime = parse_datetime(firstpart, delimiter=datetimedelimiter)

            return (startdatetime, startdatetime + duration, duration)
        else:
            #<start> must just be a date
            duration = parse_duration(secondpart, relative=relative)
            startdate = parse_date(firstpart)

            #See if we need to upconvert to datetime to preserve resolution
            if secondpart.find(datetimedelimiter) != -1:
                return (startdate, datetime.combine(startdate, datetime.min.time()) + duration, duration)
            else:
                return (startdate, startdate + duration, duration)
    else:
        #<start>/<end>
        if firstpart.find(datetimedelimiter) != -1 and secondpart.find(datetimedelimiter) != -1:
            #Both parts are datetimes
            start_datetime = parse_datetime(firstpart, delimiter=datetimedelimiter)
            end_datetime = parse_datetime(secondpart, delimiter=datetimedelimiter)

            return (start_datetime, end_datetime, end_datetime - start_datetime)
        elif firstpart.find(datetimedelimiter) != -1 and secondpart.find(datetimedelimiter) == -1:
            #First part is a datetime, second part is a date
            start_datetime = parse_datetime(firstpart, delimiter=datetimedelimiter)
            end_date = parse_date(secondpart)

            return (start_datetime, end_date, datetime.combine(end_date, datetime.min.time()) - start_datetime)
        elif firstpart.find(datetimedelimiter) == -1 and secondpart.find(datetimedelimiter) != -1:
            #First part is a date, second part is a datetime
            start_date = parse_date(firstpart)
            end_datetime = parse_datetime(secondpart, delimiter=datetimedelimiter)

            return (start_date, end_datetime, end_datetime - datetime.combine(start_date, datetime.min.time()))
        else:
            #Both parts are dates
            start_date = parse_date(firstpart)
            end_date = parse_date(secondpart)

            return (start_date, end_date, end_date - start_date)
Exemplo n.º 28
0
def parse_interval(isointervalstr, intervaldelimiter='/', datetimedelimiter='T'):
    #Given a string representing an ISO8601 interval, return a
    #tuple of datetime.date or date.datetime objects representing the beginning
    #and end of the specified interval. Valid formats are:
    #
    #<start>/<end>
    #<start>/<duration>
    #<duration>/<end>
    #
    #The <start> and <end> values can represent dates, or datetimes,
    #not times.
    #
    #The format:
    #
    #<duration>
    #
    #Is expressly not supported as there is no way to provide the addtional
    #required context.

    firstpart, secondpart = isointervalstr.split(intervaldelimiter)

    if firstpart[0] == 'P':
        #<duration>/<end>
        #Notice that these are not returned 'in order' (earlier to later), this
        #is to maintain consistency with parsing <start>/<end> durations, as
        #well as making repeating interval code cleaner. Users who desire
        #durations to be in order can use the 'sorted' operator.

        #We need to figure out if <end> is a date, or a datetime
        if secondpart.find(datetimedelimiter) != -1:
            #<end> is a datetime
            duration = parse_duration(firstpart)
            enddatetime = parse_datetime(secondpart, delimiter=datetimedelimiter)

            return (enddatetime, enddatetime - duration)
        else:
            #<end> must just be a date
            duration = parse_duration(firstpart)
            enddate = parse_date(secondpart)

            #See if we need to upconvert to datetime to preserve resolution
            if firstpart.find(datetimedelimiter) != -1:
                return (enddate, datetime.combine(enddate, datetime.min.time()) - duration)
            else:
                return (enddate, enddate - duration)
    elif secondpart[0] == 'P':
        #<start>/<duration>
        #We need to figure out if <start> is a date, or a datetime
        if firstpart.find(datetimedelimiter) != -1:
            #<end> is a datetime
            duration = parse_duration(secondpart)
            startdatetime = parse_datetime(firstpart, delimiter=datetimedelimiter)

            return (startdatetime, startdatetime + duration)
        else:
            #<start> must just be a date
            duration = parse_duration(secondpart)
            startdate = parse_date(firstpart)

            #See if we need to upconvert to datetime to preserve resolution
            if secondpart.find(datetimedelimiter) != -1:
                return (startdate, datetime.combine(startdate, datetime.min.time()) + duration)
            else:
                return (startdate, startdate + duration)
    else:
        #<start>/<end>
        if firstpart.find(datetimedelimiter) != -1 and secondpart.find(datetimedelimiter) != -1:
            #Both parts are datetimes
            return (parse_datetime(firstpart, delimiter=datetimedelimiter), parse_datetime(secondpart, delimiter=datetimedelimiter))
        elif firstpart.find(datetimedelimiter) != -1 and secondpart.find(datetimedelimiter) == -1:
            #First part is a datetime, second part is a date
            return (parse_datetime(firstpart, delimiter=datetimedelimiter), parse_date(secondpart))
        elif firstpart.find(datetimedelimiter) == -1 and secondpart.find(datetimedelimiter) != -1:
            #First part is a date, second part is a datetime
            return (parse_date(firstpart), parse_datetime(secondpart, delimiter=datetimedelimiter))
        else:
            #Both parts are dates
            return (parse_date(firstpart), parse_date(secondpart))
Exemplo n.º 29
0
def _parse_interval_end(endstr, starttuple, datetimedelimiter):
    datestr = None
    timestr = None

    monthstr = None
    daystr = None

    concise = False

    if type(starttuple) is DateTuple:
        startdatetuple = starttuple
    else:
        #Start is a datetime
        startdatetuple = starttuple.date

    if datetimedelimiter in endstr:
        datestr, timestr = endstr.split(datetimedelimiter, 1)
    elif ':' in endstr:
        timestr = endstr
    else:
        datestr = endstr

    if timestr is not None:
        endtimetuple = parse_time(timestr, builder=TupleBuilder)

    #End is just a time
    if datestr is None:
        return endtimetuple

    #Handle backwards concise representation
    if datestr.count('-') == 1:
        monthstr, daystr = datestr.split('-')
        concise = True
    elif len(datestr) <= 2:
        daystr = datestr
        concise = True
    elif len(datestr) <= 4:
        monthstr = datestr[0:2]
        daystr = datestr[2:]
        concise = True

    if concise is True:
        concisedatestr = startdatetuple.YYYY

        #Separators required because concise elements may be missing digits
        if monthstr is not None:
            concisedatestr += '-' + monthstr
        elif startdatetuple.MM is not None:
            concisedatestr += '-' + startdatetuple.MM

        concisedatestr += '-' + daystr

        enddatetuple = parse_date(concisedatestr, builder=TupleBuilder)

        #Clear unsupplied components
        if monthstr is None:
            enddatetuple = TupleBuilder.build_date(DD=enddatetuple.DD)
        else:
            #Year not provided
            enddatetuple = TupleBuilder.build_date(MM=enddatetuple.MM,
                                                   DD=enddatetuple.DD)
    else:
        enddatetuple = parse_date(datestr, builder=TupleBuilder)

    if timestr is None:
        return enddatetuple

    return TupleBuilder.build_datetime(enddatetuple, endtimetuple)