def duration(self): """ Return a duration object """ if self.base_period == "monthly": return Duration(months=1) elif self.base_period == "daily": return Duration(days=1) else: timedelta = relativedelta(dt1=self.stop, dt2=self.start) return Duration(months=timedelta.months, days=timedelta.days, hours=timedelta.hours, minutes=timedelta.minutes, seconds=timedelta.seconds)
def setDuration(self, *args): ''' It can take either one single parameter, or six parameters. @param : if one single parameter, then its type has to be either String or isodate.Duration type. If string, then the string has to align with ISO 8601 standard, with the format like "PnYnMnDTnHnMnS". See: https://www.w3.org/TR/xmlschema-2/#duration If 6 parameters, then all of them need to be integers, representing years, months, days, hours, minutes, seconds. ''' args = list(args) try: if len(args) == 1: duration = args[0] if isinstance(duration, Duration): self.duration = duration elif isinstance(duration, str) or isinstance( duration, unicode): self.duration = isodate.parse_duration(duration) else: raise ("wrong parameter type: " + type(duration)) elif len(args) == 6: self.duration = Duration(years=args[0], months=args[1], days=args[2], hours=args[3], minutes=args[4], seconds=args[5]) else: raise ("The number of parameters has to be either 1 or 6!") except: traceback.print_exc() traceback.print_stack()
def createDuration(cls, years, months, days, hours, minutes, seconds): ''' All 6 parameters are integers. @return: a newly created isodate Duration Object ''' from isodate.duration import Duration return Duration(years=years, months=months, days=days, hours=hours, minutes=minutes, seconds=seconds)
def duration(self) -> "Duration": """ Return a `duration.Duration` object :return: """ tdelta = relativedelta(dt1=self.tce.dt + relativedelta(microseconds=1), dt2=self.tcs.dt) return Duration(years=tdelta.years, months=tdelta.months, days=tdelta.days, hours=tdelta.hours, minutes=tdelta.minutes, seconds=tdelta.seconds)
def test_pickle_duration(self): ''' Pickle / unpickle duration objects. ''' from isodate.duration import Duration dur = Duration() failed = [] for proto in range(0, pickle.HIGHEST_PROTOCOL + 1): try: pikl = pickle.dumps(dur, proto) if dur != pickle.loads(pikl): raise Exception("not equal") except Exception, e: failed.append("pickle proto %d failed (%s)" % (proto, repr(e)))
def test_pickle_duration(self): """ Pickle / unpickle duration objects. """ from isodate.duration import Duration dur = Duration() failed = [] for proto in range(0, pickle.HIGHEST_PROTOCOL + 1): try: pikl = pickle.dumps(dur, proto) if dur != pickle.loads(pikl): raise Exception("not equal") except Exception as e: failed.append("pickle proto %d failed (%s)" % (proto, repr(e))) self.assertEqual(len(failed), 0, "pickle protos failed: %s" % str(failed))
def test_iso_duration_type(self): type_duration = IsoDurationType() period_str = "P3Y6M4DT12H30M5S" duration_period = Duration(years=3, months=6, days=4, hours=12, minutes=30, seconds=5) res_to_native = type_duration.to_native(period_str) self.assertEqual(res_to_native.years, 3) self.assertEqual(res_to_native.months, 6) self.assertEqual(res_to_native.days, 4) self.assertEqual(res_to_native.seconds, 45005) self.assertEqual(res_to_native, duration_period) self.assertEqual(duration_isoformat(res_to_native), period_str) res_to_primitive = type_duration.to_primitive(duration_period) self.assertEqual(res_to_primitive, period_str) # Parse with errors result = type_duration.to_native(duration_period) self.assertEqual(result, duration_period) with self.assertRaises(Exception) as context: result = type_duration.to_native("Ptest") self.assertEqual(context.exception.messages, [ "ISO 8601 time designator 'T' missing. Unable to parse datetime string 'test'" ]) with self.assertRaises(Exception) as context: result = type_duration.to_native("P3Y6MW4DT12H30M5S") self.assertEqual(context.exception.messages, ["Unrecognised ISO 8601 date format: '3Y6MW4D'"]) with self.assertRaises(Exception) as context: result = type_duration.to_native(123123) self.assertEqual( context.exception.messages, ["Could not parse 123123. Should be ISO8601 Durations."]) res_native1 = type_duration.to_native("P3Y6M4DT12H30M5S") res_native2 = type_duration.to_native("P2Y18M4DT12H30M5S") self.assertEqual(res_native1, res_native2) res_dur1 = type_duration.to_primitive(res_native1) res_dur2 = type_duration.to_primitive(res_native2) self.assertEqual("P3Y6M4DT12H30M5S", res_dur1) self.assertEqual("P2Y18M4DT12H30M5S", res_dur2)
def test_iso_duration_type_from_Duration(self): duration_instance = IsoDurationType() duration = Duration(months=1, days=1) self.assertEqual(duration_instance(duration), duration)
from isodate.duration import Duration from ..interval import IntervalManager def test_get_intervalled_forms(manager, create_forms, cleanup_db): forms = manager.get_intervalled_forms() assert len(forms) == 2 @pytest.mark.parametrize( "value,exp_startdate,exp_duration", [ ( "2018-03-01/P1Y2M10D", Duration(10, 0, 0, years=1, months=2), date(2018, 3, 1), ), ("P2W", timedelta(14), None), ("P1Y2M1p0D", False, False), ("P1Y2M10DT2H30M", False, False), ("not a date/P2W", False, False), ("2018-03-01/P2W/", False, False), ], ) def test_parse_interval(manager, value, exp_startdate, exp_duration): startdate, duration = manager.parse_interval(value) assert startdate == exp_startdate assert duration == exp_duration
def parse_duration(datestring): """ Parses an ISO 8601 durations into datetime.timedelta or Duration objects. If the ISO date string does not contain years or months, a timedelta instance is returned, else a Duration instance is returned. The following duration formats are supported: -PnnW duration in weeks -PnnYnnMnnDTnnHnnMnnS complete duration specification -PYYYYMMDDThhmmss basic alternative complete date format -PYYYY-MM-DDThh:mm:ss extended alternative complete date format -PYYYYDDDThhmmss basic alternative ordinal date format -PYYYY-DDDThh:mm:ss extended alternative ordinal date format The '-' is optional. Limitations: ISO standard defines some restrictions about where to use fractional numbers and which component and format combinations are allowed. This parser implementation ignores all those restrictions and returns something when it is able to find all necessary components. In detail: it does not check, whether only the last component has fractions. it allows weeks specified with all other combinations The alternative format does not support durations with years, months or days set to 0. """ if not isinstance(datestring, basestring): raise TypeError("Expecting a string %r" % datestring) match = ISO8601_PERIOD_REGEX.match(datestring) if not match: # try alternative format: if datestring.startswith("P"): durdt = parse_datetime(datestring[1:]) if durdt.year != 0 or durdt.month != 0: # create Duration ret = Duration(days=durdt.day, seconds=durdt.second, microseconds=durdt.microsecond, minutes=durdt.minute, hours=durdt.hour, months=durdt.month, years=durdt.year) else: # FIXME: currently not possible in alternative format # create timedelta ret = timedelta(days=durdt.day, seconds=durdt.second, microseconds=durdt.microsecond, minutes=durdt.minute, hours=durdt.hour) return ret raise ISO8601Error("Unable to parse duration string %r" % datestring) groups = match.groupdict() for key, val in groups.items(): if key not in ('separator', 'sign'): if val is None: groups[key] = "0n" #print groups[key] if key in ('years', 'months'): groups[key] = Decimal(groups[key][:-1].replace(',', '.')) else: # these values are passed into a timedelta object, which works with floats. groups[key] = float(groups[key][:-1].replace(',', '.')) if groups["years"] == 0 and groups["months"] == 0: ret = timedelta(days=groups["days"], hours=groups["hours"], minutes=groups["minutes"], seconds=groups["seconds"], weeks=groups["weeks"]) if groups["sign"] == '-': ret = timedelta(0) - ret else: ret = Duration(years=groups["years"], months=groups["months"], days=groups["days"], hours=groups["hours"], minutes=groups["minutes"], seconds=groups["seconds"], weeks=groups["weeks"]) if groups["sign"] == '-': ret = Duration(0) - ret return ret
def monthsOldData(self, months): ''' Define how many months old data will be searched. ''' duration = Duration(months=months) self.entity.add(URIRef(PROPERTY.FRESHNESS), duration)
def daysOldData(self, days): ''' Define how many days old data will be searched. ''' duration = Duration(days=days) self.entity.add(URIRef(PROPERTY.FRESHNESS), duration)