在Nodejs中将MongoDB返回的JSON数组中的UTCdate转换为本地时间的有效方法

我正在使用Node.js查询MongoDB,并有一个date(ISODate)的字段。 在查询返回的date格式后,在Node.js中看起来像这样

DT : 2014-10-02T02:36:23.354Z 

我想弄清楚如何基于我下面的代码,可以有效地将DT字段从UTC时间转换为本地时间ISOString。 换句话说,如果当地时间是美国东部时间这样的东西

 DT : 2014-10-02T23:36:23.354Z 

我不认为在Mongo的查询中我可以做任何事情。 我应该遍历Array结果集并手动更改date吗? 这里有更好的方法吗? 我正在向HTTP客户端发送响应。

 collection.find(query,options).toArray(function (err, items) { if (err) { logAndSendDebugError(500, "Error issuing find against mongo Employees Collection -" + type, res); } else { var response = { 'type': type, 'employees': items }; res.jsonp(response); } }); 

我会认为处理客户端和服务器之间date的最有效方法是使用EJSON包。 这包括了一些在其他讨论中避开的东西,重要的是在处理JSON转换时保持“types保真度”。

所以你现在正在得到的是一个“string”的结果,从“date”对象调用响应一个JSON.stringify调用。 无论使用什么方法,这基本上是从“Date”原型中调用.toJSON()方法的地方。

EJSON包可以调用EJSON.stringify而不是用原型或其他手工处理覆盖,而是调用EJSON.stringify而不是用一些内置的行为来保存types,特别是生成的JSONstring对于Date元素来说看起来像这样:

 { "myCreatedDate": { "$date": 1412227831060 } } 

这个值有一个纪元时间戳,基本上是从.valueOf()原型方法获得的,但是这个字段被自动赋予一个特殊的结构。 date以外的types也是如此。

您可以添加简单的相应的“客户端”处理包括在浏览器中的Web应用程序,例如:

 <script src="components/ejson/base64.js"></script> <script src="components/ejson/ejson.js"></script> 

这允许存在相同的EJSON对象,您可以使用EJSON.parse处理接收到的JSON。 当反序列化完成后,生成的JavaScript对象被维护为“date”types。

 var obj = EJSON.parse( "{ \"myCreatedDate\": { \"$date\": 1412227831060 } }" ); { myCreatedDate: /* Actually a Date Object here */ } 

所以现在在你的客户端浏览器中,你有一个真正的date对象,没有任何其他处理。 在该对象上调用的任何.toString()方法将导致以与该客户端的当前语言环境设置相匹配的方式表示的值。

因此,如果您使用这种方式在服务器和客户端之间传递值,以维持实际的“Date”对象,则正确的Object值将保留在客户端和服务器上,不需要进一步转换。

包含在您的项目中非常简单,并且需要大量时间维护“时区”转换。 试一试。

值得注意的是,这个“核心”来自扩展JSON语法的MongoDB规范。 因此,除了EJSON包中的这个(部分)实现之外,几个MongoDB工具以及几个具有自定义JSONparsing器的驱动实现都支持相同的“types标识符”,JSONparsing器将自动转换types。 值得注意的是,Java和C#驱动程序具有与驱动程序库一起提供的此function。

遵循该链接中概述的惯例是相当容易的,并且也打算“映射”到BSONtypes规范。 最糟糕的是,你总是可以从标准JSONparsing器中“检查”结果,并实现自定义例程来“重新实例化”“types”。 但是如前所述,这个软件已经有了几个库。

在ES5中, Date.parse应该能够parsing这种格式,但是它不可靠。 手动parsing并不困难:

 // Parse ISO 8601 UTC string like 2014-10-02T23:36:23.354Z function parseISOUTC(s) { var b = s.split(/\D/); return new Date(Date.UTC(b[0], --b[1], b[2], b[3], b[4], b[5], b[6])); } 

创build的date实例将具有根据系统设置计算的本地时区偏移量。 要从本地date获取UTC ISO 8601string,可以使用toISOString

 var date = new Date(); console.log(date.toISOString()); 

请注意, toISOString是ES5,所以如果在旧版本的浏览器中使用,可能需要使用polyfill。 请参阅MDN Date.prototype.toISOString()