当自定义引擎不接受规范时,JSON Parse and Stringify for Dates 中是否有解决方法

Is there a workaround in JSON Parse and Stringify for Dates when a custom engine doesn't accept the norm

背景故事 一个星期以来,我一直在绞尽脑汁试图在 JS 中简单地存储和恢复计划日期。为了保存会话之间的日期,我需要使用 Stringify 卸载单个字符串以保存为变量。我在不允许包含或标准 I/O 的自定义引擎(Barco 的 Medialon)中对 JS 进行编程。所以一切都必须在这一块代码中工作,小事情不是标准的或需要变通办法。

问题这个JSON stringify命令以标准格式“2019-03-05T09:20:00.000Z”存储日期对象这个特定的JSON parsing//new Date() 命令,但是,无法解释该字符串格式并产生 "Invalid Date" 错误。其他格式确实有效,IE 当我调用新日期(大纪元时间)或新日期(YYYY、MM、DD、hh、mm)时

The Quest 我正在努力修改 stringify/parse 部分以解决此问题,尽管我正在努力。虽然我对 'JSON.parse' 和正则表达式位有一点了解,但迄今为止,尝试操纵日期对象的检测并更改它的编码方式是徒劳的。

对象结构字符串化

{
  "daily": "",
  "special": [
    {
      "startDTG": "2019-03-05T09:20:00.000Z", // <- Without modifying the default stringify it gives this
      "endDTG": "2019-03-06T09:20:00.000Z",
      "mode": "0"
    }
  ],
  "current": {},
  "startup": [],
  "shutdown": []
}

我尝试了以下 strigify 操作:

        var currentEvents = JSON.stringify(this.Events, function(key,value) {
            if (value instanceof Date){             
                    return value.getTime();         
            }
            return value;
        });

然而,上面没有检测到日期对象。如果我使用 (typeof value === 'object') 它会激活太多。

另一方面,这是不适用于此引擎的代码(但在其他任何地方都适用!)代码

eventLoad = JSON.parse(eventSTR, function (key, value) {
            var reISO = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*))(?:Z|(\+|-)([\d|:]*))?$/;
                if (typeof value === 'string' && reISO.test(value)){                
                    return new Date(value);  //value.slice(0,-5));              
            }
            return value;
        });

目标 我需要找到一个解决方案来解决此引擎的限制,使我能够在 JSON.stringify 期间检测日期并将其转换为字符串以另一种形式处理,该形式还允许 JSON.Parse 函数检测并将其作为 Date 对象导入回

您正在尝试全部手动完成,但已经有处理所有这些转换的方法。

ISO 日期: https://www.w3schools.com/jsref/jsref_toisostring.asp

ISO 迄今为止: Convert ISO Date to Date Format yyyy-mm-dd format in javascript

特别是 :00.000Z 格式请看这个答案:

Moment.js 对于这种事情来说也是一个很好的节省时间的方法:http://momentjs.com/

JSON.parse 回调中,您可以使用 7 个参数调用 Date.UTC,并将生成的纪元值传递给 Date 构造函数,如下所示:

var p = value.match(/\d+/g);
return new Date(Date.UTC(p[0],p[1]-1,p[2],p[3],p[4],p[5],p[6]));

这假定字符串化日期使用带有 "Z" 时区指示的 UTC 格式。这是 JSON.stringify 为日期生成的结果。

演示:

var event = {
    dt: new Date()
};
console.log("input:");
console.log(event);
var eventSTR = JSON.stringify(event);
console.log("stringified:");
console.log(eventSTR);
var reISO = /^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\.\d+Z$/;
var result = JSON.parse(eventSTR, function (key, value) {
    if (typeof value === 'string' && reISO.test(value)) {
        var p = value.match(/\d+/g);
        return new Date(Date.UTC(p[0],p[1]-1,p[2],p[3],p[4],p[5],p[6]));
    }
    return value;
});
console.log("parsed:");
console.log(result);

关于stringify解决方案

如果 instanceof Date 不起作用,那么您可以测试 Date 原型方法的存在:

if (Object(value).getTime) {
    return value.getTime();
}

但是,在解析阶段,您很难将这些纪元号与其他数值区分开来;您没有很好的指示是否应将数字转换为 Date...