def test_tzone(self): rfc3339 = '2016-07-15T12:33:20.123000+01:30' dt = udatetime.from_string(rfc3339) offset = dt.tzinfo.utcoffset() dst = dt.tzinfo.dst() self.assertIsInstance(offset, timedelta) self.assertEqual(offset.total_seconds() / 60, 90) self.assertEqual(dst, NO_DST) rfc3339 = '2016-07-15T12:33:20.123000Z' dt = udatetime.from_string(rfc3339) offset = dt.tzinfo.utcoffset() dst = dt.tzinfo.dst() self.assertIsInstance(offset, timedelta) self.assertEqual(offset.total_seconds(), 0) self.assertEqual(dst, NO_DST) rfc3339 = '2016-07-15T12:33:20.123000-02:00' dt = udatetime.from_string(rfc3339) offset = dt.tzinfo.utcoffset() dst = dt.tzinfo.dst() self.assertIsInstance(offset, timedelta) self.assertEqual(offset.total_seconds() / 60, -120) self.assertEqual(dst, NO_DST)
def test_modify_typical(usermanager): """ Modify a user, typical "happy path" - change everything """ old = usermanager.modify( "to_change", username="******", password="******", email="*****@*****.**", activated=False, enabled=False, joined=udatetime.from_string('2010-10-23T08:00:00-06:00')) assert usermanager.exists("to_change") is False assert usermanager.exists("othername") is True user = usermanager.get("othername") assert user.id == old.id assert user.key == old.key assert user.username == "othername" assert user.activated is False assert user.enabled is False assert user.joined == udatetime.from_string('2010-10-23T08:00:00-06:00') # skip enabled/activated check assert user.authenticate("newpass", True)
def test_broken_from_string(self): invalid = [ '2016-07-15 12:33:20.123000+01:30', '2016-13-15T12:33:20.123000+01:30', '20161315T12:33:20.123000+01:30', '2016-07-15T12:33:20.1 +01:30', 'Hello World', '2016-07-15 12:33:20.123000+01:302016-07-15 12:33:20.123000+01:30' ] for r in invalid: with self.assertRaises(ValueError): udatetime.from_string(r)
def test_raises(): since = datetime(2016, 6, 1, 0, 0) now = datetime(2015, 6, 3, 0, 0) assert_raises(ValueError, pycron.has_been, '* * * * *', since, now) assert_raises(ValueError, pycron.has_been, '* * * * *', pendulum.instance(since), pendulum.instance(now)) assert_raises(ValueError, pycron.has_been, '* * * * *', arrow.get(since), arrow.get(now)) assert_raises(ValueError, pycron.has_been, '* * * * *', udatetime.from_string(since.isoformat()), udatetime.from_string(now.isoformat())) assert_raises(ValueError, pycron.has_been, '* * * * *', Delorean(datetime=since, timezone='UTC').datetime, Delorean(datetime=now, timezone='UTC').datetime)
def _decode_datetime(value: str, include_tz: bool) -> datetime: # What if the entry is messed up and there's no date? if value is None: return udatetime.from_string('1970-01-01T00:00:00') # Correct `0000-00-00 00:00:00` to `0000-00-00T00:00:00` if re.match(r'^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$', value): value = '%sT%s' % (value[0:10], value[11:]) # Correct `0000-00-00` to `0000-00-00T00:00:00` elif re.match(r'^\d{4}-\d{2}-\d{2}$', value): value = '%sT00:00:00' % value[0:10] decoded = udatetime.from_string(value) if not include_tz: return decoded.astimezone(timezone.utc).replace(tzinfo=None) return decoded
def test_basic_construction_no_params(fixate_now, fixate_randomness): """ Ensure typical case construction of a Code object functions properly - all default parameters. """ from exifcleaner.codes.manager import Code c = Code(user="******") assert c.user == "testuser1" assert c.code == "hODPLE" assert c.created == udatetime.from_string('1993-10-26T08:00:00-04:00') assert c.expires == 3600 assert c.used is False assert c.key == "code:hODPLE" assert c.expires_at() == udatetime.from_string('1993-10-26T09:00:00-04:00')
def parse(value, preserve_original_tz=False): """ Parse a date string and return a time-zone aware datetime object. :param value: Date in ISO8601 format. :type value: ``str`` :param preserve_original_tz: True to preserve the original timezone - by default result is converted into UTC. :type preserve_original_tz: ``boolean`` :rtype: ``datetime.datetime`` """ # We use udatetime since it's much faster than non-C alternatives # For compatibility reasons we still fall back to datetutil, but this should rarely happen # rfc3339 covers 90% of the iso8601 (it's a subset of it) original_value = value try: if " " in value: # udatetime doesn't support notation with whitespace so we replace it with T value = value.replace(" ", "T") dt = udatetime.from_string(str(value)) except Exception: dt = dateutil.parser.parse(str(original_value)) if not dt.tzinfo: dt = add_utc_tz(dt) if not preserve_original_tz: dt = convert_to_utc(dt) return dt
def test_minute(): def run(now): assert pycron.is_now('* * * * *', now) assert pycron.is_now('9 * * * *', now) assert pycron.is_now('*/1 * * * *', now) assert pycron.is_now('*/3 * * * *', now) assert pycron.is_now('*/9 * * * *', now) assert pycron.is_now('3,9,25,16 * * * *', now) assert pycron.is_now('*/2 * * * *', now) is False assert pycron.is_now('*/4 * * * *', now) is False assert pycron.is_now('*/5 * * * *', now) is False assert pycron.is_now('*/12 * * * *', now) is False assert pycron.is_now('3,25,16 * * * *', now) is False assert pycron.is_now('0-10 * * * *', now) assert pycron.is_now('0-10 0-10 * * *', now) assert pycron.is_now('10-20 * * * *', now) is False assert pycron.is_now('10-20 10-20 * * *', now) is False assert pycron.is_now('1,2,5-10 * * * *', now) assert pycron.is_now('9,5-8 * * * *', now) assert pycron.is_now('10,20-30 * * * *', now) is False # Issue 14 assert pycron.is_now('1-59/2 * * * *', now) is True assert pycron.is_now('1-59/4 * * * *', now) is True assert pycron.is_now('1-59/8 * * * *', now) is True now = datetime(2015, 6, 18, 0, 9) run(now) run(now.replace(tzinfo=utc)) run(pendulum.instance(now)) run(arrow.get(now)) run(udatetime.from_string(now.isoformat())) run(Delorean(datetime=now, timezone='UTC').datetime)
def test_day_matching(): def run(now): for i in range(0, 7): # Test day matching from Sunday onwards... now += timedelta(days=1) assert pycron.is_now('* * * * %s' % (pycron.DAY_NAMES[i]), now) assert pycron.is_now('* * * * %s' % (pycron.DAY_ABBRS[i]), now) # Test weekdays assert pycron.is_now('* * * * mon,tue,wed,thu,fri', now) is (True if i not in [0, 6] else False) assert pycron.is_now('* * * * monday,tuesday,wednesday,thursday,friday', now) is (True if i not in [0, 6] else False) assert pycron.is_now( '* * * * mon-fri', now) is (True if i not in [0, 6] else False) assert pycron.is_now( '* * * * monday-friday', now) is (True if i not in [0, 6] else False) assert pycron.is_now('* * * * mon,tue,wed,thu-fri', now) is (True if i not in [0, 6] else False) assert pycron.is_now('* * * * monday,tuesday,wednesday,thursday-friday', now) is (True if i not in [0, 6] else False) # Test weekends assert pycron.is_now( '* * * * sun,sat', now) is (True if i in [0, 6] else False) assert pycron.is_now( '* * * * sunday,saturday', now) is (True if i in [0, 6] else False) now = datetime(2015, 6, 20, 16, 7) run(now) run(now.replace(tzinfo=utc)) run(pendulum.instance(now)) run(arrow.get(now)) run(udatetime.from_string(now.isoformat())) run(Delorean(datetime=now, timezone='UTC').datetime)
def test_day_matching(): def run(now): for i in range(0, 7): # Test day matching from Sunday onwards... now += timedelta(days=1) assert pycron.is_now('* * * * %s' % (pycron.DAY_NAMES[i]), now) assert pycron.is_now('* * * * %s' % (pycron.DAY_ABBRS[i]), now) # Test weekdays assert pycron.is_now('* * * * mon,tue,wed,thu,fri', now) is (True if i not in [0, 6] else False) assert pycron.is_now( '* * * * monday,tuesday,wednesday,thursday,friday', now) is (True if i not in [0, 6] else False) assert pycron.is_now('* * * * mon-fri', now) is (True if i not in [0, 6] else False) assert pycron.is_now('* * * * monday-friday', now) is (True if i not in [0, 6] else False) assert pycron.is_now('* * * * mon,tue,wed,thu-fri', now) is (True if i not in [0, 6] else False) assert pycron.is_now( '* * * * monday,tuesday,wednesday,thursday-friday', now) is (True if i not in [0, 6] else False) # Test weekends assert pycron.is_now('* * * * sun,sat', now) is (True if i in [0, 6] else False) assert pycron.is_now('* * * * sunday,saturday', now) is (True if i in [0, 6] else False) now = datetime(2015, 6, 20, 16, 7) run(now) run(now.replace(tzinfo=utc)) run(pendulum.instance(now)) run(arrow.get(now)) run(udatetime.from_string(now.isoformat())) run(Delorean(datetime=now, timezone='UTC').datetime)
def _decode_datetime(value: str, include_tz: bool) -> datetime: # Correct `0000-00-00 00:00` to `0000-00-00T00:00` if value[10] == ' ': value = '%sT%s' % (value[0:10], value[11:]) decoded = udatetime.from_string(value) if not include_tz: return decoded.astimezone(timezone.utc).replace(tzinfo=None) return decoded
def test_from_and_to_string(self): rfc3339 = '2016-07-15T12:33:20.123000+01:30' dt = udatetime.from_string(rfc3339) self.assertIsInstance(dt, datetime) self.assertEqual(dt.year, 2016) self.assertEqual(dt.month, 7) self.assertEqual(dt.day, 15) self.assertEqual(dt.hour, 12) self.assertEqual(dt.minute, 33) self.assertEqual(dt.second, 20) self.assertEqual(dt.microsecond, 123000) self.assertEqual(udatetime.to_string(dt), rfc3339) rfc3339 = '2016-07-18T12:58:26.485897-02:00' dt = udatetime.from_string(rfc3339) self.assertEqual(udatetime.to_string(dt), rfc3339)
def format_benchmark_data_for_codespeed(data, codespeed_project, codespeed_executable, codespeed_environment): # type: (dict, str, str, str) -> List[dict] """ Format benchmark data dictionary for CodeSpeed /add/result payload format. :param data: Raw data as exposed by pytest-benchmark. """ commit_id = data["commit_info"]["id"] branch = data["commit_info"]["branch"] author_time = data["commit_info"]["author_time"] # This value can contain a timezone so we rely on 3rd party library to parse it. # Our performance optimized version of the function doesn't support timezones. author_time = udatetime.from_string(author_time) revision_date = time.strftime("%Y-%m-%d %H:%M:%S", author_time.utctimetuple()) payload = [] for item in data["benchmarks"]: # We use median for the actual value value = item["stats"]["median"] value_min = item["stats"]["min"] value_max = item["stats"]["max"] value_stddev = item["stats"]["stddev"] benchmark = item["name"] submit_result_to_codespeed = item["options"].get( "submit_result_to_codespeed", False) if not submit_result_to_codespeed: continue # Convert all the input values to milliseconds # NOTE: Input values are in seconds value = seconds_to_ms(value) value_min = seconds_to_ms(value_min) value_max = seconds_to_ms(value_max) value_stddev = seconds_to_ms(value_stddev) item = { "commitid": commit_id, "revision_date": revision_date, "branch": branch, "project": codespeed_project, "executable": codespeed_executable, "benchmark": benchmark, "environment": codespeed_environment, "result_value": value, "min": value_min, "max": value_max, "std_dev": value_stddev, } payload.append(item) return payload
def test_minute_ranges(): for i in range(1, 59, 2): now = datetime(2015, 6, 18, 0, i) assert pycron.is_now('1-59/2 * * * *', now) assert pycron.is_now('1-59/2 * * * *', now.replace(tzinfo=utc)) assert pycron.is_now('1-59/2 * * * *', pendulum.instance(now)) assert pycron.is_now('1-59/2 * * * *', arrow.get(now)) assert pycron.is_now('1-59/2 * * * *', udatetime.from_string(now.isoformat())) assert pycron.is_now('1-59/2 * * * *', Delorean(datetime=now, timezone='UTC').datetime) for i in range(0, 59, 2): now = datetime(2015, 6, 18, 0, i) assert pycron.is_now('1-59/2 * * * *', now) is False assert pycron.is_now('1-59/2 * * * *', now.replace(tzinfo=utc)) is False assert pycron.is_now('1-59/2 * * * *', pendulum.instance(now)) is False assert pycron.is_now('1-59/2 * * * *', arrow.get(now)) is False assert pycron.is_now('1-59/2 * * * *', udatetime.from_string(now.isoformat())) is False assert pycron.is_now('1-59/2 * * * *', Delorean(datetime=now, timezone='UTC').datetime) is False
def from_redis(cls, data): user = data['user'] created = udatetime.from_string(data['created']) expires = int(data['expires']) code = data['code'] obj = cls(user=user, code=code, created=created, expires=expires) return obj
def datetime_from_string(value): """ Given a string that should be an RFC3339 datetime, return a python datetime object. """ if isinstance(value, str): return udatetime.from_string(value) else: return value
def validator(self, value): if isinstance(value, datetime.datetime): return value elif isinstance(value, str): try: return udatetime.from_string(value) except ValueError: raise errors.BadDateFormat() else: raise errors.BadType()
def test_add_happy_path(fixture_initial_data, fixate_randomness, fixate_now): """ Add a new code using the manager. Typical use case. """ from exifcleaner.codes.manager import CodeManager manager = CodeManager() manager.new("activeuser") code = manager.get("activeuser") assert code.user == fixture_initial_data['active'].id assert code.code == "hODPLE" assert code.created == udatetime.from_string('1993-10-26T08:00:00-04:00') assert code.expires == 3600 assert code.used is False assert code.key == "code:hODPLE" assert code.expires_at() == udatetime.from_string( '1993-10-26T09:00:00-04:00')
def test_days(): def run(since, now): assert pycron.has_been('* * * * *', since, now) assert pycron.has_been('* * 0 * *', since, now) is False assert pycron.has_been('* * 1 * *', since, now) assert pycron.has_been('* * 2 * *', since, now) assert pycron.has_been('* * 3 * *', since, now) assert pycron.has_been('* * 4 * *', since, now) is False since = datetime(2015, 6, 1, 0, 0) now = datetime(2015, 6, 3, 0, 0) run(since, now) run(since.replace(tzinfo=utc), now.replace(tzinfo=utc)) run(pendulum.instance(since), pendulum.instance(now)) run(arrow.get(since), arrow.get(now)) run(udatetime.from_string(since.isoformat()), udatetime.from_string(now.isoformat())) run( Delorean(datetime=since, timezone='UTC').datetime, Delorean(datetime=now, timezone='UTC').datetime)
def _decode_datetime(value: str, include_tz: bool) -> datetime: # Correct `0000-00-00 00:00:00` to `0000-00-00T00:00:00` if re.match(r'^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(.\d)?$', value): value = '%sT%s' % (value[0:10], value[11:]) # Correct `0000-00-00` to `0000-00-00T00:00:00` elif re.match(r'^\d{4}-\d{2}-\d{2}$', value): value = '%sT00:00:00' % value[0:10] decoded = udatetime.from_string(value) if not include_tz: return decoded.astimezone(timezone.utc).replace(tzinfo=None) return decoded
def test_from_redis(): """ Test the from_redis() class method. """ from exifcleaner.codes.manager import Code data = { 'user': '******', 'code': 'code-1-2-3', 'created': '2010-11-03T10:00:00-04:00', 'used': '1', 'expires': '3423' } c = Code.from_redis(data) assert c.user == "test-user-2" assert c.code == "code-1-2-3" assert c.created == udatetime.from_string('2010-11-03T10:00:00-04:00') assert c.expires == 3423 assert c.used is True assert c.key == "code:code-1-2-3" assert c.expires_at() == udatetime.from_string( '2010-11-03T10:57:03.000000-04:00')
def get_datetime_and_remove_timezone(datetime_str: str) -> datetime: """ Get a datetime and remove the timezone info :param datetime_str: Datetime string :return: Naive Datetime in UTC """ with_tz = udatetime.from_string(datetime_str) from datetime import timedelta if with_tz.tzinfo: published = with_tz + timedelta(minutes=-with_tz.tzinfo.offset) published = published.replace(tzinfo=None) return published return with_tz
def test_last_minute(): def run(now): assert pycron.is_now('* * * * *', now) assert pycron.is_now('59 * * * *', now) assert pycron.is_now('*/1 * * * *', now) # Issue 14 assert pycron.is_now('1-59/2 * * * *', now) is True now = datetime(2015, 6, 18, 0, 59) run(now) run(now.replace(tzinfo=utc)) run(pendulum.instance(now)) run(arrow.get(now)) run(udatetime.from_string(now.isoformat())) run(Delorean(datetime=now, timezone='UTC').datetime)
def ensure_datetime(o): if o is None: return None if isinstance(o, datetime): return o if isinstance(o, date): return datetime.combine(o, datetime.min.time(), tzinfo=timezone.utc) if isinstance(o, (int, float)): return udatetime.fromtimestamp(o, tz=udatetime.TZFixedOffset(0)) if isinstance(o, date): o = datetime.combine(o, datetime.min.time()) try: return udatetime.from_string(o) except Exception: return o
def test_ok_from_string(self): rfc3339s = [ '2016-07-15 T 12:33:20.123000 +01:30', '2016-07-15 T 12:33:20.123000 +01:30', '2016-07-15T12:33:20.123 +01:30', '2016-07-15T12:33:20 +01:30', '2016-07-15T12:33:20 Z', '2016-07-15T12:33:20', '2016-07-15t12:33:20' ] for r in rfc3339s: self.assertIsInstance( udatetime.from_string(r), datetime )
def test_day_names(): def run(now): assert pycron.is_now('* * * * *', now) assert pycron.is_now('* * * * thu', now) assert pycron.is_now('* * * * thursday', now) assert pycron.is_now('* * * * */thu', now) assert pycron.is_now('* * * * */thursday', now) assert pycron.is_now('* * * * sun,wed,thu', now) assert pycron.is_now('* * * * sunday,wednesday,thursday', now) assert pycron.is_now('* * * * wed', now) is False assert pycron.is_now('* * * * wednesday', now) is False assert pycron.is_now('* * * * */wed', now) is False assert pycron.is_now('* * * * */wednesday', now) is False assert pycron.is_now('* * * * sun,wed,sat', now) is False assert pycron.is_now('* * * * sunday,wednesday,saturday', now) is False assert pycron.DOW_CHOICES[now.isoweekday()][1] == 'thursday' assert pycron.DOW_CHOICES[0][1] == 'sunday' assert pycron.is_now('* * * * sun-thu', now) assert pycron.is_now('* * * * sunday-thursday', now) assert pycron.is_now('* * * * fri-sat', now) is False assert pycron.is_now('* * * * friday-saturday', now) is False # Special cases, where the day names are more or less incorrectly set... assert pycron.is_now('* * * * thu-sun', now) assert pycron.is_now('* * * * thursday-sunday', now) assert pycron.is_now('* * * * wed-sun', now) assert pycron.is_now('* * * * wednesday-sunday', now) assert pycron.is_now('* * * * wed-mon', now) assert pycron.is_now('* * * * wednesday-monday', now) assert pycron.is_now('* * * * fri-sun', now) is False assert pycron.is_now('* * * * friday-sunday', now) is False assert pycron.is_now('* * * * fri-wed', now) is False assert pycron.is_now('* * * * friday-wednesday', now) is False # Test day matching for dividers assert pycron.is_now('* * * * monday-sunday/3', now) is False assert pycron.is_now('* * * * mon-sun/3', now) is False assert pycron.is_now('* * * * tuesday-sunday/2', now) is False assert pycron.is_now('* * * * tue-sun/2', now) is False now = datetime(2015, 6, 18, 16, 7) run(now) run(now.replace(tzinfo=utc)) run(pendulum.instance(now)) run(arrow.get(now)) run(udatetime.from_string(now.isoformat())) run(Delorean(datetime=now, timezone='UTC').datetime)
def _decode_datetime(value: str, include_tz: bool) -> datetime: try: # Correct `0000-00-00 00:00:00` to `0000-00-00T00:00:00` if re.match( r'^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$', value) or (re.match( r'^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}:\d{1}$', value)): value = '%sT%s' % (value[0:10], value[11:]) # Correct `0000-00-00` to `0000-00-00T00:00:00` elif re.match(r'^\d{4}-\d{2}-\d{2}$', value): value = '%sT00:00:00' % value[0:10] decoded = udatetime.from_string(value.replace(' ', 'T')) except: decoded = datetime(year=1970, day=1, month=1) if not include_tz: return decoded.astimezone(timezone.utc).replace(tzinfo=None) return decoded
def _rfc3339_to_nanoseconds_since_epoch_udatetime(string): """ rfc3339_to_nanoseconds_since_epoch variation which utilizes udatetime library. """ # split the string in to main time and fractional component parts = string.split(".") # it's possible that the time does not have a fractional component # e.g 2015-08-03T09:12:43Z, in this case 'parts' will only have a # single element that should end in Z. Strip the Z if it exists # so we can use the same format string for processing the main # date+time regardless of whether the time has a fractional component. if parts[0].endswith("Z"): parts[0] = parts[0][:-1] try: dt = udatetime.from_string(parts[0]) except ValueError: return None nano_seconds = (calendar.timegm( (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second)) * 1000000000) nanos = 0 # now add the fractional part if len(parts) > 1: fractions = parts[1] # if the fractional part doesn't end in Z we likely have a # malformed time, so just return the current value if not fractions.endswith("Z"): # we don't handle non UTC timezones yet if any(c in fractions for c in "+-"): return None return nano_seconds # strip the final 'Z' and use the final number for processing fractions = fractions[:-1] to_nanos = 9 - len(fractions) nanos = int(int(fractions) * 10**to_nanos) return nano_seconds + nanos
def benchmark_format(): def _datetime(): offset = DATETIME_OBJ.tzinfo.utcoffset(None).total_seconds() / 60 tz = '' if offset < 0: offset = offset * -1 tz = '-%02d:%02d' % (offset / 60, offset % 60) else: tz = '+%02d:%02d' % (offset / 60, offset % 60) return DATETIME_OBJ.strftime(DATE_TIME_FORMAT) + tz uda = udatetime.from_string(RFC3339_DATE_TIME) def _udatetime(): return udatetime.to_string(uda) arr = arrow.get(RFC3339_DATE_TIME) def _arrow(): return arr.isoformat() pen = pendulum.parse(RFC3339_DATE_TIME) def _pendulum(): return pen.to_rfc3339_string(True) delo = delorean.parse(RFC3339_DATE_TIME) def _delorean(): offset = delo.datetime.tzinfo.utcoffset(None).total_seconds() / 60 tz = '' if offset < 0: offset = offset * -1 tz = '-%02d:%02d' % (offset / 60, offset % 60) else: tz = '+%02d:%02d' % (offset / 60, offset % 60) return delo.datetime.strftime(DATE_TIME_FORMAT) + tz return (_datetime, _udatetime, _arrow, _pendulum, _delorean)
def test_dow(): def run(now): assert pycron.is_now('* * * * * *', now) assert pycron.is_now('* * * * * 169', now) assert pycron.is_now('* * * * * 1-365/2', now) assert pycron.is_now('* * * * * 168,169,170', now) assert pycron.is_now('* * * * * 170', now) is False assert pycron.is_now('* * * * * */2', now) is False assert pycron.is_now('* * * * * 165,166,167', now) is False assert pycron.is_now('* * * * 0-170', now) assert pycron.is_now('* * * * 170-365', now) is False now = datetime(2015, 6, 18, 16, 7) run(now) run(now.replace(tzinfo=utc)) run(pendulum.instance(now)) run(arrow.get(now)) run(udatetime.from_string(now.isoformat())) run(Delorean(datetime=now, timezone='UTC').datetime)
def _rfc3339_to_datetime_udatetime(string): # type: (str) -> Optional[datetime.datetime] """ rfc3339_to_datetime variation which utilizes udatetime library. """ # split the string in to main time and fractional component parts = string.split(".") # it's possible that the time does not have a fractional component # e.g 2015-08-03T09:12:43Z, in this case 'parts' will only have a # single element that should end in Z. Strip the Z if it exists # so we can use the same format string for processing the main # date+time regardless of whether the time has a fractional component. if parts[0].endswith("Z"): parts[0] = parts[0][:-1] # create a datetime object try: dt = udatetime.from_string(parts[0]) # NOTE: At this point we don't support timezones dt = dt.replace(tzinfo=None) except ValueError: return None # now add the fractional part if len(parts) > 1: fractions = parts[1] # if we had a fractional component it should terminate in a Z if not fractions.endswith("Z"): # we don't handle non UTC timezones yet if any(c in fractions for c in "+-"): return None return dt # remove the Z and just process the fraction. fractions = fractions[:-1] to_micros = 6 - len(fractions) micro = int(int(fractions) * 10**to_micros) # NOTE(Tomaz): dt.replace is quite slow... dt = dt.replace(microsecond=micro) return dt
def test_dom(): def run(now): assert pycron.is_now('* * * * *', now) assert pycron.is_now('* * 18 * *', now) assert pycron.is_now('* * */6 * *', now) assert pycron.is_now('* * 1,16,18 * *', now) assert pycron.is_now('* * 19 * *', now) is False assert pycron.is_now('* * */4 * *', now) is False assert pycron.is_now('* * 1,16 * *', now) is False assert pycron.is_now('* * 1,16 * *', now) is False assert pycron.is_now('* * 1-20 * *', now) assert pycron.is_now('* * 20-31 * *', now) is False now = datetime(2015, 6, 18, 16, 7) run(now) run(now.replace(tzinfo=utc)) run(pendulum.instance(now)) run(arrow.get(now)) run(udatetime.from_string(now.isoformat())) run(Delorean(datetime=now, timezone='UTC').datetime)
def test_check_method_no_errors(self): schema = self.schema() data = { 'email': "*****@*****.**", 'password': "******", 'active': False, 'username': "******", 'last-visit': '2001-09-26T08:00:00-04:00' } expected = { 'username': "******", 'email': "*****@*****.**", 'password': "******", 'active': False, 'last-visit': udatetime.from_string(data['last-visit']) } self.assertEqual(schema.validict(data), expected)
def test_parser(): def run(now): assert pycron.is_now('* * * * *', now) assert pycron.is_now('* * * 6 *', now) assert pycron.is_now('* * * */2 *', now) assert pycron.is_now('* * * 1,4,6,12 *', now) assert pycron.is_now('* * * 5 *', now) is False assert pycron.is_now('* * * */5 *', now) is False assert pycron.is_now('* * * 1,4,12 *', now) is False assert pycron.MONTH_CHOICES[now.month - 1][1] == 'June' assert pycron.is_now('* * * 5-8 *', now) assert pycron.is_now('* * * 8-10 *', now) is False now = datetime(2015, 6, 18, 16, 7) run(now) run(now.replace(tzinfo=utc)) run(pendulum.instance(now)) run(arrow.get(now)) run(udatetime.from_string(now.isoformat())) run(Delorean(datetime=now, timezone='UTC').datetime)
def test_day_matching(): def run(now): for i in range(0, 7): # Test day matching from Sunday onwards... now += timedelta(days=1) assert pycron.is_now('* * * * %i' % (i), now) # Test weekdays assert pycron.is_now('* * * * 1,2,3,4,5', now) is (True if i not in [0, 6] else False) assert pycron.is_now('* * * * 1-5', now) is (True if i not in [0, 6] else False) assert pycron.is_now('* * * * 1,2,3,4-5', now) is (True if i not in [0, 6] else False) # Test weekends assert pycron.is_now('* * * * 0,6', now) is (True if i in [0, 6] else False) now = datetime(2015, 6, 20, 16, 7) run(now) run(now.replace(tzinfo=utc)) run(pendulum.instance(now)) run(arrow.get(now)) run(udatetime.from_string(now.isoformat())) run(Delorean(datetime=now, timezone='UTC').datetime)
def test_dow(): def run(now): assert pycron.is_now('* * * * *', now) assert pycron.is_now('* * * * 4', now) assert pycron.is_now('* * * * */4', now) assert pycron.is_now('* * * * 0,3,4', now) assert pycron.is_now('* * * * 3', now) is False assert pycron.is_now('* * * * */3', now) is False assert pycron.is_now('* * * * 0,3,6', now) is False assert pycron.DOW_CHOICES[now.isoweekday()][1] == 'thursday' assert pycron.DOW_CHOICES[0][1] == 'sunday' assert pycron.is_now('* * * * 0-4', now) assert pycron.is_now('* * * * 5-6', now) is False now = datetime(2015, 6, 18, 16, 7) run(now) run(now.replace(tzinfo=utc)) run(pendulum.instance(now)) run(arrow.get(now)) run(udatetime.from_string(now.isoformat())) run(Delorean(datetime=now, timezone='UTC').datetime)
def updated(self, item: Dict) -> datetime: """ Gets an updated datetime for an item. :param item: deserialized JSON item :type item: Dict :return: datetime """ updated = None try: updated = udatetime.from_string(item.get("date_modified", "")) except Exception as e: app.logger.warning( "Exception getting updated date from date_modified " "for item %s from %s: %s", self.item_id, self.feed, e, ) return updated
def test_variable_fraction(self): rfc3339 = '2016-07-15T12:33:20.1' d1 = udatetime.from_string(rfc3339 + ('0' * 5) + 'Z') for x in range(0, 6): d2 = udatetime.from_string(rfc3339 + ('0' * x) + 'Z') self.assertEqual(d1, d2) self.assertEqual( udatetime.from_string('2016-07-15T12:33:20.123Z'), udatetime.from_string('2016-07-15T12:33:20.123000Z'), ) self.assertEqual( udatetime.from_string('2016-07-15T12:33:20.0Z'), udatetime.from_string('2016-07-15T12:33:20Z'), )
def test_hour(): def run(now): assert pycron.is_now('* * * * *', now) assert pycron.is_now('* 16 * * *', now) assert pycron.is_now('* */4 * * *', now) assert pycron.is_now('*/7 16 * * *', now) assert pycron.is_now('*/7 */8 * * *', now) assert pycron.is_now('* 2,8,16 * * *', now) assert pycron.is_now('* */9 * * *', now) is False assert pycron.is_now('* */5 * * *', now) is False assert pycron.is_now('*/3 */4 * * *', now) is False assert pycron.is_now('3 16 * * *', now) is False assert pycron.is_now('*/8 */3 * * *', now) is False assert pycron.is_now('* 2,8 * * *', now) is False assert pycron.is_now('* 16-20 * * *', now) assert pycron.is_now('* 0-10 * * *', now) is False now = datetime(2015, 6, 18, 16, 7) run(now) run(now.replace(tzinfo=utc)) run(pendulum.instance(now)) run(arrow.get(now)) run(udatetime.from_string(now.isoformat())) run(Delorean(datetime=now, timezone='UTC').datetime)
def _parse_udatetime(self, value): return udatetime.from_string(value)
def udatetime_parse(): udatetime.from_string(RFC3339_DATE_TIME)