简体   繁体   English

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

[英]Why does JSON.stringify screw up my datetime object?

{ 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' }

I have a JSON object with the "datetime" field like above. 我有一个带有“datetime”字段的JSON对象,如上所示。 It's perfect. 这是完美的。 But when I stringify it (I want to store it in cache), I get this format: 但是当我对其进行字符串化(我想将其存储在缓存中)时,我得到以下格式:

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

This causes problems, because when I want to JSON.parse this, suddenly it's no longer datetime format and it's incompatible with my other format. 这会导致问题,因为当我想要JSON.parse时,它突然不再是日期时间格式,而且与我的其他格式不兼容。

What can I do to solve this problem? 我该怎么做才能解决这个问题? I have 'created_at' littered everywhere throughout my application. 在我的应用程序中,我的'created_at'遍布各处。 I don't want to manually change each one. 我不想手动更改每一个。

It is actually possible to modify how a Date object will be serialized into JSON. 实际上可以修改Date对象如何序列化为JSON。 Combined with the reviver function, a bi-directional solution can be created which will automatically work on serialization and can easily be used on deserialization. 结合reviver功能,可以创建一个双向解决方案,该解决方案将自动处理序列化,并且可以轻松地用于反序列化。

First modify the serialization like this: 首先像这样修改序列化:

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

This will change the representation of a Date object into a UNIX timestamp with a prefix as a marker: 这会将Date对象的表示形式更改为带有前缀作为标记的UNIX时间戳:

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

Then you can create a reviver function which will automatically filter out these values: 然后你可以创建一个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;
}

(Credit: This code was basically copied from this answer in a related question: https://stackoverflow.com/a/14509447/2572897 ) (信用:此代码基本上是从相关问题的答案中复制而来的: https//stackoverflow.com/a/14509447/2572897

Now with this setup, deserialization of our result from before will result in a Date object again: 现在使用此设置,从之前反序列化我们的结果将再次导致Date对象:

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

Or you can choose not to modify the serialization but instead use the regexp to catch the standard serialization format: 或者您可以选择不修改序列化,而是使用正则表达式来捕获标准序列化格式:

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;
}

Example: 例:

> 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)}

There is not special way to serialize Date objects in JSON. 没有特殊的方法来在JSON中序列化Date对象。 That's why you get the standardized string representation. 这就是你获得标准化字符串表示的原因。 You need to convert them back to Date objects by passing them to the Date constructor. 您需要通过将它们传递给Date构造函数将它们转换回Date对象。

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

Update: With the reviver function (see comments), you can get the Date objects back. 更新:使用reviver功能(请参阅注释),您可以返回Date对象。

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

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

You can read more about moment documentation and tailor type of date you want to return. 您可以阅读有关时刻文档的更多信息,并定制您想要返回的日期类型。

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 https://weblog.west-wind.com/posts/2014/Jan/06/JavaScript-JSON-Date-Parsing-and-real-Dates

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM