43
votes

I am trying to calculate the difference between two times using JavaScript. It's just basic math but I seem to have some issues with that while using JSON.stringify() and JSON.parse().

If you're wondering why am I applying the JSON.stringify() function to the date, it's because I using local storage to store some data on the client side and use it whenever the client lands on my website again ( it's faster that way rather than making more requests to the server ). That data usually updates once in a while ( I'm grabbing the data through API from another website ), so I set up a data_update variable and I'm storing it together with the other data.

That way I'm grabbing the stored data from the local storage and check if the difference between data_update ( which is a date / time ) and the time / date when the check it's made and see if it's greater than a week / day /etc .

So that is the reason why I'm using the JSON functions. My problem is that when I'm parsing the data from the local storage, the date seems to be different from a Date() object.

I'm trying to do the next operation per say :

var x = JSON.parse(JSON.stringify(new Date()));

var y = JSON.parse(this.get_local_storage_data(this.data_cache_key)); // the data object stored on local storage

var q = y.data_update; // this is the variable where the Date() was stored

console.log(Math.floor((x-q)/1000));

The above will return null. Also when I want to see the Math.floor(x) result, it returns null again.

So what can I do in this situation ? Is there a fix for this ?

3
You can avoid aggro like this by using a localStorage wrapper like rhaboo instead of stringify/parse which have many other inaccuracies besides this one.Adrian May

3 Answers

62
votes

If you look at the output of JSON.stringify for a Date, you'll see that:

JSON.stringify(new Date())

Results in a string. JSON does not have a primitive representation of Date objects that JSON.parse will turn back into a Date object automatically.

The Date object's constructor can take a date string, so you can turn those string values back into dates by doing:

var x = new Date(JSON.parse(JSON.stringify(new Date())));

Then the arithmetic will work.

x = new Date(JSON.parse(JSON.stringify(new Date())))
y = new Date(JSON.parse(JSON.stringify(new Date())))
y - x
=> 982
27
votes
JSON.stringify(new Date())

returns

"2013-10-06T15:32:18.605Z"

Thank God is: Date.prototype.toISOString()

0
votes

As the recommended answer suggests, the date is simply converted to a string when using JSON.stringify.

Another approach that would maybe fit this use case is to store the time in milliseconds using Date.now():

// Date.now() instead of new Date()
const millis = Date.now();

console.log(millis);

// same output as input
console.log(JSON.parse(JSON.stringify(millis)));

That way you can be sure that what goes into JSON.stringify comes out the same when using JSON.parse.

This also makes it easy to compare dates, if you have two millisecond values, using < and >.

Plus you can convert the milliseconds to a date at any time (usually before you render it to the user):

const millis = Date.now();

console.log(millis);

console.log(new Date(millis));

NOTE: using milliseconds as your date representation is usually not recommended, at least not in your database: https://stackoverflow.com/a/48974248/10551293.