请注意, 与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)
的时间,这是真正的午夜。
编辑:
我实际上在想我和我之间的区别是我正在寻找过去最近的午夜。这个问题的答案似乎能够给出过去或未来的午夜,或许?
答案 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