Python: как преобразовать метку времени/времени из одного часового пояса в другой часовой пояс?

в частности, учитывая часовой пояс моего сервера (системная временная перспектива) и вход часового пояса, как я могу рассчитать системное время, как если бы оно было в этом новом часовом поясе (независимо от летнего времени и т. д.)?

import datetime
current_time = datetime.datetime.now() #system time

server_timezone = "US/Eastern"
new_timezone = "US/Pacific"

current_time_in_new_timezone = ???

2 ответов


если вы знаете свой часовой пояс origin и новый часовой пояс, в который вы хотите его преобразовать, сначала используйте pytz.localize для обработки любой локализации (например, для экономии дневного света и т. д.) Используйте pytz.timezone для создания объектов часового пояса и, наконец, использовать datetime.astimezone(timezone) для простого расчета. Например:

import datetime
import pytz # new import

my_timestamp = datetime.datetime.now() # some timestamp
old_timezone = pytz.timezone("US/Eastern")
new_timezone = pytz.timezone("US/Pacific")

# returns datetime in the new timezone
my_timestamp_in_new_timezone = old_timezone.localize(my_timestamp).astimezone(new_timezone) 

и, конечно, если все, что вам нужно, это текущее время в определенном часовом поясе, вы можете передать этот часовой пояс непосредственно в datetime.теперь (), чтобы получить метку времени. Как это:

datetime.datetime.now(new_timezone)

теперь со всем сказанным, я настоятельно рекомендую хранить все ваши метки времени в UTC в качестве системного стандарта и избегать всей проблемы DST. Для контекста об этом см.:http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/

и знать, как трудно иметь дело с вычислениями времени в целом:http://yourcalendricalfallacyis.com


как вы конвертировать datetime/timestamp из одного часового пояса в другой часовой пояс?

есть два шага:

  1. создайте осведомленные объекты datetime из системного времени и часового пояса например, чтобы получить текущее системное время в данном часовом поясе:

    #!/usr/bin/env python
    from datetime import datetime
    import pytz
    
    server_timezone = pytz.timezone("US/Eastern")
    server_time = datetime.now(server_timezone) # you could pass *tz* directly
    

    Примечание: datetime.now(server_timezone) работает даже в неоднозначные времена например, во время переходов DST в то время как server_timezone.localize(datetime.now()) может произойти сбой (50% шанс.)

    если вы уверены, что ваше время ввода существует в часовом поясе сервера, и оно уникально, вы можете пройти is_dst=None утверждать, что:

    server_time = server_timezone.localize(naive_time, is_dst=None)
    

    это вызывает исключение для недопустимых времен.
    Если допустимо игнорировать до в день ошибка (хотя обычно ошибка из-за DST вокруг час) тогда вы могли бы упасть :

    server_time = server_timezone.normalize(server_timezone.localize(naive_time))
    

    .normalize() вызывается для настройки несуществующего времени (местное время в промежутке, во время переходов "весна вперед"). Если правила часового пояса не изменились; ваш сервер не должен генерировать несуществующее время. См. " могу ли я всегда устанавливать is_dst=True?"

  2. преобразование объекта datetime в целевой часовой пояс tz:

    tz = pytz.timezone("US/Pacific")
    server_time_in_new_timezone = server_time.astimezone(tz)