def _calculate_times(self): """ Calculates and returns several time-related values that tend to be needed at the same time. :return: tuple of numbers described below... now_s: current time as seconds since the epoch first_run_s: time of the first run as seconds since the epoch, calculated based on self.first_run since_first_s: how many seconds have elapsed since the first run run_every_s: how many seconds should elapse between runs of this schedule last_scheduled_run_s: the most recent time at which this schedule should have run based on its schedule, as seconds since the epoch expected_runs: number of runs that should have happened based on the first_run time and the interval :rtype: tuple """ now_s = time.time() first_run_dt = dateutils.to_utc_datetime(dateutils.parse_iso8601_datetime(self.first_run)) first_run_s = calendar.timegm(first_run_dt.utctimetuple()) since_first_s = now_s - first_run_s run_every_s = timedelta_seconds(self.as_schedule_entry().schedule.run_every) # don't want this to be negative expected_runs = max(int(since_first_s / run_every_s), 0) last_scheduled_run_s = first_run_s + expected_runs * run_every_s return now_s, first_run_s, since_first_s, run_every_s, last_scheduled_run_s, expected_runs
def _convert_repo_dates_to_strings(repo): """ Convert the last_unit_added & last_unit_removed fields of a repository This modifies the repository in place :param repo: diatabase representation of a repo :type repo: dict """ # convert the native datetime object to a string with timezone specified last_unit_added = repo.get('last_unit_added') if last_unit_added: new_date = dateutils.to_utc_datetime(last_unit_added, no_tz_equals_local_tz=False) repo['last_unit_added'] = dateutils.format_iso8601_datetime(new_date) last_unit_removed = repo.get('last_unit_removed') if last_unit_removed: new_date = dateutils.to_utc_datetime(last_unit_removed, no_tz_equals_local_tz=False) repo['last_unit_removed'] = dateutils.format_iso8601_datetime(new_date)
def _ensure_tz_specified(time_stamp): """ Check a datetime that came from the database to ensure it has a timezone specified in UTC Mongo doesn't include the TZ info so if no TZ is set this assumes UTC. :param time_stamp: a datetime object to ensure has UTC tzinfo specified :type time_stamp: datetime.datetime :return: The time_stamp with a timezone specified :rtype: datetime.datetime """ if time_stamp: time_stamp = dateutils.to_utc_datetime(time_stamp, no_tz_equals_local_tz=False) return time_stamp
def __init__(self, repo_id, unit_id, unit_type_id, owner_type, owner_id): super(RepoContentUnit, self).__init__() # Mapping Identity Information self.repo_id = repo_id self.unit_id = unit_id self.unit_type_id = unit_type_id # Association Metadata self.owner_type = owner_type self.owner_id = owner_id # store time in UTC created = dateutils.to_utc_datetime(datetime.datetime.utcnow()) self.created = dateutils.format_iso8601_datetime(created) self.updated = self.created
def update_time_to_utc_on_collection(collection_name, field_name): """ Update the iso8601 string representation of time in a field in a collection from time zone specific to UTC native :param collection_name: The name of the collection to update :type collection_name: str :param field_name: The name of the field within the collection that contains the timestamp :type field_name: str """ collection = connection.get_collection(collection_name) for distributor in collection.find({field_name: {'$ne': None}}): time_str = distributor[field_name] time = dateutils.parse_iso8601_datetime(time_str) # only update if we are not UTC to begin with if time.tzinfo != dateutils.utc_tz(): time_utc = dateutils.to_utc_datetime(time) distributor[field_name] = dateutils.format_iso8601_datetime(time_utc) collection.save(distributor)
def update_time_to_utc_on_collection(collection_name, field_name): """ Update the iso8601 string representation of time in a field in a collection from time zone specific to UTC native :param collection_name: The name of the collection to update :type collection_name: str :param field_name: The name of the field within the collection that contains the timestamp :type field_name: str """ collection = connection.get_collection(collection_name) for distributor in collection.find({field_name: {'$ne': None}}): time_str = distributor[field_name] time = dateutils.parse_iso8601_datetime(time_str) # only update if we are not UTC to begin with if time.tzinfo != dateutils.utc_tz(): time_utc = dateutils.to_utc_datetime(time) distributor[field_name] = dateutils.format_iso8601_datetime( time_utc) collection.save(distributor, safe=True)
def test_utc_offset(self): n1 = datetime.datetime.now(dateutils.local_tz()) u1 = dateutils.to_utc_datetime(n1) n2 = n1.replace(tzinfo=None) u2 = u1.replace(tzinfo=None) self.assertTrue(n2 - u2 == dateutils.local_utcoffset_delta())
def test_local_to_utz_tz_conversion(self): n1 = datetime.datetime.now(dateutils.local_tz()) u = dateutils.to_utc_datetime(n1) n2 = dateutils.to_local_datetime(u) self.assertTrue(n1 == n2)
def test_utc_no_tz_to_utz_tz_conversion(self): dt = datetime.datetime.utcnow() new_date = dateutils.to_utc_datetime(dt, no_tz_equals_local_tz=False) self.assertEquals(new_date.tzinfo, dateutils.utc_tz())
def _calculate_times(self): """ Calculates and returns several time-related values that tend to be needed at the same time. :return: tuple of numbers described below... now_s: current time as seconds since the epoch first_run_s: time of the first run as seconds since the epoch, calculated based on self.first_run since_first_s: how many seconds have elapsed since the first run run_every_s: how many seconds should elapse between runs of this schedule last_scheduled_run_s: the most recent time at which this schedule should have run based on its schedule, as seconds since the epoch expected_runs: number of runs that should have happened based on the first_run time and the interval :rtype: tuple """ now_s = time.time() first_run_dt = dateutils.to_utc_datetime(dateutils.parse_iso8601_datetime(self.first_run)) first_run_s = calendar.timegm(first_run_dt.utctimetuple()) since_first_s = now_s - first_run_s # An interval could be an isodate.Duration or a datetime.timedelta interval = self.as_schedule_entry().schedule.run_every if isinstance(interval, isodate.Duration): # Determine how long (in seconds) to wait between the last run and the next one. This # changes depending on the current time because a duration can be a month or a year. if self.last_run_at is not None: last_run_dt = dateutils.to_utc_datetime( dateutils.parse_iso8601_datetime(str(self.last_run_at))) run_every_s = timedelta_seconds(interval.totimedelta(start=last_run_dt)) else: run_every_s = timedelta_seconds(interval.totimedelta(start=first_run_dt)) # This discovers how many runs should have occurred based on the schedule expected_runs = 0 current_run = first_run_dt last_scheduled_run_s = first_run_s duration = self.as_schedule_entry().schedule.run_every while True: # The interval is determined by the date of the previous run current_interval = duration.totimedelta(start=current_run) current_run += current_interval # If time of this run is less than the current time, keep going current_run_s = calendar.timegm(current_run.utctimetuple()) if current_run_s < now_s: expected_runs += 1 last_scheduled_run_s += timedelta_seconds(current_interval) else: break else: run_every_s = timedelta_seconds(interval) # don't want this to be negative expected_runs = max(int(since_first_s / run_every_s), 0) last_scheduled_run_s = first_run_s + expected_runs * run_every_s return now_s, first_run_s, since_first_s, run_every_s, last_scheduled_run_s, expected_runs
def _calculate_times(self): """ Calculates and returns several time-related values that tend to be needed at the same time. :return: tuple of numbers described below... now_s: current time as seconds since the epoch first_run_s: time of the first run as seconds since the epoch, calculated based on self.first_run since_first_s: how many seconds have elapsed since the first run run_every_s: how many seconds should elapse between runs of this schedule last_scheduled_run_s: the most recent time at which this schedule should have run based on its schedule, as seconds since the epoch expected_runs: number of runs that should have happened based on the first_run time and the interval :rtype: tuple """ now_s = time.time() first_run_dt = dateutils.to_utc_datetime( dateutils.parse_iso8601_datetime(self.first_run)) first_run_s = calendar.timegm(first_run_dt.utctimetuple()) since_first_s = now_s - first_run_s # An interval could be an isodate.Duration or a datetime.timedelta interval = self.as_schedule_entry().schedule.run_every if isinstance(interval, isodate.Duration): # Determine how long (in seconds) to wait between the last run and the next one. This # changes depending on the current time because a duration can be a month or a year. if self.last_run_at is not None: last_run_dt = dateutils.to_utc_datetime( dateutils.parse_iso8601_datetime(str(self.last_run_at))) run_every_s = timedelta_seconds( interval.totimedelta(start=last_run_dt)) else: run_every_s = timedelta_seconds( interval.totimedelta(start=first_run_dt)) # This discovers how many runs should have occurred based on the schedule expected_runs = 0 current_run = first_run_dt last_scheduled_run_s = first_run_s duration = self.as_schedule_entry().schedule.run_every while True: # The interval is determined by the date of the previous run current_interval = duration.totimedelta(start=current_run) current_run += current_interval # If time of this run is less than the current time, keep going current_run_s = calendar.timegm(current_run.utctimetuple()) if current_run_s < now_s: expected_runs += 1 last_scheduled_run_s += timedelta_seconds(current_interval) else: break else: run_every_s = timedelta_seconds(interval) # don't want this to be negative expected_runs = max(int(since_first_s / run_every_s), 0) last_scheduled_run_s = first_run_s + expected_runs * run_every_s return now_s, first_run_s, since_first_s, run_every_s, last_scheduled_run_s, expected_runs