关于python:给定UTC时间,获取指定时区的午夜

Given a UTC time, get a specified timezone's midnight

请注意,这与此问题并不完全相同。这个问题假定你想要的时间是"现在",这与任意时间点不同。

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

我有一个时区,称之为location(例如'US/Pacific'),因为我关心它的位置,但它与UTC的时间偏差可能会在全年都有所改变,夏令时等等。

我想要
1)如果我站在location,得到point_in_time的日期,
2)如果我站在location,那个日期的午夜。

===

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

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

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


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

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

1
2
3
4
5
6
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)

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


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

1
2
3
4
5
6
7
8
9
10
11
12
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点,所以你可以简化它

1
2
3
4
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