def _parse_duration_element(durationstr, elementstr): #Extracts the specified portion of a duration, for instance, given: #durationstr = 'T4H5M6.1234S' #elementstr = 'H' # #returns 4 # #Note that the string must start with a character, so its assumed the #full duration string would be split at the 'T' durationstartindex = 0 durationendindex = durationstr.find(elementstr) for characterindex in compat.range(durationendindex - 1, 0, -1): if durationstr[characterindex].isalpha() is True: durationstartindex = characterindex break durationstartindex += 1 if ',' in durationstr: #Replace the comma with a 'full-stop' durationstr = durationstr.replace(',', '.') return durationstr[durationstartindex:durationendindex]
def _parse_duration_element(durationstr, elementstr): #Extracts the specified portion of a duration, for instance, given: #durationstr = 'T4H5M6.1234S' #elementstr = 'H' # #returns 4 # #Note that the string must start with a character, so its assumed the #full duration string would be split at the 'T' durationstartindex = 0 durationendindex = durationstr.find(elementstr) for characterindex in compat.range(durationendindex - 1, 0, -1): if durationstr[characterindex].isalpha() == True: durationstartindex = characterindex break durationstartindex += 1 if ',' in durationstr: #Replace the comma with a 'full-stop' durationstr = durationstr.replace(',', '.') return float(durationstr[durationstartindex:durationendindex])
def _parse_duration_element(durationstr, elementstr): #Extracts the specified portion of a duration, for instance, given: #durationstr = 'T4H5M6.1234S' #elementstr = 'H' # #returns 4 # #Note that the string must start with a character, so its assumed the #full duration string would be split at the 'T' durationstartindex = 0 durationendindex = durationstr.find(elementstr) for characterindex in compat.range(durationendindex - 1, 0, -1): if durationstr[characterindex].isalpha() is True: durationstartindex = characterindex break durationstartindex += 1 if ',' in durationstr: #Replace the comma with a 'full-stop' durationstr = durationstr.replace(',', '.') if elementstr == 'S': #We truncate seconds to avoid precision issues with microseconds #https://bitbucket.org/nielsenb/aniso8601/issues/10/sub-microsecond-precision-in-durations-is if '.' in durationstr[durationstartindex:durationendindex]: stopindex = durationstr.index('.') if durationendindex - stopindex > 7: durationendindex = stopindex + 7 return float(durationstr[durationstartindex:durationendindex])
def test_parse_repeating_interval(self): results = list(parse_repeating_interval('R3/1981-04-05/P1D')) self.assertEqual(results[0], datetime.date(year=1981, month=4, day=5)) self.assertEqual(results[1], datetime.date(year=1981, month=4, day=6)) self.assertEqual(results[2], datetime.date(year=1981, month=4, day=7)) results = list( parse_repeating_interval('R11/PT1H2M/1980-03-05T01:01:00')) for dateindex in compat.range(0, 11): self.assertEqual( results[dateindex], datetime.datetime(year=1980, month=3, day=5, hour=1, minute=1) - dateindex * datetime.timedelta(hours=1, minutes=2)) results = list( parse_repeating_interval( 'R2--1980-03-05T01:01:00--1981-04-05T01:01:00', intervaldelimiter='--')) self.assertEqual( results[0], datetime.datetime(year=1980, month=3, day=5, hour=1, minute=1)) self.assertEqual( results[1], datetime.datetime(year=1981, month=4, day=5, hour=1, minute=1)) results = list( parse_repeating_interval( 'R2/1980-03-05 01:01:00/1981-04-05 01:01:00', datetimedelimiter=' ')) self.assertEqual( results[0], datetime.datetime(year=1980, month=3, day=5, hour=1, minute=1)) self.assertEqual( results[1], datetime.datetime(year=1981, month=4, day=5, hour=1, minute=1)) resultgenerator = parse_repeating_interval( 'R/PT1H2M/1980-03-05T01:01:00') for dateindex in compat.range(0, 11): self.assertEqual( next(resultgenerator), datetime.datetime(year=1980, month=3, day=5, hour=1, minute=1) - dateindex * datetime.timedelta(hours=1, minutes=2))
def _component_order_correct(durationstr, componentorder): # Given a duration string, and a list of components, returns # True if the components are in the same order as the # component order list, False otherwise. Characters that # are present in the component order list but not in the # duration string are ignored. # # https://bitbucket.org/nielsenb/aniso8601/issues/8/durations-with-components-in-wrong-order # # durationstr = 'P1Y1M1D' # components = ['P', 'Y', 'M', 'D'] # # returns True # # durationstr = 'P1Y1M' # components = ['P', 'Y', 'M', 'D'] # # returns True # # durationstr = 'P1D1Y1M' # components = ['P', 'Y', 'M', 'D'] # # returns False componentindex = 0 for characterindex in compat.range(len(durationstr)): character = durationstr[characterindex] if character in componentorder: # This is a character we need to check the order of if character in componentorder[componentindex:]: componentindex = componentorder.index(character) else: # A character is out of order return False return True
def _component_order_correct(durationstr, componentorder): #Given a duration string, and a list of components, returns #True if the components are in the same order as the #component order list, False otherwise. Characters that #are present in the component order list but not in the #duration string are ignored. # #https://bitbucket.org/nielsenb/aniso8601/issues/8/durations-with-components-in-wrong-order # #durationstr = 'P1Y1M1D' #components = ['P', 'Y', 'M', 'D'] # #returns True # #durationstr = 'P1Y1M' #components = ['P', 'Y', 'M', 'D'] # #returns True # #durationstr = 'P1D1Y1M' #components = ['P', 'Y', 'M', 'D'] # #returns False componentindex = 0 for characterindex in compat.range(len(durationstr)): character = durationstr[characterindex] if character in componentorder: #This is a character we need to check the order of if character in componentorder[componentindex:]: componentindex = componentorder.index(character) else: #A character is out of order return False return True
class TimeResolution(object): Seconds, Minutes, Hours = list(compat.range(3))
class DateResolution(object): Year, Month, Week, Weekday, Day, Ordinal = list(compat.range(6))
def test_parse_repeating_interval_relative(self): results = list( parse_repeating_interval('R3/1981-04-05/P1D', relative=True)) self.assertEqual(results[0], datetime.date(year=1981, month=4, day=5)) self.assertEqual(results[1], datetime.date(year=1981, month=4, day=6)) self.assertEqual(results[2], datetime.date(year=1981, month=4, day=7)) results = list( parse_repeating_interval('R11/PT1H2M/1980-03-05T01:01:00', relative=True)) for dateindex in compat.range(0, 11): self.assertEqual( results[dateindex], datetime.datetime(year=1980, month=3, day=5, hour=1, minute=1) - dateindex * datetime.timedelta(hours=1, minutes=2)) results = list( parse_repeating_interval( 'R2--1980-03-05T01:01:00--1981-04-05T01:01:00', intervaldelimiter='--', relative=True)) self.assertEqual( results[0], datetime.datetime(year=1980, month=3, day=5, hour=1, minute=1)) self.assertEqual( results[1], datetime.datetime(year=1981, month=4, day=5, hour=1, minute=1)) results = list( parse_repeating_interval( 'R2/1980-03-05 01:01:00/1981-04-05 01:01:00', datetimedelimiter=' ', relative=True)) self.assertEqual( results[0], datetime.datetime(year=1980, month=3, day=5, hour=1, minute=1)) self.assertEqual( results[1], datetime.datetime(year=1981, month=4, day=5, hour=1, minute=1)) #Make sure relative is correctly applied for months #https://bitbucket.org/nielsenb/aniso8601/issues/12/month-intervals-calculated-incorrectly-or results = list( parse_repeating_interval('R4/2017-04-30T00:00:00/P1M', relative=True)) self.assertEqual(results[0], datetime.datetime(year=2017, month=4, day=30)) self.assertEqual(results[1], datetime.datetime(year=2017, month=5, day=30)) self.assertEqual(results[2], datetime.datetime(year=2017, month=6, day=30)) self.assertEqual(results[3], datetime.datetime(year=2017, month=7, day=30)) resultgenerator = parse_repeating_interval( 'R/PT1H2M/1980-03-05T01:01:00', relative=True) for dateindex in compat.range(0, 11): self.assertEqual( next(resultgenerator), datetime.datetime(year=1980, month=3, day=5, hour=1, minute=1) - dateindex * datetime.timedelta(hours=1, minutes=2))
def test_build_repeating_interval(self): #Repeating intervals are contingent on durations, make sure they work args = { 'Rnn': '3', 'interval': (('1981', '04', '05', None, None, None, 'date'), None, (None, None, None, '1', None, None, None, 'duration'), 'interval') } results = list(RelativeTimeBuilder.build_repeating_interval(**args)) self.assertEqual(results[0], datetime.date(year=1981, month=4, day=5)) self.assertEqual(results[1], datetime.date(year=1981, month=4, day=6)) self.assertEqual(results[2], datetime.date(year=1981, month=4, day=7)) args = { 'Rnn': '11', 'interval': (None, (('1980', '03', '05', None, None, None, 'date'), ('01', '01', '00', None, 'time'), 'datetime'), (None, None, None, None, '1', '2', None, 'duration'), 'interval') } results = list(RelativeTimeBuilder.build_repeating_interval(**args)) for dateindex in compat.range(0, 11): self.assertEqual( results[dateindex], datetime.datetime(year=1980, month=3, day=5, hour=1, minute=1) - dateindex * datetime.timedelta(hours=1, minutes=2)) #Make sure relative is correctly applied for months #https://bitbucket.org/nielsenb/aniso8601/issues/12/month-intervals-calculated-incorrectly-or args = { 'Rnn': '4', 'interval': ((('2017', '04', '30', None, None, None, 'date'), ('00', '00', '00', None, 'time'), 'datetime'), None, (None, '1', None, None, None, None, None, 'duration'), 'interval') } results = list(RelativeTimeBuilder.build_repeating_interval(**args)) self.assertEqual(results[0], datetime.datetime(year=2017, month=4, day=30)) self.assertEqual(results[1], datetime.datetime(year=2017, month=5, day=30)) self.assertEqual(results[2], datetime.datetime(year=2017, month=6, day=30)) self.assertEqual(results[3], datetime.datetime(year=2017, month=7, day=30)) args = { 'R': True, 'interval': (None, (('1980', '03', '05', None, None, None, 'date'), ('01', '01', '00', None, 'time'), 'datetime'), (None, None, None, None, '1', '2', None, 'duration'), 'interval') } resultgenerator = RelativeTimeBuilder.build_repeating_interval(**args) for dateindex in compat.range(0, 11): self.assertEqual( next(resultgenerator), datetime.datetime(year=1980, month=3, day=5, hour=1, minute=1) - dateindex * datetime.timedelta(hours=1, minutes=2))
class IntervalResolution(object): Year, Month, Week, Weekday, Day, Ordinal, Hours, Minutes, Seconds = list( compat.range(9))
class DurationResolution(object): Years, Months, Weeks, Days, Hours, Minutes, Seconds = list(compat.range(7))