将UTC时间转换为纪元

时间:2014-06-04 02:04:33

标签: python date datetime

我希望分析与天气数据相关的交通流量。流量数据具有UNIX时间戳(也称为纪元),但是我将时间戳(在天气数据中)转换为纪元时遇到了麻烦。问题是我在挪威,天气数据中的UTC时间戳与我不在同一时区(GMT + 1)。

我的初步方法

我首先尝试将其转换为时代并将数据视为处于GMT + 1时区。然后我通过减去UTC和GMT + 1之间的秒数差来补偿。

方法问题

我首先意识到这种方法非常原始并且不是很优雅(实际上可能它至多是一个丑陋的黑客)。但是,这里最大的问题是UTC和GMT + 1之间的差异不是恒定的(由于夏令时)。

问题

是否有任何可靠方式将UTC时间转换为python中的UNIX时间戳(考虑到我的机器处于GMT + 1)?时间戳采用以下格式:

Y-m-d HH:MM:SS

编辑: 试过rmunns的解决方案:

def convert_UTC_to_epoch(timestamp):
  tz_UTC = pytz.timezone('UTC')
  time_format = "%Y-%m-%d %H:%M:%S"
  naive_timestamp = datetime.datetime.strptime(timestamp, time_format)
  aware_timestamp = tz_UTC.localize(naive_timestamp)
  epoch = aware_timestamp.strftime("%s")
  return (int) (epoch)

这样做正常工作,如下所示:

#Current time at time of the edit is 15:55:00 UTC on June 9th 2014.
>>> diff = time.time() - convert_UTC_to_epoch("2014-06-09 15:55:00")
>>> diff
3663.25887799263
>>> #This is about an hour off.

4 个答案:

答案 0 :(得分:4)

解决方案是使用日历模块(灵感来自here

>>>#Quick and dirty demo
>>>print calendar.timegm(datetime.datetime.utcnow().utctimetuple()) - time.time()
>>>-0.6182510852813721

这是转换功能:

import calendar, datetime, time

#Timestamp is a datetime object in UTC time
def UTC_time_to_epoch(timestamp):
  epoch = calendar.timegm(timestamp.utctimetuple())
  return epoch

答案 1 :(得分:3)

另一种选择,datetime拥有自己的.strptime()方法。

http://en.wikipedia.org/wiki/Unix_time

  
    

Unix纪元是1970年1月1日00:00:00 UTC(或1970-01-01T00:00:00Z ISO 8601)的时间。

  
import datetime
unix_epoch = datetime.datetime(1970, 1, 1)
log_dt = datetime.datetime.strptime("14-05-07 12:14:16", "%y-%m-%d %H:%M:%S")
seconds_from_epoch = (log_dt - unix_epoch).total_seconds()
>>> 1399490056.0

答案 2 :(得分:3)

pytz module可能对您有所帮助。它允许您编写如下代码:

import pytz
import datetime
tz_oslo = pytz.timezone('Europe/Oslo')
time_format = "%Y-%m-%d %H:%M:%S"
naive_timestamp = datetime.datetime(2014, 6, 4, 12, 34, 56)
# Or:
naive_timestamp = datetime.datetime.strptime("2014-06-04 12:34:56", time_format)
aware_timestamp = tz_oslo.localize(naive_timestamp)
print(aware_timestamp.strftime(time_format + " %Z%z"))

这应打印" 2014-06-04 14:34:56 CEST + 0200"。

请从pytz手册中注意以下事项:

  

处理时间的首选方法是始终使用UTC,仅在生成输出以供人类阅读时转换为本地时间。

因此,在编写代码时请记住这一点:只转换到本地时间一次,然后您就可以更轻松地比较两个时间戳之间的比较。

更新:以下是您可能会发现有用的几个视频:

  • What you need to know about datetimes,由Taavi Burns撰写的PyCon 2012演讲(30分钟)
  • Drive-in Double Header: Datetimes and Log Analysis,由两部分组成。 (注意:视频中有恼人的嗡嗡声,但我找不到声音更好的副本)。第一部分是"您需要了解的关于日期时间的信息"演示文稿我在上面链接,第二部分有一些实用技巧,用于解析日志文件并使用它们执行有用的操作。 (50分钟)

更新2 :您在更新的问题中提到的convert_UTC_to_epoch()功能(我已在下面转发)返回当地时间,而不是UTC:

def convert_UTC_to_epoch(timestamp):
  tz_UTC = pytz.timezone('UTC')
  time_format = "%Y-%m-%d %H:%M:%S"
  naive_timestamp = datetime.datetime.strptime(timestamp, time_format)
  aware_timestamp = tz_UTC.localize(naive_timestamp)
  epoch = aware_timestamp.strftime("%s")
  return (int) (epoch)

问题是您正在使用strftime("%s"),这是未记录的并且返回错误的结果。 Python不支持%s参数,但它似乎有效,因为它传递给系统的strftime()函数,它支持%s参数 - 但它返回本地时间!您正在使用UTC时间戳并将其解析为本地时间,这就是它休息一小时的原因。 (这个谜就是为什么现在不是两个小时 - 挪威在夏令时间?现在不能在UTC + 2吗?)

正如您在下面的交互式Python会话中所看到的,我在UTC + 7时区,而convert_UTC_to_epoch()功能对我来说是七个小时。

# Current time is 02:42 UTC on June 10th 2014, 09:42 local time
>>> time.timezone
-25200
>>> time.time() - convert_UTC_to_epoch("2014-06-10 02:42:00")
25204.16531395912
>>> time.time() + time.timezone - convert_UTC_to_epoch("2014-06-10 02:42:00")
6.813306093215942

strftime("%s")电话是在6月10日02:42解释当地时间,即6月9日19:42 UTC。从6月9日的02:42 UTC 6月10日(这是time.time()返回的)减去19:42 UTC,给出了7个小时的差异。有关您永远不应使用strftime("%s")的原因的详细信息,请参阅Convert python datetime to epoch with strftime

(顺便说一下,如果你看到我之前在标题"更新2"之前写过的内容,我声称time.time()正在返回当地时间,请忽略 - 我得到了它错了。我最初被strftime("%s")错误愚弄了,就像你一样。)

答案 3 :(得分:0)

您可以使用timedatetime模块:

import time, datetime
date = "14-05-07 12:14:16" #Change to whatever date you want
date = time.strptime(date, "%y-%m-%d %H:%M:%S")
epoch = datetime.datetime.fromtimestamp(time.mktime(date)).strftime('%s')

运行如下:

>>> import time, datetime
>>> date = "14-05-07 12:14:16"
>>> date = time.strptime(date, "%y-%m-%d %H:%M:%S")
>>> epoch = datetime.datetime.fromtimestamp(time.mktime(date)).strftime('%s')
>>> epoch
'1399490056'
>>>