为什么JSON.stringify搞砸了我的日期时间对象?

时间:2012-02-08 13:36:50

标签: javascript string json node.js

{ id: 1533,
  story_type_id: 1,
  content_id: 470,
  created_at: Sun, 05 Feb 2012 07:02:43 GMT,
  updated_at: Sun, 05 Feb 2012 07:02:43 GMT,
  type_name: 'post' }

我有一个带有“datetime”字段的JSON对象,如上所述。这是完美的。但是当我对其进行字符串化时(我想将其存储在缓存中),我得到了这种格式:

"created_at":"2012-02-05T07:02:43.000Z"

这会导致问题,因为当我想要JSON.parse时,它突然不再是日期时间格式,而且与我的其他格式不兼容。

我该怎么做才能解决这个问题?在我的应用程序中,我的'created_at'遍布各处。我不想手动更改每一个。

4 个答案:

答案 0 :(得分:13)

在JSON中没有特殊的方法来序列化Date个对象。这就是你获得标准化字符串表示的原因。您需要通过将它们传递给Date构造函数将它们转换回Date个对象。

item['created_at'] = new Date(item['created_at']);

更新:使用reviver功能(请参阅注释),您可以恢复Date个对象。

var item = JSON.parse(row, function (key, value) {
  if (key === 'created_at') {
    return new Date(value);
  } else {
    return value;
  }
});

答案 1 :(得分:13)

实际上可以修改Date对象如何序列化为JSON。结合reviver功能,可以创建一个双向解决方案,该解决方案将自动用于序列化,并且可以轻松用于反序列化。

首先像这样修改序列化:

Date.prototype.toJSON = function() { return "{timestamp}+" . this.getTime() }

这会将Date对象的表示形式更改为带有前缀作为标记的UNIX时间戳:

> json = JSON.stringify({test:new Date()});
"{"test":"{timestamp}1380164268633"}"

然后你可以创建一个reviver函数,它会自动过滤掉这些值:

function json_deserialize_helper(key,value) {
  if ( typeof value === 'string' ) {
    var regexp;
    regexp = /^{timestamp}(\d*)$/.exec(value);
    if ( regexp ) {
      return new Date(+regexp[1]);
    }
  }
  return value;
}

(信用:此代码基本上是从相关问题的答案中复制而来的:https://stackoverflow.com/a/14509447/2572897

现在使用此设置,我们的结果从之前反序列化将再次导致Date对象:

> JSON.parse(json, json_deserialize_helper);
Object {test: Thu Sep 26 2013 04:57:48 GMT+0200 (CEST)}

或者您可以选择不修改序列化,而是使用regexp来捕获标准序列化格式:

function json_deserialize_helper(key,value) {
  if ( typeof value === 'string' ) {
    var regexp;
    regexp = /^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d.\d\d\dZ$/.exec(value);
    if ( regexp ) {
      return new Date(value);
    }
  }
  return value;
}

示例:

> json = JSON.stringify({test:new Date()})
"{"test":"2013-09-26T03:05:26.563Z"}"
> JSON.parse(json, json_deserialize_helper)
Object {test: Thu Sep 26 2013 05:05:26 GMT+0200 (CEST)}

答案 2 :(得分:0)

Date.prototype.toJSON = function(){return moment(this).format('L'); }

您可以阅读有关时刻文档的更多信息,并定制您想要返回的日期类型。

答案 3 :(得分:0)

var date = new Date();
console.log(date);//Mon Jun 11 2018 10:14:33 GMT+0430 (Iran Daylight Time)
var json = JSON.stringify(date);
console.log(json);//"2018-06-11T05:44:33.590Z"
var dateStr = JSON.parse(json);  
console.log(dateStr);//2018-06-11T05:44:33.590Z
var date = new Date(dateStr);
console.log(date);//Mon Jun 11 2018 10:14:33 GMT+0430 (Iran Daylight Time)

https://weblog.west-wind.com/posts/2014/Jan/06/JavaScript-JSON-Date-Parsing-and-real-Dates