Python 将UTC时间转换为历元

Python 将UTC时间转换为历元,python,date,datetime,Python,Date,Datetime,我希望分析交通流量与天气数据的关系。流量数据有一个UNIX时间戳(又名epoch),但是我在将时间戳(在天气数据中)转换为epoch时遇到了麻烦。问题是我在挪威,天气数据中的UTC时间戳与我不在同一时区(GMT+1) 我最初的做法 我首先尝试将其转换为历元,并将数据视为在GMT+1时区。然后我通过减去UTC和GMT+1之间秒数的差值进行补偿 方法的问题 我首先意识到,这种方法非常原始,也不是很优雅(事实上,它充其量只是一种丑陋的黑客行为)。然而,这里最大的问题是UTC和GMT+1之间的差异不是恒

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

我最初的做法

我首先尝试将其转换为历元,并将数据视为在GMT+1时区。然后我通过减去UTC和GMT+1之间秒数的差值进行补偿

方法的问题

我首先意识到,这种方法非常原始,也不是很优雅(事实上,它充其量只是一种丑陋的黑客行为)。然而,这里最大的问题是UTC和GMT+1之间的差异不是恒定的(由于夏令时)

问题

是否有可靠的方法将UTC时间转换为python中的UNIX时间戳(考虑到我的机器使用的是GMT+1)?时间戳的格式如下:

Y-m-d HH:MM:SS

编辑: 尝试了RMUNS的解决方案:

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.

您可以使用
time
datetime
模块:

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'
>>> 

另一种方法,
datetime
有自己的
.strtime()
方法

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

这可能会帮助你。它允许您编写如下代码:

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工作,仅当生成供人读取的输出时才转换为localtime

因此,在编写代码时要记住这一点:将本地时间转换一次,并且只转换一次,这样就可以更轻松地正确比较两个时间戳

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

  • ,Taavi Burns的PyCon 2012演示文稿(30分钟)
  • ,分两部分介绍。(注意:视频中有令人讨厌的嗡嗡声,但我找不到声音更好的副本)。第一部分是我在上面链接的“关于datetimes您需要了解的内容”,第二部分有一些解析日志文件和使用日志文件做有用事情的实用技巧。(50分钟)
更新2:您在更新的问题(我在下面复制)中提到的
convert\u UTC\u to\u 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月10日02:42 UTC减去6月9日19:42 UTC(这就是
time.time()
返回的值)得到的差值为7小时。有关为什么不应使用strftime(“%s”)的更多详细信息,请参阅


(顺便说一句,如果你看到了我之前在标题“Update 2”下写的东西,我声称
time.time()
返回本地时间,请忽略这一点——我弄错了。一开始我和你一样被
strftime(“%s”)
错误愚弄了。)

解决方案是使用日历模块(灵感来源于)

这是转换函数:

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

我不明白你的第一段。你说流量数据是“UNIX时间戳(aka-epoch)”格式的,但是你想把它转换成epoch格式,它已经是这种格式了?请澄清。我将用我对你的意思的最佳猜测来回答你的问题,但对输入格式和输出格式的解释会有所帮助。@rmun这是一个小的打字错误。交通数据采用历元格式。天气数据是字符串格式的Y-m-d HH:MM:SS(UTC)。我已更新了我的答案,以说明出现问题的原因以及正确的解决方案。(有两种正确的解决方案,取决于您是否需要关心毫秒。)更新:对不起,我以前的评论是错误的。问题不在于您使用了
time.time()
,而在于您使用了
strftime(“%s”)
:“它不受支持,不可移植,它可能会默默地为aware datetime对象生成错误的结果,如果输入是UTC(如问题中所示),但本地时区不是UTC,则会失败”。相关:
time。mktime(date)
就足够了。
mktime()
预期的是本地时间(如问题中所述),而不是UTC时间
mktime()
已返回时间戳(在Unix上从历元开始的秒数);您不应该调用
fromtimestamp().strftime()
<代码>strftime('%s')不可移植(它在Unix上与本地时间一起工作)。请注意,我的代码假定您的输入时间戳是字符串。如果您输入的是历元数(UTC 1970年1月1日午夜后的秒数),则您需要使用
datetime.datetime.fromtimestamp(一些数字)
而不是
datetime.datetime.strtime(
>>>#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