难以理解时间转换

时间:2018-11-14 14:12:04

标签: python time epoch datetime-conversion

我在理解python中的时间转换时遇到了一些麻烦。 我有两个相同的time_struct对象

In [22]: local_dt
Out[22]: datetime.datetime(2000, 1, 1, 0, 0, tzinfo=<DstTzInfo 'America/Los_Angeles' PST-1 day, 16:00:00 STD>)
In [23]: local_dt.timetuple()                                                                                                                             
Out[24]: time.struct_time(tm_year=2000, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=1, tm_isdst=0)

当我将其输入到一台计算机上的time.mktime函数中

time.mktime(local_dt.timetuple())

它返回946681200.0

在第二台计算机上,我得到了不同的答案

In [31]: local_dt.timetuple()                                                                                                                             
Out[31]: time.struct_time(tm_year=2000, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=1, tm_isdst=0)

In [32]: time.mktime(local_dt.timetuple())                                                                                                                
Out[32]: 946684800.0

尽管这些机器具有不同的时区:

In [44]: time.tzname                                                                                                                                      
Out[44]: ('Europe', 'Europe')

In [45]: time.tzname
Out[45]: ('CET', 'CEST')

时间模块上的文档说:

  

使用以下函数在时间表示形式之间进行转换:   距纪元mktime()的本地时间秒数struct_time

据我了解,我的本地时间是“ America / Los_Angeles”,因此自纪元起的秒数应该完全相同,而不取决于系统配置。

我误会什么?那我该如何正确计算时间戳呢?

2 个答案:

答案 0 :(得分:1)

time.mktime()根据本地计算机的时区解释timetuple。请注意,您的timetuple对象如何不包含任何时区信息,因此创建的时间戳将始终根据本地计算机上设置的时区而有所不同。因此,完全可以理解为什么相同的time.mktime(local_dt.timetuple())在这两台机器上返回不同的值。

您可以改用local_dt.timestamp(),而两者都是essentially the same ...

  

假定朴素的datetime实例代表本地时间,并且此方法依赖于平台C mktime()函数来执行转换。

...但是由于您是直接从非幼稚的timestamp对象创建datetime的,因此它仍然保留时区信息并可以相应地更改时间:

  

对于已知的datetime实例,返回值的计算方式为:

     

(dt - datetime(1970, 1, 1, tzinfo=timezone.utc)).total_seconds()

观察:

>>> est = datetime.datetime(1999, 12, 31, 19, 0).astimezone(pytz.timezone('EST'))
>>> utc = est.astimezone(pytz.timezone('UTC'))
>>> est
datetime.datetime(1999, 12, 31, 19, 0, tzinfo=<StaticTzInfo 'EST'>)
>>> utc
datetime.datetime(2000, 1, 1, 0, 0, tzinfo=<UTC>)
>>> est.timestamp()
946684800.0           
>>> utc.timestamp()
946684800.0           # same as est
>>> time.mktime(est.timetuple())
946684800.0
>>> time.mktime(utc.timetuple())
946702800.0           # different than est

由于未传递时区信息,最后一个time.mktime()处理utc.timetuple()作为本地时间。您会注意到它的偏移量为18000(对于EST,我的时区为time.timezone)。

答案 1 :(得分:0)

您说过:“尽管这些机器具有不同的时区:”,而doc却说:“在当地时间”。

您的“本地时间”在两台计算机上都不相同:一个是欧洲/欧洲(可能是格林尼治标准时间,所以UTC + 0),另一个是CEST(UTC +1)。

请参阅https://www.timeanddate.com/time/zones/eu

  

欧洲中部时间(CET)比世界协调时间(UTC)早1小时。   该时区在欧洲,非洲的标准时间使用。

我认为您想将日期时间转换为“ UTC + 0日期时间”