如何在JavaScript、JSON、Python和MongoDB之间处理日期时间?
我和同事一起做了一个小应用,这个应用在浏览器里使用了一堆JavaScript,并通过JSON和一个用Python3写的Tornado服务器进行通信。这个服务器使用mongodb来存储持久数据。这对我们俩来说都是第一次尝试。
我们遇到的一个难题是如何在JavaScript和Python之间传递日期时间信息。我们认为应该使用UTC时间来处理所有的时间。JSON格式本身没有日期时间的表示方式,所以我们需要想办法编码。我们天真地使用了JavaScript中从1970年开始的毫秒数,并在两者之间传递大整数。因此,JavaScript代码可能会用类似下面的方式获取当前的UTC时间:
var newTime = new Date().getTime();
在Python3和MongoDB那边,我们想使用真正的datetime
对象,所以我们用类似下面的方式进行转换:
datetime.datetime.utcfromtimestamp(jsMilliseconds / 1000)
但是当我们需要把日期时间发送回去时,Python3的对象只有一个timestamp()
方法。而通过这个方法来回转换似乎不能得到相同的时间。这让我们感到很沮丧。
我们希望能找到有经验的人给我们一些好的建议。我们在用JSON传递数据时,应该用字符串而不是毫秒整数吗?在两边之间转换时,有哪些推荐的方法?还是说我们应该继续使用整数,那我们又该用哪些方法呢?
1 个回答
处理时间的时候,有很多要求需要考虑。不过,如果你想要在用户的时区里显示日期和时间,并且使用mongo/python/java/javascript,我通常会使用ISO 8601的日期格式,并且总是存储UTC(协调世界时)时间。此外,如果你真的想要保留某个事件发生的实际时间,不仅需要存储“日期/时间”,还需要存储事件发生时的“时区”(比如IANA时区字符串)。
如果想深入了解,可以搜索“日期时间最佳实践”。这个回答对讨论有个很好的开端:夏令时和时区最佳实践
好了,现在来看代码(这些内容在网上搜索“解析||输出ISO 8601解析”都能找到,比如“python解析ISO 8601日期字符串”):
- JSON - 在JavaScript和Python后端之间传输一个复杂的对象(如果不需要保留时区,可以简单一些),包含ISO-8601格式的字符串和存储时区字符串的字符串:
{ "dateTime": "1970-07-10T12:00:00.047Z", "timeZone": "America/New_York" }
JavaScript
a. 读取日期时间字符串 JavaScript: 哪些浏览器支持解析ISO-8601日期字符串
var d = Date.parse("2011-04-26T13:16:50Z");
b. 写入日期时间字符串 如何在JavaScript中输出ISO 8601格式的字符串?
var date = new Date(); date.toISOString(); //"2011-12-19T15:28:46.493Z"
Python
a. 读取日期时间字符串 如何将ISO 8601日期时间字符串转换为Python日期时间对象?
import dateutil.parser yourdate = dateutil.parser.parse(datestring)
b. 写入日期时间字符串 Python - 将日期转换为ISO 8601
import dateutil.parser as parser date.isoformat()
- Mongo - 将日期时间存储为原生日期时间字段 http://docs.mongodb.org/manual/reference/mongodb-extended-json/#date
a. 存储日期时间字符串(注意“$date”和日期时间是以ZULU/UTC格式存储的(用'Z'表示)):
"dateTime" : { "$date" : "1970-07-10T13:00:00.047Z"}
参考资料:
1. IANA时区数据库http://en.wikipedia.org/wiki/Tz_database
2. Google日历API(事件资源)也可以作为RFC 3339的示例(见开始/结束):https://developers.google.com/google-apps/calendar/v3/reference/events