def get_today_time_range_in_utc(timezone_as_str, utc_now=utc_now): """ Given a timezone, return the start of day and end of day times in UTC. Why do this? Because if it is now 10:00 pm EST, January 1, 2013, it is 3:00 am UTC, January 2, 2013. In this case, this function will return (datetime(2013, 1, 1, 0, 0, 0), datetime(2013, 1, 2, 0, 0, 0)) """ # Convert to target timezone target_tz = pytz.timezone(timezone_as_str) target_now = target_tz.normalize(utc_now()) # Get the start and end times of the day day_start = datetime.datetime.combine( target_now, datetime.time(0)) day_end = day_start + datetime.timedelta(days=1) # Attach some lovely timezones day_start = target_tz.localize(day_start) day_end = target_tz.localize(day_end) # Convert it back to utc return (utc_tz.normalize(day_start), utc_tz.normalize(day_end))
def convert_central_datetime_to_utc(datetime): if isinstance(datetime, DT): local_dt = central.localize(datetime) return utc.normalize(local_dt) if isinstance(datetime, UnicodeType): local_dt = central.localize(DT.strptime(datetime, datetime_format)) utc_datetime = utc.normalize(local_dt) return utc_datetime.strftime(datetime_format)
def next(self): """ :return: Combined air quality and GPS data as a line of CSV text """ if self._output_header: self._output_header = False return 'utc,filter,pm,lat,lon,device' line = None while line is None: aq = self._aq_data.next() aq_datetime = utc.normalize(self._aq_start_datetime + timedelta( seconds=int(aq['Elapsed Time [s]']))) utc_timestamp = calendar.timegm(aq_datetime.utctimetuple()) mass = aq['Mass [mg/m3]'] errors = aq['Errors'] # TODO(smcclellan): How should this be defined? device = errors or 'A' while self._gps_datetime < aq_datetime: self._gps_last_datetime = self._gps_datetime self._gps_last_lat = self._gps_lat self._gps_last_lon = self._gps_lon gps = self._parse_next_gps() self._gps_datetime = utc.normalize( utc.localize(datetime.combine(gps.datestamp, gps.timestamp))) self._gps_lat = gps.latitude self._gps_lon = gps.longitude aq_gps_tdiff = abs(self._gps_datetime - aq_datetime) aq_gps_last_tdiff = abs(aq_datetime - self._gps_last_datetime) if aq_gps_tdiff <= aq_gps_last_tdiff and aq_gps_tdiff <= self._tolerance: # The air quality timestamp is closer to the current GPS measurement, and within tolerance line = '{utc},{filter},{pm},{lat:.6f},{lon:.6f},{device}'.format( utc=utc_timestamp, filter=self._filter_size, pm=mass, lat=self._gps_lat, lon=self._gps_lon, device=device) elif aq_gps_last_tdiff <= aq_gps_tdiff and aq_gps_last_tdiff <= self._tolerance: # The air quality timestamp is closer to the previous GPS measurement, and within tolerance line = '{utc},{filter},{pm},{lat:.6f},{lon:.6f},{device}'.format( utc=utc_timestamp, filter=self._filter_size, pm=mass, lat=self._gps_last_lat, lon=self._gps_last_lon, device=device) # Otherwise the air quality measurement is not tolerably close to the current or previous GPS # GPS measurement and should be skipped return line
def get_shows(self, channel, fromtime, totime): """ Gets a list of shows in the given period of time. This method returns a Deferred. The callback gets one parameter, the ``ChannelList`` of the period of time. The errback is called on an error with the failure. The first show will be the one **before** (or equal) fromtime and the last one will be the last show **before** (or equal) totime. ``frotime`` and ``totime`` will be handeled correctly if it is not in UTC time. """ def parse_day(shows, fromtime, totime, defer, result, channel): ready = False while len(shows) > 1 and shows[1].time <= fromtime: shows = shows[1:] ready = True # since we had to throw something away, # we are ready and don't need to go further # into the past showlist = ShowList() for show in shows: if show.time <= totime: showlist.append(show) else: break i = 0 for show in showlist: result.insert(i, show) i += 1 if ready: defer.callback(result) else: yesterday = self.get_tele_day( channel, shows[0].time - timedelta(days=1)) yesterday.addCallback(parse_day, fromtime, totime, defer, result, channel) yesterday.addErrback(defer.errback) fromtime = utc.normalize(fromtime.astimezone(utc)) totime = utc.normalize(totime.astimezone(utc)) defer = Deferred() result = ShowList() last_defer = self.get_tele_day(channel, totime) last_defer.addCallback(parse_day, fromtime, totime, defer, result, channel) last_defer.addErrback(defer.errback) return defer
def unix_to_datetime(unix_timestamp, tz=pytz_utc): ''' :param unix_timestamp: Number of seconds since unix epoch (1/1/1970) :type unix_timestamp: float :param tz: timezone to use for conversion (default None = UTC) :type tz: None or tzinfo object (see datetime docs) :returns: datetime object :raises: ValueError if unix_timestamp is not of type float or datetime Returns a datetime object from a unix timestamp. Simple wrapper for :func:`datetime.datetime.fromtimestamp` ''' if isinstance(unix_timestamp, datetime.datetime): if unix_timestamp.tzinfo is None: unix_datetime = pytz_utc.localize(unix_timestamp) elif unix_timestamp.tzinfo == pytz_utc: unix_datetime = unix_timestamp else: unix_datetime = pytz_utc.normalize(unix_timestamp.astimezone(pytz_utc)) elif isinstance(unix_timestamp, float): unix_datetime = pytz_utc.localize(datetime.datetime.fromtimestamp(unix_timestamp)) else: errstr = 'Looking for a timestamp of type datetime.datetime or # of sec past unix epoch.\n' errstr += 'Supplied timestamp \'%s\' of type %s.' % \ (str(unix_timestamp), type(unix_timestamp)) raise ValueError(errstr) return unix_datetime
def process_type_date_time(self, field_data): value = field_data.value if value is not None and value >= 0x10000000: dt = datetime.utcfromtimestamp(631065600 + value) dt = self.tz.localize(dt) field_data.value = utc.normalize(dt) field_data.units = None # Units were 's', set to None
def _to_utc(dt): if not tz_available: return dt if dt.tzinfo is None: dt = dt.replace(tzinfo=tzlocal()) return utc.normalize(dt)
def tz_convert(date, tz): """ Convert date to time zone tz can be; - '-2' (relative to utc) - 'Paris/Europe' real timezone like (cf pytz) """ if tz: system_local_date = local_tz.localize(date) try: # simple utc delta? utc_offset = int(tz) utc_time = system_local_date.astimezone(utc) res = utc.normalize(utc_time + timedelta(hours=utc_offset)) return res except: try: # real timezone timez = timezone(tz) local_date = system_local_date.astimezone(timez) return local_date except UnknownTimeZoneError: # fall back to date return date else: return date
def unix_to_nt(unix_timestamp): ''' Given a date, return the 2-element tuple used for timekeeping with SIMRAD echosounders #converting back may not yield the exact original date, #but will be within the datetime's precision ''' if isinstance(unix_timestamp, datetime.datetime): if unix_timestamp.tzinfo is None: unix_datetime = pytz_utc.localize(unix_timestamp) elif unix_timestamp.tzinfo == pytz_utc: unix_datetime = unix_timestamp else: unix_datetime = pytz_utc.normalize(unix_timestamp.astimezone(pytz_utc)) elif isinstance(unix_timestamp, np.datetime64): ts = (unix_timestamp - np.datetime64('1970-01-01T00:00:00Z')) / np.timedelta64(1, 's') unix_datetime = unix_to_datetime(ts) else: unix_datetime = unix_to_datetime(unix_timestamp) sec_past_nt_epoch = (unix_datetime - UTC_NT_EPOCH).total_seconds() onehundred_ns_intervals = int(sec_past_nt_epoch * 1e7) lowDateTime = onehundred_ns_intervals & 0xFFFFFFFF highDateTime = onehundred_ns_intervals >> 32 return lowDateTime, highDateTime
def normalize_ts(cls, ts): if ts.tzinfo is not None: ts = utc.normalize(ts.astimezone(utc)) return datetime.datetime(year=ts.year, month=ts.month, day=ts.day, hour=ts.hour)
def test_insert_task(self): with self.app.app_context(): tq = apis.TaskQueue('test') tq.add_task({'method': 'GET', 'url': 'http://httpbin.org/get'}, cname='testtask') task_dict = { 'request': {'url': 'http://httpbin.org/get'}, 'cname': 'testtask', 'eta': '10:42' } rv = self.client.post( '/apps/test/taskqueues/default/tasks', data=anyjson.dumps(task_dict)) self.assertEqual(rv.status_code, 409) self.assertEqual(anyjson.loads(rv.data)['error_code'], 207203) task_dict['cname'] = 'testtask1' rv = self.client.post( '/apps/test/taskqueues/default/tasks', data=anyjson.dumps(task_dict)) self.assertEqual(rv.status_code, 201) task = anyjson.loads(rv.data) self.assertEqual(task['id'], 2) self.assertEqual(task['request']['method'], 'GET') self.assertEqual(task['cname'], 'testtask1') now = datetime.now() eta_expect = utc.normalize( get_localzone().localize( datetime(now.year, now.month, now.day, 10, 42) ) ).isoformat() self.assertEqual(task['eta'], eta_expect) self.assertTrue(isinstance(task['countdown'], float))
def utc_localize(dtime): if use_tz: if dtime.tzinfo: return utc.normalize(dtime) else: return utc.localize(dtime) return dtime
def fetch_donates(bot, job, s): last_qiwi = Donate.q.filter( Donate.source == Donate.Source.QIWI, ).order_by(Donate.date.desc()).first() # Все входящие операции за либо последний месяц, либо промежуток # от даты последней транзакции до сейчас start_date = last_qiwi.date - _sec if last_qiwi else datetime.utcnow() - _month now = datetime.utcnow() log.info('querying qiwi') # ! обёртка api форсит часовой пояс UTC+3, а у нас всё в UTC+0, подстраиваемся msk_start = msk.fromutc(start_date) msk_now = msk.fromutc(now) h = w.history( rows=40, operation='IN', start_date=msk_start, end_date=msk_now ) ts = h['transactions'] """:type: list[pyqiwi.types.Transaction]""" changes = False for t in ts[::-1]: log.info(f'checking ts #{t.txn_id}') try: Donate.q.filter(Donate.txn_id == t.txn_id).one() except NoResultFound: phone = str(t.account) try: a = DonateAuthor.q.filter(DonateAuthor.phone == phone).one() except NoResultFound: a = DonateAuthor(phone=phone) s.add(a) s.commit() log.info(f'added new {a!r}') new_donate = Donate( txn_id=t.txn_id, source=Donate.Source.QIWI, date=utc.normalize(t.date).replace(tzinfo=None), # приводим к UTC и удаляем tz amount=Decimal(t.total.amount), currency=Donate.Currency(t.total.currency), author=a ) s.add(new_donate) log.info(f'added fresh {new_donate!r}') changes = True if changes: admins = Chat.q.filter(Chat.is_admin == True, Chat.muted == False).all() for ac in admins: bot.send_message(ac.id, 'Новые донаты! /pending')
def est_2_utc(est): """ Given a time in EST, convert it to UTC """ if est.tzinfo is None: # Attach the EST timezone est = pytz.timezone('US/Eastern').localize(est) return utc_tz.normalize(est)
def tz_2_utc(time, tz): """ Given a time in the tz timezone, convert it to UTC """ if time.tzinfo is None: # Attach the timezone time = pytz.timezone(tz).localize(time) return utc_tz.normalize(time)
def __init__(self, thetime, title, subtitle, genre): #: The time when this show starts. This is a ``datetime.datetime`` in #: UTC. self.time = utc.normalize(thetime.astimezone(utc)) #: The title of this show. self.title = title #: The subtitle of this show. This is usually the name of the episode. self.subtitle = subtitle #: The German genre this show belongs to. self.genre = genre
def _getLunarTime(self, asOf: datetime, doFinalCorrections: bool) -> Dict: utcAsOf = utc.normalize(asOf) utcAsOfTuple = (utcAsOf.year, utcAsOf.month, utcAsOf.day, utcAsOf.hour, utcAsOf.minute, utcAsOf.second) moon_info = MoonInfo(self._latitude_dms, self._longitude_dms) moon_info.update(utcAsOfTuple) moon_times = moon_info.rise_set_times(self._timezone_str) return self._getLunarTimeFromMoonTimes(moon_times, asOf, moon_info.fractional_phase(), doFinalCorrections)
def test_next_year(self): date = utc.normalize( datetime(year=2016, month=1, day=1, hour=0, minute=0, tzinfo=utc)) other = icalevents.icalparser.next_year_at(date, count=2) self.assertEqual(date.year + 2, other.year, "year is changed") self.assertEqual(date.month, other.month, "month is same") self.assertEqual(date.day, other.day, "day is same") self.assertEqual(date.hour, other.hour, "hour is same") self.assertEqual(date.minute, other.minute, "minute is same") self.assertEqual(date.tzinfo, other.tzinfo, "timezone is same")
def test_next_month(self): dt = utc.normalize( datetime(year=2016, month=10, day=1, hour=0, minute=0, tzinfo=utc)) other = icalevents.icalparser.next_month_at(dt, count=5) self.assertEqual(2017, other.year, "year is same") self.assertEqual(3, other.month, "month is changed") self.assertEqual(dt.day, other.day, "day is same") self.assertEqual(dt.hour, other.hour, "hour is same") self.assertEqual(dt.minute, other.minute, "minute is same") self.assertEqual(dt.tzinfo, other.tzinfo, "timezone is same")
def gen_events( start: int, stop: int, start_time: Union[datetime.datetime, datetime.date], no_time: bool = False) -> List[Dict[str, Union[str, Dict[str, str]]]]: if no_time: start_time = datetime.date(start_time.year, start_time.month, start_time.day) duration: datetime.timedelta = datetime.date(1, 1, 2) - datetime.date( 1, 1, 1) date_key: str = "date" date_end: str = '' else: start_time = utc.normalize( start_time.astimezone(utc)).replace(tzinfo=None) duration: datetime.timedelta = datetime.datetime( 1, 1, 1, 2) - datetime.datetime(1, 1, 1, 1) date_key: str = "dateTime" date_end: str = 'Z' result: List[Dict[str, Union[str, Dict[str, str]]]] = [] for i in range(start, stop): event_start = start_time + (duration * i) event_end = event_start + duration updated: Union[datetime.datetime, datetime.date] = event_start if no_time: updated = datetime.datetime(updated.year, updated.month, updated.day, 0, 0, 0, 1, tzinfo=utc) event: Dict[str, Union[str, Dict[str, str]]] = { 'summary': 'test event __ {}'.format(i), 'location': 'la la la {}'.format(i), 'description': 'test TEST -- test event {}'.format(i), "iCalUID": "{}@test.com".format(sha1("test - event {}".format(i))), "updated": updated.isoformat() + 'Z', "created": updated.isoformat() + 'Z', 'start': { date_key: event_start.isoformat() + date_end }, 'end': { date_key: event_end.isoformat() + date_end } } result.append(event) return result
def to_utc(dt): """ Helper function to return UTC-based datetime objects. If the input datetime object has any timezone information, it is converted to UTC. Otherwise, the datetime is taken as-is and only the timezone information UTC is added. """ if dt.tzinfo is None: logging.warning( "You supplied a naive date/time object. Timezone cannot be guessed and is assumed to be UTC. If your date/time is NOT UTC, you will get wrong results!") return utc.localize(dt) else: return utc.normalize(dt)
def test_event_copy_to(self): new_start = utc.normalize( datetime(year=2017, month=2, day=5, hour=12, minute=5, tzinfo=utc)) eventC = self.eventA.copy_to(new_start) self.assertNotEqual(eventC.uid, self.eventA.uid, "new event has new UID") self.assertEqual(eventC.start, new_start, "new event has new start") self.assertEqual(eventC.end - eventC.start, self.eventA.end - self.eventA.start, "new event has same duration") self.assertEqual(eventC.all_day, False, "new event is no all day event") self.assertEqual(eventC.summary, self.eventA.summary, "copy to: summary")
def format_datetime_utc(value): """utc datetime as string from date or datetime value Arguments: value -- date or datetime value Returns: utc datetime value as string in iso format """ if not isinstance(value, datetime.datetime): value = datetime.datetime(value.year, value.month, value.day, tzinfo=utc) value = value.replace(microsecond=1) return utc.normalize( value.astimezone(utc)).replace(tzinfo=None).isoformat() + 'Z'
def get_at(self, thetime): """ Returns the show running at the given time. If time is smaller than the first show's time a KeyError is raised. ``thetime`` is automatically converted into UTC time and normalized. """ thetime = utc.normalize(thetime.astimezone(utc)) shows = sorted(self, lambda a, b: cmp(a.time, b.time)) if thetime < shows[0].time: raise KeyError("%s is before the first show" % thetime) lastshow = shows[0] for show in shows: if show.time > thetime: return lastshow lastshow = show return lastshow
def __call__(self, value): # Datetime fields may contain timezone naive or timezone aware # objects. Unfortunately the zope.schema.Datetime field does not # contain any information if the field value should be timezone naive # or timezone aware. While some fields (start, end) store timezone # aware objects others (effective, expires) store timezone naive # objects. # We try to guess the correct deserialization from the current field # value. if value is None: self.field.validate(value) return # get tz from already stored value dm = queryMultiAdapter((self.context, self.field), IDataManager) current = dm.get() if current is not None: tzinfo = current.tzinfo else: # this is the patch tzinfo = pytz.timezone(default_timezone()) # Parse ISO 8601 string with dateutil try: dt = dateutil.parser.parse(value) except ValueError: raise ValueError(u"Invalid date: {}".format(value)) # Convert to TZ aware in UTC if dt.tzinfo is not None: dt = dt.astimezone(utc) else: dt = utc.localize(dt) # Convert to local TZ aware or naive UTC if tzinfo is not None: tz = timezone(tzinfo.zone) value = tz.normalize(dt.astimezone(tz)) else: value = utc.normalize(dt.astimezone(utc)).replace(tzinfo=None) self.field.validate(value) return value
def unix_to_datetime(unix_timestamp): """ :param unix_timestamp: Number of seconds since unix epoch (1/1/1970) :type unix_timestamp: float :param tz: timezone to use for conversion (default None = UTC) :type tz: None or tzinfo object (see datetime docs) :returns: datetime object :raises: ValueError if unix_timestamp is not of type float or datetime Returns a datetime object from a unix timestamp. Simple wrapper for :func:`datetime.datetime.fromtimestamp` >>> from pytz import utc >>> from datetime import datetime >>> epoch = unix_to_datetime(0.0, tz=utc) >>> assert epoch == datetime(1970, 1, 1, tzinfo=utc) """ if isinstance(unix_timestamp, datetime.datetime): if unix_timestamp.tzinfo is None: unix_datetime = pytz_utc.localize(unix_timestamp) elif unix_timestamp.tzinfo == pytz_utc: unix_datetime = unix_timestamp else: unix_datetime = pytz_utc.normalize( unix_timestamp.astimezone(pytz_utc)) elif isinstance(unix_timestamp, float): unix_datetime = pytz_utc.localize( datetime.datetime.fromtimestamp(unix_timestamp)) else: errstr = "Looking for a timestamp of type datetime.datetime or # of sec past unix epoch.\n" errstr += "Supplied timestamp '%s' of type %s." % ( str(unix_timestamp), type(unix_timestamp), ) raise ValueError(errstr) return unix_datetime
def gen_events(start, stop, start_time, no_time=False): if no_time: start_time = datetime.date(start_time.year, start_time.month, start_time.day) duration = datetime.date(1, 1, 2) - datetime.date(1, 1, 1) date_key = "date" suff = '' else: start_time = utc.normalize( start_time.astimezone(utc)).replace(tzinfo=None) duration = datetime.datetime(1, 1, 1, 2) - datetime.datetime( 1, 1, 1, 1) date_key = "dateTime" suff = 'Z' result = [] for i in range(start, stop): event_start = start_time + (duration * i) event_end = event_start + duration updated = event_start if no_time: updated = datetime.datetime(updated.year, updated.month, updated.day, 0, 0, 0, 1, tzinfo=utc) event = { 'summary': 'test event __ {}'.format(i), 'location': 'la la la {}'.format(i), 'description': 'test TEST -- test event {}'.format(i), "iCalUID": "{}@test.com".format(sha1("test - event {}".format(i))), "updated": updated.isoformat() + 'Z', "created": updated.isoformat() + 'Z' } event['start'] = {date_key: event_start.isoformat() + suff} event['end'] = {date_key: event_end.isoformat() + suff} result.append(event) return result
def unix_to_nt(unix_timestamp): ''' Given a date, return the 2-element tuple used for timekeeping with SIMRAD echosounders #Simple conversion >>> dt = datetime.datetime(2011, 12, 23, 20, 54, 3, 964000, pytz_utc) >>> assert (19496896L, 30196149L) == unix_to_nt(dt) #Converting back and forth between the two standards: >>> orig_dt = datetime.datetime.now(tz=pytz_utc) >>> nt_tuple = unix_to_nt(orig_dt) #converting back may not yield the exact original date, #but will be within the datetime's precision >>> back_to_dt = nt_to_unix(nt_tuple) >>> d_mu_seconds = abs(orig_dt - back_to_dt).microseconds >>> mu_sec_resolution = orig_dt.resolution.microseconds >>> assert d_mu_seconds <= mu_sec_resolution ''' if isinstance(unix_timestamp, datetime.datetime): if unix_timestamp.tzinfo is None: unix_datetime = pytz_utc.localize(unix_timestamp) elif unix_timestamp.tzinfo == pytz_utc: unix_datetime = unix_timestamp else: unix_datetime = pytz_utc.normalize( unix_timestamp.astimezone(pytz_utc)) else: unix_datetime = unix_to_datetime(unix_timestamp) sec_past_nt_epoch = (unix_datetime - UTC_NT_EPOCH).total_seconds() onehundred_ns_intervals = int(sec_past_nt_epoch * 1e7) lowDateTime = onehundred_ns_intervals & 0xFFFFFFFF highDateTime = onehundred_ns_intervals >> 32 return lowDateTime, highDateTime
def __call__(self, value): # Datetime fields may contain timezone naive or timezone aware # objects. Unfortunately the zope.schema.Datetime field does not # contain any information if the field value should be timezone naive # or timezone aware. While some fields (start, end) store timezone # aware objects others (effective, expires) store timezone naive # objects. # We try to guess the correct deserialization from the current field # value. dm = queryMultiAdapter((self.context, self.field), IDataManager) current = dm.get() if current is not None: tzinfo = current.tzinfo else: tzinfo = None # This happens when a 'null' is posted for a non-required field. if value is None: self.field.validate(value) return # Parse ISO 8601 string with Zope's DateTime module try: dt = DateTime(value).asdatetime() except (SyntaxError, DateTimeError) as e: raise ValueError(e.message) # Convert to TZ aware in UTC if dt.tzinfo is not None: dt = dt.astimezone(utc) else: dt = utc.localize(dt) # Convert to local TZ aware or naive UTC if tzinfo is not None: tz = timezone(tzinfo.zone) value = tz.normalize(dt.astimezone(tz)) else: value = utc.normalize(dt.astimezone(utc)).replace(tzinfo=None) self.field.validate(value) return value
def status(self): from pytz import timezone, utc unix = datetime(1970, 1, 1, tzinfo=utc) tz = timezone("Europe/Moscow") now = datetime.now() starts_at_utc = utc.normalize(tz.localize(self.tutorial.starts_at)) td = starts_at_utc - unix self.starts_at_utc = int( (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6 * 1000) if self.tutorial.starts_at > now: return 'early' elif self.tutorial.starts_at <= now and ( now - self.tutorial.starts_at).seconds < 15 * 60: return 'in_time' elif self.tutorial.youtube_video_url: return 'recorded' else: return 'late'
def list_events_from(self, start: datetime) -> EventList: """ list events from calendar, where start date >= start """ fields = 'nextPageToken,items(id,iCalUID,updated)' events = [] page_token = None timeMin = utc.normalize(start.astimezone(utc)).replace( tzinfo=None).isoformat() + 'Z' while True: response = self.service.events().list(calendarId=self.calendarId, pageToken=page_token, singleEvents=True, timeMin=timeMin, fields=fields).execute() if 'items' in response: events.extend(response['items']) page_token = response.get('nextPageToken') if not page_token: break self.logger.info('%d events listed', len(events)) return events
def process_type_local_date_time(self, field_data): if field_data.value is not None: dt = datetime.fromtimestamp(631065600 + field_data.value) field_data.value = utc.normalize(dt.replace(tzinfo=utc)) field_data.units = None
def to_utc(dt): if dt.tzinfo is None: dt = dt.replace(tzinfo=tzlocal()) return utc.normalize(dt)
def to_utc(dt): try: return utc.normalize(dt) if dt.tzinfo else utc.localize(dt) except Exception as e: raise Exception(f'Failed to convert {dt!r} to UTC: {e!r}')
def normalize_ts(cls, ts): if ts.tzinfo is not None: ts = utc.normalize(ts.astimezone(utc)) return ts
def normalize_ts(cls, ts): if ts.tzinfo is not None: ts = utc.normalize(ts.astimezone(utc)) return datetime.datetime( year=ts.year, month=ts.month, day=ts.day, hour=ts.hour )
def _format_time(timestamp): return utc.normalize(timestamp).isoformat()
def query_moves(token): print('Querying Moves...') table_places = db[PLACES_TABLE] table_categories = db[CATEGORIES_TABLE] days = moves_get('/user/places/daily?pastDays=31', token) recentDays = sorted(days, key=lambda item: item['date'], reverse=True) all_segments = [] segment_start_times = set() segment_categories = {} for day in recentDays: # Sometimes day['segments'] is null. Make sure we catch that. # I'm surprised Moves API returns days without segments. if not day['segments']: continue for segment in day['segments']: # Parse then rewrite times as UTC to ensure they're consistent for prop in ['startTime', 'lastUpdate', 'endTime']: dirty_dt = parse(segment[prop]) clean_dt = utc.normalize(dirty_dt.astimezone(utc)) segment[prop] = clean_dt.isoformat() segment = flatten(segment) # Dedupe: some segments appear in multiple days if segment['startTime'] in segment_start_times: continue # Move foursquareCategoryIds lists outside of place data # into segment_categories: lists of categories indexed by # segment startTimes categories = [] if FSQ_PROP in segment: categories = segment[FSQ_PROP] if categories: segment_categories[segment['startTime']] = categories del segment[FSQ_PROP] segment_start_times.add(segment['startTime']) all_segments.append(segment) num_segments = len(all_segments) recent_segments = sorted(all_segments, key=lambda seg: parse(seg['startTime']), reverse=True) segments_added = 0 segments_updated = 0 for segment in recent_segments: existing = table_places.find_one(startTime=segment['startTime']) needs_categories = False if existing: existing_updated = parse(existing['lastUpdate']) segment_updated = parse(segment['lastUpdate']) if segment_updated > existing_updated: # Segment has been updated since last DB commit. # Replace its data with fresh data. segments_updated += 1 place_row = existing['id'] segment['id'] = place_row table_places.update(segment, ['id']) # Update all categories by deleting and recreating all # category data for that row. table_categories.delete(place_id=place_row) places_row = place_row needs_categories = True else: segments_added += 1 places_row = table_places.insert(segment) needs_categories = True # Insert category data into the place categories table if update is # necessary and category data is present. if needs_categories and segment['startTime'] in segment_categories: categories = segment_categories[segment['startTime']] for category in categories: table_categories.insert({'place_id': places_row, 'category': category}) print('Done! Added %s and updated %s segments (out of %s total).' % (segments_added, segments_updated, num_segments))
def parsedt(dt, tzs): # In [271]: lp = pytz.timezone('US/Eastern').localize(p) # In [272]: pytz.utc.normalize(lp) # Out[272]: datetime.datetime(2011, 7, 17, 8, 53, tzinfo=<UTC>) lp = timezone(tzs).localize(dt) return utc.normalize(lp)
def process_type_local_date_time(self, field_data): if field_data.value is not None: dt = datetime.fromtimestamp(631065600 + field_data.value) dt = self.tz.localize(dt) field_data.value = utc.normalize(dt) field_data.units = None # Units were 's', set to None