给定UTC时间,获取指定时区的午夜

时间:2017-03-15 00:04:48

标签: python datetime timezone timezone-offset pytz

请注意, this question相同。那个问题假设你想要的时间是“现在”,这与任意时间点都不一样。

我有一个UTC,感知日期时间对象,称之为point_in_time(例如datetime(2017, 3, 12, 16, tzinfo=tz.tzutc()))。

我有一个时区,称之为location(例如'US/Pacific'),因为我关心其中,但它与UTC的小时数可能会在一年内发生变化夏令时等等。

我想要 1)如果我站在point_in_time,则获得location的日期 2)如果我站在location,请到达该日期的午夜。

===

我尝试使用.astimezone(timezone('US/Pacific')),然后.replace(hours=0, ...)移至午夜,但正如您可能会注意到我的示例point_in_time,该日期的午夜位于另一侧夏令时开关!

结果是我得到了代表UTC datetime(2017, 3, 12, 7)的时间,而不是代表UTC datetime(2017, 3, 12, 8)的时间,这是真正的午夜。

编辑:
我实际上在想我和我之间的区别是我正在寻找过去最近的午夜。这个问题的答案似乎能够给出过去或未来的午夜,或许?

2 个答案:

答案 0 :(得分:1)

您的示例突出显示了在本地时区进行日期时算术的危险。

您可以使用pytz的normalize()函数实现此目的,但这是我遇到的方法:

point_in_time = datetime(2017, 3, 12, 16, tzinfo=pytz.utc)
pacific = pytz.timezone("US/Pacific")
pacific_time = point_in_time.astimezone(pacific)
pacific_midnight_naive = pacific_time.replace(hour=0, tzinfo=None)
pacific_midnight_aware = pacific.localize(pacific_midnight_naive)
pacific_midnight_aware.astimezone(pytz.utc)  # datetime(2017, 3, 12, 8)

换句话说,你首先转换到太平洋时间来确定正确的日期;然后你从该日期的午夜再次转换,以获得正确的当地时间。

答案 1 :(得分:0)

"US/Pacific"等命名时区根据定义可识别日光节省。如果您希望使用GMT中固定的非日光节省感知偏移量,您可以使用时区"Etc/GMT+*",其中*是所需的偏移量。例如,对于美国太平洋标准时间,您将使用"Etc/GMT+8"

import pandas as pd
point_in_time = pd.to_datetime('2017-03-12 16:00:00').tz_localize('UTC')

# not what you want
local_time = point_in_time.tz_convert("US/Pacific")
(local_time - pd.Timedelta(hours=local_time.hour)).tz_convert('UTC')
# Timestamp('2017-03-12 07:00:00+0000', tz='UTC')

# what you want
local_time = point_in_time.tz_convert("Etc/GMT+8")
(local_time - pd.Timedelta(hours=local_time.hour)).tz_convert('UTC')
# Timestamp('2017-03-12 08:00:00+0000', tz='UTC')

有关详细信息,请参阅http://pvlib-python.readthedocs.io/en/latest/timetimezones.html处的文档。

编辑现在我考虑一下,午夜太平洋标准时间将始终是UTC时间早上8点,所以你可以简化这个

if point_in_time.hour >=8:
    local_midnight = point_in_time - point_in_time.hour + 8
else:
    local_midnight = point_in_time - point_in_time.hour - 16