Javascript 将Nodejs中MongoDB返回的JSON数组中的UTC日期转换为本地时间的有效方法

Javascript 将Nodejs中MongoDB返回的JSON数组中的UTC日期转换为本地时间的有效方法,javascript,json,node.js,mongodb,Javascript,Json,Node.js,Mongodb,我使用Node.js查询MongoDB,并有一个日期为ISODate的字段。在Node.js中,查询返回的日期格式后如下所示 DT : 2014-10-02T02:36:23.354Z DT : 2014-10-02T23:36:23.354Z 我想弄清楚的是,根据下面的代码,如何有效地将DT字段从UTC转换为本地时间字符串。换句话说,如果当地时间是美国东部夏令时,那么类似的事情 DT : 2014-10-02T02:36:23.354Z DT : 2014-10-02T23:36:23.

我使用Node.js查询MongoDB,并有一个日期为ISODate的字段。在Node.js中,查询返回的日期格式后如下所示

DT : 2014-10-02T02:36:23.354Z
DT : 2014-10-02T23:36:23.354Z
我想弄清楚的是,根据下面的代码,如何有效地将DT字段从UTC转换为本地时间字符串。换句话说,如果当地时间是美国东部夏令时,那么类似的事情

DT : 2014-10-02T02:36:23.354Z
DT : 2014-10-02T23:36:23.354Z
我不认为在Mongo的查询中我能做什么。我应该遍历数组结果集并手动更改日期吗?这里有更好的方法吗?我正在将响应发送到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);
           }
 });
在ES5中,Date.parse应该能够解析该格式,但是它不可靠。手动解析并不困难:

// 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]));
}
创建的日期实例将具有根据系统设置计算的本地时区偏移量。要从本地日期获取UTC ISO 8601字符串,可以使用:

请注意,toISOString是ES5,因此如果在较旧的浏览器中使用,则可能需要polyfill。请参阅ES5中的。

,Date.parse应该能够解析该格式,但它不可靠。手动解析并不困难:

// 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]));
}
创建的日期实例将具有根据系统设置计算的本地时区偏移量。要从本地日期获取UTC ISO 8601字符串,可以使用:


请注意,toISOString是ES5,因此如果在较旧的浏览器中使用,则可能需要polyfill。请参阅。

我认为处理客户端和服务器之间日期的最有效方法是使用包。这涵盖了在这里的其他讨论中忽略的一些事情,重点是在处理JSON转换时保持类型保真度

因此,您现在得到的是一个字符串的结果,该字符串是响应JSON.stringify调用从Date对象调用的。无论使用什么方法,这本质上就是从日期原型调用.toJSON方法时发生的情况

EJSON包允许您调用EJSON.stringify,它具有一些内置的行为来保留类型,其中生成的JSON字符串对于日期元素具体如下所示:

{ "myCreatedDate": { "$date": 1412227831060 } }
其中的值有一个历元时间戳,基本上是从.valueOf prototype方法中获得的,但是该字段被自动赋予了一个特殊的结构。对于日期以外的类型也是如此

可以使用simple添加到浏览器中web应用程序的相应客户端处理,例如:

这允许存在相同的EJSON对象,您可以使用EJSON.parse处理接收到的JSON。反序列化完成后,生成的JavaScript对象将作为日期类型进行维护

var obj = EJSON.parse( "{ \"myCreatedDate\": { \"$date\": 1412227831060 } }" );

{
    myCreatedDate: /* Actually a Date Object here */
}
因此,现在在客户端浏览器中,您拥有了一个真实的日期对象,而无需任何其他处理。对该对象调用的任何.toString方法都将生成一个值,该值的表示方式与该客户端的当前语言环境设置相匹配

因此,如果您使用此方法在服务器和客户端之间传递值,以维护实际的日期对象,则在客户端和服务器上都会维护正确的对象值,无需进一步转换

将其包含在项目中非常简单,并且需要大量的繁重工作来维护时区转换。试试看

可能值得注意的是,它的核心来自的MongoDB规范。因此,除了EJSON包中的这个部分实现之外,在几个MongoDB工具中以及在几个驱动程序实现中都支持相同的类型标识符,这些驱动程序实现具有一个自定义JSON解析器,该解析器将自动转换类型。值得注意的是,Java和C驱动程序具有驱动程序库附带的这种功能


遵循该链接中概述的约定是相当容易的,并且它还打算映射到BSON类型规范。在最坏的情况下,您总是可以检查标准JSON解析器的结果,并实现自定义例程来重新实例化类型。但是正如前面提到的,这个软件已经有了几个库。

我认为处理客户机和服务器之间日期的最有效方法是使用这个包。这涵盖了在这里的其他讨论中忽略的一些事情,重点是在处理JSON转换时保持类型保真度

因此,您现在得到的是一个字符串的结果,该字符串是响应JSON.stringify调用从Date对象调用的。无论使用什么方法,这本质上就是从日期原型调用.toJSON方法时发生的情况

EJSON包允许您调用 相反,EJSON.stringify具有一些内置行为来保留类型,其中生成的JSON字符串对于日期元素如下所示:

{ "myCreatedDate": { "$date": 1412227831060 } }
其中的值有一个历元时间戳,基本上是从.valueOf prototype方法中获得的,但是该字段被自动赋予了一个特殊的结构。对于日期以外的类型也是如此

可以使用simple添加到浏览器中web应用程序的相应客户端处理,例如:

这允许存在相同的EJSON对象,您可以使用EJSON.parse处理接收到的JSON。反序列化完成后,生成的JavaScript对象将作为日期类型进行维护

var obj = EJSON.parse( "{ \"myCreatedDate\": { \"$date\": 1412227831060 } }" );

{
    myCreatedDate: /* Actually a Date Object here */
}
因此,现在在客户端浏览器中,您拥有了一个真实的日期对象,而无需任何其他处理。对该对象调用的任何.toString方法都将生成一个值,该值的表示方式与该客户端的当前语言环境设置相匹配

因此,如果您使用此方法在服务器和客户端之间传递值,以维护实际的日期对象,则在客户端和服务器上都会维护正确的对象值,无需进一步转换

将其包含在项目中非常简单,并且需要大量的繁重工作来维护时区转换。试试看

可能值得注意的是,它的核心来自的MongoDB规范。因此,除了EJSON包中的这个部分实现之外,在几个MongoDB工具中以及在几个驱动程序实现中都支持相同的类型标识符,这些驱动程序实现具有一个自定义JSON解析器,该解析器将自动转换类型。值得注意的是,Java和C驱动程序具有驱动程序库附带的这种功能


遵循该链接中概述的约定是相当容易的,并且它还打算映射到BSON类型规范。在最坏的情况下,您总是可以检查标准JSON解析器的结果,并实现自定义例程来重新实例化类型。但是,正如前面提到的,这个软件已经有了几个库。

这里唯一需要注意的是,如果JSON被其他系统使用,它们可能不知道如何处理$date。最好将其命名为timevalue或类似名称。但这不在这里-@罗布为它的价值增加了一点信息。实际上,这是建立在一个规范之上的,所以它不仅仅是一个独立的想法。还有其他语言平台的现有库。如果您试图存储以$date开头的密钥,MongoDB本身会大声抱怨,因为它被认为是保留的。感谢您提供的额外信息。这里唯一的警告是,如果JSON被其他系统使用,他们可能不知道如何处理$date。最好将其命名为timevalue或类似名称。但这不在这里-@罗布为它的价值增加了一点信息。实际上,这是建立在一个规范之上的,所以它不仅仅是一个独立的想法。还有其他语言平台的现有库。如果您试图存储以$开头的密钥,MongoDB本身会大声抱怨,因为它被认为是保留的。谢谢您提供的额外服务。