Backstory I've been beating my head for a week trying to simply store and resume scheduling dates in JS. To save dates between sessions I need to use Stringify to offload a single string to be saved as a variable. I am programming JS in a custom engine (Barco's Medialon) that does not allow includes or standard I/O. So everything has to work in this one block of code with small things not being standard or needing workarounds.
The problem This JSON stringify command stores date objects in a standard format "2019-03-05T09:20:00.000Z" This particular JSON parsing//new Date() command, however, can not interpret that string format and creates an error of "Invalid Date". Other formats do work though, IE when I invoke a new Date(Epoch Time) or new Date(YYYY,MM,DD,hh,mm)
The Quest I am trying to modify the stringify/parse sections to work around this issue though I am struggling. While I have a small handle on the 'JSON.parse' and regex bit, Trying to manipulate the detection of Date Object and changing how it encodes is a quest in futility thus far.
Object structure getting Stringified
{
"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": []
}
I have tried the following strigify manipulation:
var currentEvents = JSON.stringify(this.Events, function(key,value) {
if (value instanceof Date){
return value.getTime();
}
return value;
});
The above however, does not detect the Date Object. If I use (typeof value === 'object')
it activates on far too much.
On the other side, here is the non-working for this engine (but works everywhere else!) code
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;
});
The goal I need to find a solution to work around the limitations of this engine that allows me to detect and convert a Date to a string during the JSON.stringify process in an alternate form that also allows the JSON.Parse function to detect and import it back as a Date object
In the JSON.parse
callback, you could call Date.UTC
with 7 arguments, and pass the resulting epoch value to the Date
constructor, like so:
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]));
This assumes that the stringified date uses the UTC format with the "Z" timezone indication. This is what JSON.stringify
produces for dates.
Demo:
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
solutionIf instanceof Date
does not work, then you could test the presence of a Date
prototype method:
if (Object(value).getTime) {
return value.getTime();
}
However, in the parsing phase you would have trouble to distinguish such epoch numbers from other numerical values; you would have no good indication whether the number should be converted to a Date
...