Python与Javascript DateTime的比较

8

我想把一个Javascript API调用转换成Python代码。这个可行的Javascript代码可以正常工作,并生成类似于以下这样的时间戳:

var curdate = new Date();
var gmtstring = curdate.toGMTString();
var utc = Date.parse(gmtstring) / 1000;

这个结果(自纪元以来的秒数)随后被哈希并用于API调用,但这是相关部分。如果有人能告诉我正确的转换方式,将不胜感激。

以下是有关不同方法得到的不同结果的详细信息:

Javascript(有效的API结果)

var curdate = new Date(2013, 7, 10);
var gmtstring = curdate.toGMTString();
var utc = Date.parse(gmtstring) / 1000;

结果:1376089200

Python(API结果无效)

from datetime import datetime
import calendar

d = datetime(2013, 8, 10)
calendar.timegm(d.utctimetuple())

结果:1376092800

我显然缺少一些东西,有人能给我解释一下吗?

更新

我最初在我的例子中犯了一个错误,因为Javascript使用基于0的日期,Python的日期是基于1的。

Jonathon友善地解释说,这些值的差异是由于Python默认为UTC,而Javascript默认为本地时区。在我的情况下,这是GMT,这是API所需的。现在我只需要在Python中获得这个结果。

答案

解决方案是提供的时区不匹配。虽然我仍然遇到第三方api的问题,但我至少现在获得了正确的时间。

这可能需要清理:

from datetime import datetime
import calendar
import time
import pytz

def GenerateTimeStamp(d):
    europe = pytz.timezone('Europe/London')
    d = europe.localize(d)
    tuple = d.utctimetuple()
    timestamp = int(time.mktime(tuple))
    return timestamp

只需提供日期时间:

GenerateTimeStamp(datetime(2013, 8, 10))

或者

GenerateTimeStamp(datetime.utcnow())

作为旁注,如果您正在尝试此操作并希望使用pip安装pytz1,您可以使用pre tag2获取它:
pip install --pre pytz
3个回答

8
对于 JavaScript 日期,month 参数的取值范围为 0 - 11。所以,如果要表示八月份,需要传递 7

整数值代表月份,从一月份的 0 开始到十二月份的 11。

它们也有不同的默认时区,Python 的默认时区是 UTC,而 JavaScript 的默认时区是用户的 "本地" 时区。
你可以使用 Date.UTC() 来获取 JavaScript 中对应的时间戳。
var utc = Date.UTC(2013, 7, 10) / 1000;
// 1376092800

顺带一提:你可以使用 getTime() 方法来获取一个 Date 对象的时间戳。

var curdate = new Date(2013, 7, 10);
var utc = curdate.getTime() / 1000;

糟糕,我的错误,我更正了示例日期。只是在看你的UTC建议。 - Paul Coghill
啊,这就解释了示例中的差异,JavaScript 是我需要的结果。我的时区是 GMT,这就解释了这一点。你能建议一下如何在 Python 中获取 GMT 结果吗? - Paul Coghill
@PaulCoghill 嗯,你现在从Python得到了该日期的UTC/GMT时区;这似乎是问题所在。如果你想让Python在不同的时区创建datetime,你可以传递一个自定义的tzinfo子类实例datetime(2013, 8, 10, tzinfo=desiredTZ)。你也可以使用pytzpytz.timezone('...').localize(datetime(2013, 8, 10)) - Jonathan Lonowski

3
在JavaScript中,new Date(2013, 8, 10)表示的是2013年9月10日。

Python

在Python中,datetime(2013, 8, 10)表示的是2013年8月10日。

你正在比较两个不同的日期。

本地时间与UTC

结果可能会有所不同(我的系统时区为亚洲/首尔)。

> new Date(2013, 7, 10) / 1000
1376060400
> Date.UTC(2013, 7, 10) / 1000
1376092800

Python

>>> import calendar
>>> import datetime
>>> import time
>>> time.mktime(datetime.datetime(2013, 8, 10).timetuple())
1376060400.0
>>> calendar.timegm(datetime.datetime(2013, 8, 10).timetuple())
1376092800

查看Python - calendar.timegm() vs. time.mktime()


谢谢,我会阅读你推荐的文章。谢谢更新,不过我需要调用的API将期望1376089200作为该日期,就像问题中的示例一样。 - Paul Coghill
@PaulCoghill,你在哪个时区? - falsetru
GMT。尽管目前是英国夏令时(BST),但JavaScript可以在任何时间正常工作。 - Paul Coghill
@PaulCoghill,你是否在你的系统中尝试过 time.mktime(datetime.datetime(2013, 8, 10).timetuple()) - falsetru
time.mktime(datetime.datetime(2013, 8, 10).timetuple()) 返回 1376092800.0 - Paul Coghill

1
除了Jonathan上面的回答,我可能会在python方面推荐这个:
 d = datetime(2013, 8, 10)
 d.strftime("%s")

那将返回:'1376107200'。

对我来说,这将返回: 1376089200 本地 1376092800 在远程服务器上 - Paul Coghill

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接