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

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

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

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

Ответы [ 2 ]

2 голосов
/ 22 апреля 2011

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

1 голос
/ 22 апреля 2011

Относительно того, как можно сгенерировать таблицу критических времен 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
...