`pytz.localize ()` с округлением до ближайшего существующего часа (в случае скачка летнего времени) - PullRequest
0 голосов
/ 15 марта 2019

В основном я получил:

tz = pytz.timezone('US/Eastern')
dt = datetime.datetime(2019, 03, 10, 02, 30)

Я хочу локализовать dt для часового пояса при удалении несуществующего часа.

Если я сделаю tz.normalize(tz.localize(dt)), я 'я получу

datetime.datetime(2019, 3, 10, 3, 30, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>)

Я хочу

datetime.datetime(2019, 3, 10, 3, 00, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>)

(используйте 03:00 вместо 03:30, поскольку он ближе к 02:30 настенных часов).

Вариант использования: я получил список настенных часов (один из них, случается, 02:30), дата-время 2019-03-10 и часовой пояс США / Восточный.

Я хочу построить временные метки в определенной дате и часовом поясе, используя 03:00 (ну, на самом деле, время сразу после перехода на летнее время) вместо любого времени на стене, которое станет недействительным, когда я объединю метку времени с датой и временеми локализуйте это.Это делается для автоматического копирования списка встреч, связанных с часами на другой день, на другой день.

1 Ответ

0 голосов
/ 15 марта 2019
def localize_and_round_datetime(dt, tz):
    """
    Similar to tz.normalize(tz.localize(dt)), but rounds any time in non-existing hour to the time right after it.
    """
    result = tz.normalize(tz.localize(dt))
    if result.replace(tzinfo=None) == dt:
        return result

    # DT belongs to the leap hour. find the datetime right after leap
    # see: DstTzInfo.localize()
    tzinfo_dst_idx = bisect_right(tz._utc_transition_times, dt)
    new_tz = tz._utc_transition_times[tzinfo_dst_idx]
    return pytz.UTC.localize(new_tz).astimezone(tz)

, кажется, работает.

...