async def query_hist_data( engine: object, sectype: str, symbol: str, datatype: str, barsize: str, start: datetime=None, end: datetime=None) -> MarketDataBlock: """Query database on conditions. """ if start is None: start = pytz.UTC.localize(datetime(1, 1, 1)) if end is None: end = pytz.UTC.localize(datetime(9999, 12, 31, 23, 59, 59)) table = _gen_sa_table(sectype) stmt = table.select().where( and_( table.c.Symbol == symbol, table.c.DataType == datatype, table.c.BarSize == barsize, table.c.TickerTime.between( start.astimezone(pytz.UTC), end.astimezone(pytz.UTC)) ) ) async with engine.acquire() as conn: result = await conn.execute(stmt) df = pd.DataFrame(list(result), columns=table.columns.keys()) blk = MarketDataBlock(df, tz='UTC') blk.tz_convert(start.tzinfo) return blk
def get_tickets(self, datetime_since: datetime.datetime, statuses: list=None) -> dict: """ Retrieve tickets :param datetime_since: Only retrieve tickets created after this :param statuses: filter the tickets by its statuses: `TicketStatus` :return: Tickets """ payload = self._credentials_payload.copy() payload['p_tickets_list'] = 1 payload['p_created_after'] = datetime_since.astimezone(self._timezone).timestamp() if statuses is not None: logger.warning('Ignoring status filter (BUG in livezilla API?). Caller should filter by status after getting the result.') #payload['p_status'] = ','.join([str(s.value) for s in statuses]) res = self.http_client.post(self._api_url, data=payload) logger.debug(res.request.url) logger.debug(res.request.body) if not res.status_code == requests.codes.ok: raise APIError(res.text) logger.debug(res.text) j = json.loads(res.text) return j['Tickets']
def get_with_timezone( datetime_object: datetime.datetime, to_timezone: str='', default_from_timezone: str='UTC', ) -> datetime.datetime: """ Change timezone of a date :param datetime_object: datetime to update :param to_timezone: timezone name, if equal to '', try to grap current user timezone. If no given timezone name and no current user timezone, return original date time :param default_from_timezone: datetime original timezone if datetime object is naive :return: datetime updated """ # If no to_timezone, try to grab from current user if not to_timezone and tmpl_context.current_user: to_timezone = tmpl_context.current_user.timezone # If no to_timezone, return original datetime if not to_timezone: return datetime_object # If datetime_object have not timezone, set new from default_from_timezone if not datetime_object.tzinfo: from_tzinfo = pytz.timezone(default_from_timezone) datetime_object = from_tzinfo.localize(datetime_object) new_tzinfo = pytz.timezone(to_timezone) return datetime_object.astimezone(new_tzinfo)
def as_local(dattim: dt.datetime) -> dt.datetime: """Convert a UTC datetime object to local time zone.""" if dattim.tzinfo == DEFAULT_TIME_ZONE: return dattim if dattim.tzinfo is None: dattim = UTC.localize(dattim) return dattim.astimezone(DEFAULT_TIME_ZONE)
def _create_order(event: Event, email: str, positions: List[CartPosition], now_dt: datetime, payment_provider: BasePaymentProvider, locale: str=None, address: int=None, meta_info: dict=None): from datetime import date, time total = sum([c.price for c in positions]) payment_fee = payment_provider.calculate_fee(total) total += payment_fee tz = pytz.timezone(event.settings.timezone) exp_by_date = now_dt.astimezone(tz) + timedelta(days=event.settings.get('payment_term_days', as_type=int)) exp_by_date = exp_by_date.replace(hour=23, minute=59, second=59, microsecond=0) if event.settings.get('payment_term_weekdays'): if exp_by_date.weekday() == 5: exp_by_date += timedelta(days=2) elif exp_by_date.weekday() == 6: exp_by_date += timedelta(days=1) expires = exp_by_date if event.settings.get('payment_term_last'): last_date = make_aware(datetime.combine( event.settings.get('payment_term_last', as_type=date), time(hour=23, minute=59, second=59) ), tz) if last_date < expires: expires = last_date order = Order.objects.create( status=Order.STATUS_PENDING, event=event, email=email, datetime=now_dt, expires=expires, locale=locale, total=total, payment_fee=payment_fee, payment_provider=payment_provider.identifier, meta_info=json.dumps(meta_info or {}), ) OrderPosition.transform_cart_positions(positions, order) if address is not None: try: addr = InvoiceAddress.objects.get( pk=address ) if addr.order is not None: addr.pk = None addr.order = order addr.save() except InvoiceAddress.DoesNotExist: pass order.log_action('pretix.event.order.placed') order_placed.send(event, order=order) return order
def get_datetime_string(dt: datetime = None, with_timezone: bool = True) -> typing.Optional[str]: if not dt: dt = datetime.now() if with_timezone: dt = dt.astimezone() s = dt.isoformat() return s
def localise_to_utc(timestamp: datetime) -> datetime: """ Localise the given timestamp to UTC. :param timestamp: the timestamp to localise :return: the timestamp localised to UTC """ if timestamp.tzinfo is None: return pytz.utc.localize(timestamp) else: return timestamp.astimezone(pytz.utc)
def as_utc(dattim: dt.datetime) -> dt.datetime: """Return a datetime as UTC time. Assumes datetime without tzinfo to be in the DEFAULT_TIME_ZONE. """ if dattim.tzinfo == UTC: return dattim if dattim.tzinfo is None: dattim = DEFAULT_TIME_ZONE.localize(dattim) # type: ignore return dattim.astimezone(UTC)
def datetime_utc_isoformat(timestamp: datetime.datetime, *, naive_utc: bool = False) -> str: """ Returns a timestamp ISO string in implicit UTC. :param timestamp: The timestamp to get the ISO string for. :param naive_utc: Whether to interpret naive timestamps as UTC. By default naive timestamps are assumed to be in local time. """ naive_utc_timestamp: datetime.datetime = ( timestamp if timestamp.tzinfo is None and naive_utc else timestamp.astimezone(datetime.timezone.utc).replace(tzinfo=None)) return naive_utc_timestamp.isoformat(timespec="microseconds")
def localize_timezone(dt: datetime, tz: Union[str, BaseTzInfo] = None) -> datetime: """ Convert a datetime into the specified timezone, defaulting to user's timezone. Naive datetimes are assumed to be in UTC. """ if not dt.tzinfo: dt = utc.localize(dt) if not tz: tz = get_timezone() if isinstance(tz, str): tz = timezone(tz) return dt.astimezone(tz)
def between_dates_predicate(start_date: datetime, end_date: datetime) \ -> Callable[[datetime], bool]: """Returns a function that tests if a date is between two dates. Dates are converted to local timezone """ if start_date > end_date: raise ValueError('start_date is later than end_date.') local_start: datetime = start_date.astimezone() local_end: datetime = end_date.astimezone() def _between_local_dates(given_date: Union[str, datetime]) -> bool: if isinstance(given_date, str): given_date = datetime.strptime(given_date, HK_APPLE_DATETIME_FORMAT) elif not isinstance(given_date, datetime): raise TypeError( "date's type must be a str or datetime.datetime object.") return local_start <= given_date.astimezone() <= local_end return _between_local_dates
def pull_all_from_table_or_query( config: RepoConfig, data_source: DataSource, join_key_columns: List[str], feature_name_columns: List[str], event_timestamp_column: str, start_date: datetime, end_date: datetime, ) -> RetrievalJob: """ Note that join_key_columns, feature_name_columns, event_timestamp_column, and created_timestamp_column have all already been mapped to column names of the source table and those column names are the values passed into this function. """ assert isinstance(data_source, SparkSource) warnings.warn( "The spark offline store is an experimental feature in alpha development. " "This API is unstable and it could and most probably will be changed in the future.", RuntimeWarning, ) spark_session = get_spark_session_or_start_new_with_repoconfig( store_config=config.offline_store) fields = ", ".join(join_key_columns + feature_name_columns + [event_timestamp_column]) from_expression = data_source.get_table_query_string() start_date = start_date.astimezone(tz=utc) end_date = end_date.astimezone(tz=utc) query = f""" SELECT {fields} FROM {from_expression} WHERE {event_timestamp_column} BETWEEN TIMESTAMP '{start_date}' AND TIMESTAMP '{end_date}' """ return SparkRetrievalJob(spark_session=spark_session, query=query, full_feature_names=False)
def current_week(self, date: datetime.datetime = None) -> shield.Week: op = Operation(shield.Viewer) if date is None: week: shield.Week = op.viewer.league.current.week() else: date = date.astimezone(pendulum.UTC) week: shield.Week = op.viewer.league.current(date=date).week() week.season_value() week.season_type() week.week_order() week.week_type() week.week_value() return self.query(op).viewer.league.current.week
def make_request(self, start_time: datetime, hours_ahead: int, current_alt, current_long, current_lat): params = { "launch_latitude": current_lat, "launch_longitude": current_long % 360, # convert from [-180,180] to [0,360] "launch_altitude": current_alt - 1, "launch_datetime": start_time.astimezone().isoformat() + "Z", "ascent_rate": 0.8, "float_altitude": current_alt, "stop_datetime": (start_time + timedelta(hours=hours_ahead)).astimezone().isoformat(), "profile": "float_profile" } return requests.get(BASE_URL, params=params)
def adjust(cls, time: datetime.datetime, latlng: s2sphere.LatLng) -> datetime.datetime: # If a timezone is set, there's nothing to do. if time.utcoffset(): return time assert cls._timezonefinder tz_name = cls._timezonefinder.timezone_at(lat=latlng.lat().degrees, lng=latlng.lng().degrees) if tz_name is None: return time tz = pytz.timezone(tz_name) tz_time = time.astimezone(tz) return tz_time
def robust_datetime_serialization(input_dt: datetime.datetime) -> str: """Return a nicely formatted string for time as OSCAL likes it.""" # fail if the input datetime is not aware - ie it has no associated timezone if input_dt.tzinfo is None: raise Exception('Missing timezone in datetime') if input_dt.tzinfo.utcoffset(input_dt) is None: raise Exception('Missing utcoffset in datetime') # use this leave in original timezone rather than utc # return input_dt.astimezone().isoformat(timespec='milliseconds') noqa: E800 # force it to be utc return input_dt.astimezone(datetime.timezone.utc).isoformat(timespec='milliseconds')
def make_native(value: datetime, timezone: Optional[str] = None) -> datetime: """ Make an aware datetime.datetime naive in a given time zone. :raises ValueError: when value is naive datetime """ if timezone is None: tz = get_default_timezone() else: tz = pytz.timezone(timezone) if is_naive(value): raise ValueError("make_naive() cannot be applied to a naive datetime") return value.astimezone(tz).replace(tzinfo=None)
def _get_next_sleep_time(self, now: datetime.datetime = MISSING ) -> datetime.datetime: if self._sleep is not MISSING: return self._last_iteration + datetime.timedelta( seconds=self._sleep) if now is MISSING: now = datetime.datetime.now(datetime.timezone.utc) index = self._start_time_relative_to(now) if index is None: time = self._time[0] tomorrow = now.astimezone(time.tzinfo) + datetime.timedelta(days=1) date = tomorrow.date() else: time = self._time[index] date = now.astimezone(time.tzinfo).date() dt = datetime.datetime.combine(date, time, tzinfo=time.tzinfo) return resolve_datetime(dt)
async def get_bitpanda_withdrawals( self, from_timestamp: datetime.datetime = None, to_timestamp: datetime.datetime = None, currency: str = None, max_page_size: int = None, cursor: int = None) -> dict: params = self._clean_request_params({ 'currency_code': currency, 'max_page_size': max_page_size, 'cursor': cursor }) if from_timestamp is not None: params['from'] = from_timestamp.astimezone(pytz.utc).isoformat() if to_timestamp is not None: params['to'] = to_timestamp.astimezone(pytz.utc).isoformat() return await self._create_get("account/withdrawals/bitpanda", params=params, signed=True)
def save_fetched_visa_status( cls, visa_type: VisaType, embassy_code: EmbassyCode, write_time: datetime, available_date: Optional[datetime], ) -> None: """ The method called when a new fetched result is obtained from crawler backend. The `'latest_written'` collection will always be modified, whereas the `'available_dates'` collection will only be modified when available date is not None """ embassy = USEmbassy.get_embassy_by_code(embassy_code) write_time_utc = write_time.astimezone(tz=None).astimezone(tz=timezone.utc) write_date_utc = write_time_utc.replace(hour=0, minute=0, second=0, microsecond=0) write_date_emb = write_time_utc.astimezone(embassy.timezone)\ .replace(hour=0, minute=0, second=0, microsecond=0, tzinfo=None) query = {'visa_type': visa_type, 'embassy_code': embassy_code} visa_status_query = {**query, 'write_date': write_date_utc} overview_query = {**query, 'overview.write_date': write_date_emb} new_fetch = {'write_time': write_time_utc, 'available_date': available_date} # udpate document if exists, otherwise insert a new document cls.latest_written.update_one(query, {'$set': new_fetch}, upsert=True) if available_date is not None: cls.visa_status.update_one(visa_status_query, {'$push': {'available_dates': new_fetch}}, upsert=True) if cls.overview.find_one(overview_query) is None: # $(update) of array can't work with upsert cls.overview.update_one( query, { '$push': { 'overview': { 'write_date': write_date_emb, 'earliest_date': available_date, 'latest_date': available_date } } }, upsert=True ) else: cls.overview.update_one( overview_query, { '$min': {'overview.$.earliest_date': available_date}, '$max': {'overview.$.latest_date': available_date}, } )
def __init__(self, root_order_id: int, order_id: int, symbol: Symbol, side: SalesSide, order_type: OrderType, execution_type: ExecutionType, settle_type: SettleType, size: Decimal, executed_size: Decimal, price: Decimal, losscut_price: Decimal, status: OrderStatus, time_in_force: TimeInForce, timestamp: datetime) -> None: """ コンストラクタです。 Args: root_order_id: 親注文ID order_id: 注文ID symbol: 銘柄名: BTC ETH BCH LTC XRP BTC_JPY ETH_JPY BCH_JPY LTC_JPY XRP_JPY side: 売買区分: BUY SELL order_type: 取引区分: NORMAL LOSSCUT execution_type: 注文タイプ: MARKET LIMIT STOP settle_type: 決済区分: OPEN CLOSE size: 発注数量 executed_size: 約定数量 price: 注文価格 (MARKET注文の場合は"0") losscut_price: ロスカットレート (現物取引や未設定の場合は"0") status: 注文ステータス: WAITING ORDERED MODIFYING CANCELLING CANCELED EXECUTED EXPIRED ※逆指値注文の場合はWAITINGが有効 time_in_force: 執行数量条件: FAK FAS FOK (Post-onlyの場合はSOK) timestamp: 注文日時 """ self.root_order_id = root_order_id self.order_id = order_id self.symbol = symbol self.side = side self.order_type = order_type self.execution_type = execution_type self.settle_type = settle_type self.size = size self.executed_size = executed_size self.price = price self.losscut_price = losscut_price self.status = status self.time_in_force = time_in_force self.timestamp = timestamp.astimezone(timezone('Asia/Tokyo'))
def read_tag_values(self, tag_id: int, start_local: datetime, end_local: datetime) -> List[DataDouble]: """ Выполняет чтение значений тега за указанный период времени :param tag_id: идентификатор тега :param start_local: начальное время чтения (локальное) :param end_local: конечное время чтения (локальное) :return: массив значений тега """ utc_start = start_local.astimezone(pytz.UTC).replace(tzinfo=None) utc_end = end_local.astimezone(pytz.UTC).replace(tzinfo=None) ret_val: List[DataDouble] = [] d = Table('DataDouble') q = (self._query.from_(d).where( (d.IdTagDef == Parameter('%s')) & (d.TimeWrite[ToTicks(self._schema, Parameter('%s') ):ToTicks(self._schema, Parameter('%s'))])). orderby(d.TimeWrite, order=Order.asc).select( d.IdTagDef, d.Data, ToDateTime2(self._schema, d.TimeWrite, alias='TimeWrite'), d.QSlim)) sql = q.get_sql() self._logger.debug( f'SQL: {sql} PARAMS: tag_id:{tag_id}, utc_start={utc_start}, utc_end={utc_end}' ) try: result = self._engine_data.execute(sql, tag_id, utc_start, utc_end) for row in result: data = DataDouble( tag_id, row['Data'], datetime.strptime( row['TimeWrite'][:23], self.DATETIME_FORMAT_F).replace( tzinfo=pytz.UTC).astimezone(settings.TIME_ZONE), row['QSlim']) ret_val.append(data) except Exception as e: self._logger.error(e) return ret_val
def insert_ephemeral(self, rid: str, pid: str, dt: datetime) -> int: dt_then = dt.astimezone(tz=MTN_TZ) dt_now = datetime.now(tz=MTN_TZ) days = (dt_now - dt_then).days e = Ephemeral(rid=rid, pid=pid, date_ephemeral=dt, days_ephemeral=days) try: self.session.add(e) self.session.commit() pk = e.id except IntegrityError as ex: logger.error(ex) self.session.rollback() raise ex return pk
def build_request_signature(request_id: str, timestamp: datetime, signature_key: str, hash_list: List[str] = None) -> str: formatted_time = timestamp.astimezone( tz=timezone.utc).strftime('%Y%m%d%H%M%S') signature = f'{request_id}{formatted_time}{signature_key}' if hash_list is not None and len(hash_list) > 0: signature += ''.join(hash_list) ut8_encoded = signature.encode('UTF-8', 'strict') result = sha3_512(ut8_encoded).hexdigest() return result.upper()
def get_time_str_from_utc(utc_time: datetime.datetime): """ :param utc_time: datetime object :return: string formatted timestamp """ if not utc_time.tzinfo: logger.warning( 'parameter "utc_time" does not have a timezone defined so UTC time will be assumed' ) else: if utc_time.utcoffset() != TIME_ZERO: logger.debug('parameter "utc_time" being converted to UTC time') utc_time = utc_time.astimezone(pytz.utc) return utc_time.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z"
def time_difference(cls, datetime: dt.datetime, *, naive=True, date=True, time=True, days_difference=True, name_month=True) -> str: local_datetime = datetime.replace(tzinfo=dt.timezone.utc).astimezone( ) if naive else datetime.astimezone() timedelta = dt.datetime.now().astimezone() - local_datetime time_difference_elements = [] if date: if name_month: time_difference_elements.append( local_datetime.strftime('%-d %B %Y')) else: time_difference_elements.append( local_datetime.strftime('%-d.%m.%Y')) if time: if date: time_difference_elements.append( local_datetime.strftime(' o %H:%M')) else: time_difference_elements.append( local_datetime.strftime('%H:%M')) if days_difference: days_difference_number = timedelta.days if days_difference_number == -2: days_difference_string = 'pojutrze' elif days_difference_number == -1: days_difference_string = 'jutro' elif days_difference_number == 0: days_difference_string = 'dzisiaj' elif days_difference_number == 1: days_difference_string = 'wczoraj' elif days_difference_number == 2: days_difference_string = 'przedwczoraj' elif days_difference_number > 0: days_difference_string = f'{cls.word_number_variant(days_difference_number, "dzień", "dni")} temu' else: days_difference_string = f'za {cls.word_number_variant(-days_difference_number, "dzień", "dni")}' if date or time: time_difference_elements.append(f', {days_difference_string}') else: time_difference_elements.append(days_difference_string) return ''.join(time_difference_elements)
def transform_datetime_parameter_timezone( self: ProfileInterface, date_time: datetime.datetime) -> datetime.datetime: """ Transfers datetime parameters incoming by the user to the profile timezone :param date_time: datetime parameter incoming by user. Can be timezone aware or unaware :return: Timezone aware datetime object in profile timezone """ if date_time.tzinfo is not None and date_time.tzinfo.utcoffset( date_time) is not None: return date_time.astimezone(self.timezone) else: return self.timezone.localize(date_time)
def utc_as_timezone(dt: datetime, naive: bool = False, reverse: bool = False) -> datetime: """Converts a random utc datetime into a correct local timezone aware datetime""" ts = dt.timestamp() localtm = time.localtime(ts) delta = timedelta(seconds=localtm.tm_gmtoff) if reverse: delta = -delta tz = timezone(delta, localtm.tm_zone) dt += delta return dt if naive else dt.astimezone(tz)
def erase_data(self, selected_datetime: datetime): if not os.path.exists(self.working_path): print('Pasta de trabalho inexistente') else: data = selected_datetime.astimezone(tz=timezone.utc) file_path = 's3://noaa-goes16/' + self.product_name + '/' + str( data.year) + '/' + str(data.timetuple().tm_yday) + '/' + str( data.hour).zfill(2) + '/' fs = s3fs.S3FileSystem(anon=True) files = np.array(fs.ls(file_path)) for file_with_path in files: filename = file_with_path.split('/')[-1] if os.path.exists(self.working_path + filename): os.remove(self.working_path + filename)
def to_ticks(date_time: datetime) -> int: """ Return the number of ticks for a date time. Ticks are defined here as number of seconds since the unix epoch (00:00:00 UTC on 1 January 1970) :param date_time: Date time to convert :return: number of ticks """ ticks = ( date_time.timestamp() if date_time.tzinfo else date_time.astimezone(timezone.utc).timestamp() ) return int(ticks)
def _split_today_tomorrow_prices( current_prices: Dict[datetime, float], utc_time: datetime, timezone: zoneinfo.ZoneInfo, ) -> Tuple[Dict[datetime, float], Dict[datetime, float]]: local_time = utc_time.astimezone(timezone) today, tomorrow = {}, {} for ts_utc, price_h in current_prices.items(): ts_local = ts_utc.astimezone(timezone) if _is_tomorrow_price(ts_local, local_time): tomorrow[ts_utc] = price_h else: today[ts_utc] = price_h return today, tomorrow
def validate_time(time: datetime = datetime.utcnow()) -> None: """Validate that it's a Sunday UTC time Args: time (datetime): Time to validate. Defaults to datetime.utcnow() Raises: InvalidConditionError: Not a Sunday UTC time """ time = time.astimezone(timezone.utc) if time.strftime("%A") != "Sunday": raise InvalidConditionError( "entering_and_transitioning_app only runs on Sundays")
def timestamp(dt: datetime = None) -> float: """获取时间戳, 如果参数为None则返回当前时间戳 :param dt: 要转化为时间戳的时间,如果为None则返回当前时间戳。 :return float: 时间戳 """ if dt is None: return time.time() else: if dt.tzinfo is None: dt = _DEFAULT_TIMEZONE.localize(dt) utc_dt = dt.astimezone(pytz.utc) delta = utc_dt - datetime(1970, 1, 1, 0, 0 ,0, 0, pytz.utc) return delta.total_seconds()
def convert_utc_into_jst(self, time: datetime) -> datetime: """naive/awareなUTCをawareなJSTにする関数 Args: created_at (datetime): naiveなUTC Returns: datetime: awareなJST """ if time.tzinfo is None: time = pytz.utc.localize(time) time_jst = time.astimezone(pytz.timezone(self.local_timezone.zone)) return time_jst
def to_utc(date: datetime) -> datetime: """Convert date to utc. :param date: datetime object. :return: utc datetime object. """ if isinstance(date, datetime): try: # for timezone aware objects return date.astimezone(pytz.utc) except ValueError: # replace timezone if naive date return date.replace(tzinfo=pytz.utc) raise TypeError('Provided object is not instance of datetime.')
async def get_account_trades(self, from_timestamp: datetime.datetime = None, to_timestamp: datetime.datetime = None, pair: Pair = None, max_page_size: str = None, cursor: str = None) -> dict: params = BitpandaClient._clean_request_params({ "max_page_size": max_page_size, "cursor": cursor, }) if pair is not None: params["instrument_code"] = map_pair(pair) if from_timestamp is not None: params["from"] = from_timestamp.astimezone(pytz.utc).isoformat() if to_timestamp is not None: params["to"] = to_timestamp.astimezone(pytz.utc).isoformat() return await self._create_get("account/trades", params=params, signed=True)
def guess_next_update_utc(dt: datetime = datetime.now(timezone.utc)) \ -> Tuple[datetime, bool]: """ Make a sensible guess at earliest possible datetime of next update. Guess is based on provided datetime. Parameters ---------- dt : datetime The datetime to use as the basis for comparison to guess the "next update" datetime. Returns ------- Tuple[datetime, bool] A UTC-based datetime for the next update; a boolean that indicates whether the provided dt is likely to coincide with a publish process, which is the APPROX_PUBLISH_DURATION window starting 20:00 on the normal publish days specified by PUBLISH_ISO_WEEKDAYS. """ config = get_application_config() tz = gettz(config.get('ARXIV_BUSINESS_TZ', 'US/Eastern')) dt = dt.astimezone(tz=tz) possible_publish_dt = dt.replace(hour=20, minute=0, second=0) after_todays_publish: bool = dt >= possible_publish_dt likely_in_publish = False delta_to_next_publish = timedelta(days=0) weekday = dt.isoweekday() if after_todays_publish: delta_to_next_publish = timedelta(days=1) if dt < (possible_publish_dt + APPROX_PUBLISH_DURATION) \ and weekday in PUBLISH_ISO_WEEKDAYS: likely_in_publish = True if weekday == 4 and after_todays_publish: # It's Thursday and after publish; next update would be Sunday delta_to_next_publish = timedelta(days=3) elif weekday in (5, 6): # It's Friday or Saturday days_to_add = 7 - weekday delta_to_next_publish = timedelta(days=days_to_add) possible_publish_dt = possible_publish_dt + delta_to_next_publish return (possible_publish_dt.astimezone(tz=tzutc()), likely_in_publish)
async def get_timestring(last_changed: datetime) -> str: # exact state-change time but not relative/readable time last_changed = datetime.fromisoformat(str(last_changed)) # calculate timedelta opened_ago = datetime.now().astimezone() - last_changed.astimezone() opened_ago_min, opened_ago_sec = divmod( (datetime.now().astimezone() - last_changed.astimezone()).total_seconds(), float(SECONDS_PER_MIN), ) # append suitable unit if opened_ago.total_seconds() >= SECONDS_PER_MIN: if opened_ago_sec < 10 or opened_ago_sec > 50: open_since = f"{hl(int(opened_ago_min))}min" else: open_since = f"{hl(int(opened_ago_min))}min {hl(int(opened_ago_sec))}sec" else: open_since = f"{hl(int(opened_ago_sec))}sec" return open_since
def _to_dt( obj: typing.Union["Time", datetime.datetime], ref: datetime.datetime ) -> datetime.datetime: if isinstance(obj, datetime.datetime): return obj elif isinstance(obj, Time): return ref.astimezone(obj.tzinfo).replace( minute=obj.minute, hour=obj.hour, second=0, microsecond=0, ) else: raise ValueError(f"Unsupport comparaison type: {type(obj)}")
def move_tz(dt: _datetime.datetime, tz: str) -> _datetime.datetime: """Change a datetime from one timezone to another.""" # Datetime provides a ValueError if you use this function on a naive DT, so # no need to explicitly raise an error here. return dt.astimezone(pytz.timezone(tz))
def localtime_format(value: datetime, fmt: str): return value.astimezone(config.TIMEZONE).strftime(fmt)
def datetime_(dt: datetime, now: Optional[datetime] = None) -> str: if now is None: now = datetime.utcnow() if dt.tzinfo != now.tzinfo: tz = dt.tzinfo or now.tzinfo dt, now = dt.astimezone(tz), now.astimezone(tz) return timedelta_(now - dt)
def convert_to_UTC(dt: datetime.datetime) -> datetime.datetime: if dt.tzinfo is None: return dt.replace(tzinfo=timezone_utc) return dt.astimezone(timezone_utc)
def to_unix_time(dtime: dt.datetime) -> float: """convert a datetime object to unix time in UTC (as a float)""" if getattr(dtime, 'tzinfo', None) is not None: dtime = dtime.astimezone(pytz.UTC) unix_time = timegm(dtime.timetuple()) return unix_time