Какой самый быстрый способ определить, когда две метки времени выдают одинаковое местное время в Python?

Метки времени UNIX 1289106000 а также 1289109600 оба представляют 2010-11-07T01:00:00 в часовом поясе EST/EDT США-Восток в результате перехода на летнее время. Я создаю похожий на словарь объект с ключом времени, который должен сопоставить любые такие пары с одним и тем же значением.

Кроме того, насколько мы хотим избежать преждевременной оптимизации, я знаю, что эта операция выполняется в чрезвычайно узком цикле. Любое решение должно быть быстрее, чем при использовании fromtimestamp получить местное время для каждой отметки времени.

Есть ли способ структурировать внутреннее хранилище моего объекта или заранее создать какую-то таблицу поиска, которая делает это возможным?

2 ответа

Решение

Вы могли бы построить стол, уходящий так далеко в прошлое или будущее, как вам хотелось бы, с перекрывающимся часом для каждого года. Преобразовать временную метку в приблизительный год с помощью простого деления легко. Посмотрите на кортеж (start_leap_hour,end_leap_hour) из года; если временная метка находится между ними, вычтите час.

Относительно того, как можно создать таблицу критических времен DST:

Это создает дату и время, когда наступает переход на "летнее время":

import datetime as dt
import time
import itertools

def fall_dst_boundaries(date=None):
    '''
    Generates the datetimes when Daylight Savings Time "fall back" occurs after date.
    '''
    if date is None:
        date=dt.datetime.now()
    timestamp=time.mktime(date.timetuple())//3600 * 3600
    previous_date=dt.datetime.fromtimestamp(timestamp)
    while True:
        timestamp+=3600
        date=dt.datetime.fromtimestamp(timestamp)
        if date==previous_date:
            yield date
        previous_date=date

for date in itertools.islice(fall_dst_boundaries(dt.datetime(1980,1,1)),15):
    print(date)

выходы:

1980-10-26 01:00:00
1981-10-25 01:00:00
1982-10-31 01:00:00
1983-10-30 01:00:00
1984-10-28 01:00:00
1985-10-27 01:00:00
1986-10-26 01:00:00
1987-10-25 01:00:00
1988-10-30 01:00:00
1989-10-29 01:00:00
1990-10-28 01:00:00
1991-10-27 01:00:00
1992-10-25 01:00:00
1993-10-31 01:00:00
1994-10-30 01:00:00

PS. Летнее время заканчивается в 2 часа ночи, но час повторения - 1 час ночи.


Чтобы сгенерировать даты и время возврата назад, вы можете использовать что-то вроде этого:

def DST_boundaries(date=None):
    '''
    Generates the datetimes when Daylight Savings Time "fall back" or "spring
    forward" occurs after date.
    '''
    if date is None:
        date=dt.datetime.now()
    timestamp=time.mktime(date.timetuple())//3600 * 3600 + 3599
    previous_date=dt.datetime.fromtimestamp(timestamp)
    while True:
        timestamp+=3600
        date=dt.datetime.fromtimestamp(timestamp)
        if date==previous_date or date.hour-previous_date.hour>1:
            yield previous_date
        previous_date=date
Другие вопросы по тегам