pandas to_datetime从毫秒开始产生不正确的日期时间

时间:2017-03-09 14:51:36

标签: python pandas

包含dateMillis列的数据框,其中包含时间戳,距离纪元

的毫秒数
 In [5]: df.head(5)
    Out[5]: 
       custId     dateMillis
    0   31403  1488232800000
    1   28197  1488232800013
    2   30158  1488232800026
    3   28538  1488232800030
    4   28538  1488232800033

如果我使用python的datetime将第一行中dateMillis的值转换为datetime,我会得到以下内容

 In [8]: print datetime.datetime.fromtimestamp(df.ix[0]['dateMillis']/1000.0)
    2017-02-27 17:00:00

这是正确的。但是,如果我使用panda的to_datetime转换dateMillis列,我会得到

In [11]: df['date'] = pd.to_datetime(df['dateMillis'], unit='ms')
In [12]: df.head(5)
Out[12]: 
   custId     dateMillis                    date
0   31403  1488232800000 2017-02-27 22:00:00.000
1   28197  1488232800013 2017-02-27 22:00:00.013
2   30158  1488232800026 2017-02-27 22:00:00.026
3   28538  1488232800030 2017-02-27 22:00:00.030
4   28538  1488232800033 2017-02-27 22:00:00.033
提前五个小时。机器本身有EST时区,所以看起来pandas会将datetime转换为本地时区。

 In [15]: time.tzname
    Out[15]: ('EST', 'EDT')

我想to_datetime与datetime.fromtimestamp保持一致。我为utc参数尝试了各种值(True / False / None),但没有帮助。

1 个答案:

答案 0 :(得分:1)

默认情况下,UNIX时间戳(纪元)不知道任何时区。

  

“此计数始于1970年1月1日的Unix纪元 UTC `。

但您可以使用以下解决方法:

In [47]: datetime.datetime.fromtimestamp(df.loc[0, 'dateMillis']/1000)
Out[47]: datetime.datetime(2017, 2, 27, 23, 0)   # 23:00:00

UTC TZ:

In [48]: pd.to_datetime(df['dateMillis'], unit='ms')
Out[48]:
0   2017-02-27 22:00:00.000
1   2017-02-27 22:00:00.013
2   2017-02-27 22:00:00.026
3   2017-02-27 22:00:00.030
4   2017-02-27 22:00:00.033
Name: dateMillis, dtype: datetime64[ns]

解决方案:

In [51]: from tzlocal import get_localzone

In [52]: mytz = get_localzone()

In [53]: mytz
Out[53]: <DstTzInfo 'Europe/Berlin' LMT+0:53:00 STD>

In [54]: pd.to_datetime(df['dateMillis'], unit='ms').dt.tz_localize('UTC').dt.tz_convert(mytz)
Out[54]:
0          2017-02-27 23:00:00+01:00
1   2017-02-27 23:00:00.013000+01:00
2   2017-02-27 23:00:00.026000+01:00
3   2017-02-27 23:00:00.030000+01:00
4   2017-02-27 23:00:00.033000+01:00
Name: dateMillis, dtype: datetime64[ns, Europe/Berlin]