我正在调试一些DateTime功能,特别是在本地时间和UTC之间转换。我正在使用的程序将仅在Linux和Mac上运行,但我希望看到一个跨平台解决方案。我正在使用dateTime.timestamp()在数据库中存储的几秒钟内生成UTC时间戳,但在转换为和FRO时会注意到一些非常不稳定的行为。
根据Python文档,DateTime.timestamp()应该返回代表POSIX(UTC)时间为秒数以来秒的浮点。据我了解...对于TZ Naive对象(或已经在UTC中定位的对象),这将是总数几秒钟。对于TZ Aware对象,这次应自动从给定的TZ转换为UTC。
为了测试这种行为,我在2000年1月1日创建了一个tz-nive dateTime对象。然后,这次将其定位为美国/太平洋,并使用.astimezone()转换为UTC。这是一些设置代码:
import datetime, time
from pytz import timezone
tz_pac = timezone("US/Pacific")
tz_utc = timezone("UTC")
start_tuple = (2000, 1, 1, 0, 0, 0)
naive_time_obj = datetime.datetime(*start_tuple, tzinfo = None)
pac_time_obj = tz_pac.localize(naive_time_obj)
utc_time_obj = pac_time_obj.astimezone(tz_utc)
naive_seconds = int(naive_time_obj.strftime("%s"))
pac_seconds = int(pac_time_obj.strftime("%s"))
utc_seconds = int(utc_time_obj.strftime("%s"))
print("Naive\tseconds:", naive_seconds, "\ttimestamp:", naive_time_obj.timestamp(), "\trepr:", naive_time_obj)
print("PAC\tseconds:", pac_seconds, "\ttimestamp:", pac_time_obj.timestamp(), "\trepr:", pac_time_obj)
print("UTC\tseconds:", utc_seconds, "\ttimestamp:", utc_time_obj.timestamp(), "\trepr:", utc_time_obj)
我要得到的:
Naive seconds: 946713600 timestamp: 946713600.0 repr: 2000-01-01 00:00:00
PAC seconds: 946713600 timestamp: 946713600.0 repr: 2000-01-01 00:00:00-08:00
UTC seconds: 946742400 timestamp: 946713600.0 repr: 2000-01-01 08:00:00+00:00
Naive对象的输出是有道理的,因为没有时区信息可转换。对于PAC局部化对象,我希望时间戳从几秒钟转换为TZ,但它们是平等的。对于UTC本地化对象,我希望秒和时间戳相等,但是进行了转换。我想念什么?
I'm debugging some datetime functionality, specifically converting between local time and UTC. The program I'm working on will only be running on Linux and Mac but I would like to see a cross-platform solution. I'm using datetime.timestamp() to generate a utc timestamp in seconds to be stored in a database but am noticing some very erratic behavior when converting to and fro.
According to the python docs, datetime.timestamp() is supposed to return a float representing POSIX(UTC) time as seconds since the epoch. As I understand... For a tz naive object (or one already localized in UTC), this would just be total seconds. For a tz aware object, this time should be automatically be converted from the given tz to utc.
To test this behavior, I create a tz-naive datetime object at Jan, 1 2000. This time is then localized as US/Pacific and also converted to UTC with .astimezone(). Here's some setup code:
import datetime, time
from pytz import timezone
tz_pac = timezone("US/Pacific")
tz_utc = timezone("UTC")
start_tuple = (2000, 1, 1, 0, 0, 0)
naive_time_obj = datetime.datetime(*start_tuple, tzinfo = None)
pac_time_obj = tz_pac.localize(naive_time_obj)
utc_time_obj = pac_time_obj.astimezone(tz_utc)
naive_seconds = int(naive_time_obj.strftime("%s"))
pac_seconds = int(pac_time_obj.strftime("%s"))
utc_seconds = int(utc_time_obj.strftime("%s"))
print("Naive\tseconds:", naive_seconds, "\ttimestamp:", naive_time_obj.timestamp(), "\trepr:", naive_time_obj)
print("PAC\tseconds:", pac_seconds, "\ttimestamp:", pac_time_obj.timestamp(), "\trepr:", pac_time_obj)
print("UTC\tseconds:", utc_seconds, "\ttimestamp:", utc_time_obj.timestamp(), "\trepr:", utc_time_obj)
And here's what I'm getting:
Naive seconds: 946713600 timestamp: 946713600.0 repr: 2000-01-01 00:00:00
PAC seconds: 946713600 timestamp: 946713600.0 repr: 2000-01-01 00:00:00-08:00
UTC seconds: 946742400 timestamp: 946713600.0 repr: 2000-01-01 08:00:00+00:00
Output for the naive object makes sense as there is no timezone info to convert with. For the PAC localized object, I expect timestamp to be tz converted from seconds, but instead they are equal. For the UTC localized object, I expect seconds and timestamp to be equal, but a conversion has taken place. What am I missing?
发布评论
评论(1)
有几点:
Unix 时间戳(又名 POSIX 时间戳)总是< /em> 以 UTC 表示(在任何平台/语言上),因为它们代表一个不同的时刻。将表示形式转换为另一个时区不会改变该时刻。
%s
不应在 Python 中使用。它受您当地时区的影响。有关更多详细信息,请参阅此答案。Python 的
timestamp
方法将正确给出awaredatetime
实例的即时信息,但对于naive 实例,它们假定以当地时间为准。因此,在计算时间戳之前完成本地到 UTC 的转换。 文档对此进行了介绍,其中表示:< /p><块引用>
假定 Naive
datetime
实例表示本地时间,并且此方法依赖于平台 Cmktime()
函数来执行转换。就您而言,
naive_time_obj.timestamp()
仅匹配其他时间戳,因为您的本地时区可能也是太平洋时间。如果您在不同的本地时区下运行此代码,您将获得不同的值。在输出的最后一列中,所有三个值都显示正确的表示形式,因此转换正确进行。
A few things:
Unix Timestamps (aka POSIX Timestamps) are always in terms of UTC (on any platform/language) because they're representing a distinct instant in time. Converting the representation to another time zone doesn't change that instant.
%s
should not be used in Python. It's influenced by your local time zone. See this answer for more details.Python's
timestamp
method will correctly give the instant for awaredatetime
instances, but for naive instances, they are assumed to be in terms of local time. Thus a local-to-utc conversion is done before calculating the timestamp. This is covered in the docs which says:In your case, the
naive_time_obj.timestamp()
only matches the other timestamps because your local time zone is likely also Pacific time. If you ran this code under a different local time zone, you'd get a different value.In the last column of your output, all three values are showing the correct representation, and thus the conversion occurred properly.