8

When i create a javascript date and then stringify it and send it to the server, i get two different dates. The stringified date is always one day behind.

So currently i increment my javascript date by 1 day so that i receive the same date on the server.

my current code:

var dt = $(.datepicker).datepicker('getDate');//Fri Aug 26 2016 00:00:00 GMT+0200 (South Africa Standard Time)
var result = Json.stringify(dt); //"2016-08-25T22:00:00.000Z"

Is this the correct approach or am i missing something?

JustLearning
  • 3,164
  • 3
  • 35
  • 52
  • what is the content of `dt` and what is the output of `result`? – Guy Aug 26 '16 at 09:54
  • 1
    `i increment my javascript date by 1 day` - not a good way to do this - try it at a different time of day when UTC day is the same as your day - then look into libraries that have tried to overcome these issues ... dates are a pain in the backside for every programmer in every language :p – Jaromanda X Aug 26 '16 at 09:57
  • please verify your client and server is in same time zone – ciril sebastian Aug 26 '16 at 09:57
  • @guy i update the question, – JustLearning Aug 26 '16 at 09:58
  • @cirilsebastian how does this have any effect on my issue, as all processing is done on the client. When i check console and the server, the `ajax post` already contains the wrong date, and thus the server is receiving the wrong date – JustLearning Aug 26 '16 at 10:00
  • 1
    You don't seem to understand locale and UTC datetimes. – Xotic750 Aug 26 '16 at 10:02

3 Answers3

10

This is due to the timezone component in the Date. The work around I did was:

var date = $(.datepicker).datepicker('getDate');
var utcDate = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes()))
var result = Json.stringify(utcDate);

The removes the timezone component.

Arun Ghosh
  • 7,634
  • 1
  • 26
  • 38
  • You are going to end up with a inaccurate application going about it like this. – Xotic750 Aug 26 '16 at 10:11
  • @Xotic750, could you explain why and propose a solution – JustLearning Aug 29 '16 at 08:32
  • The datetime formats in your questions are the same datetime, just different timezones, one is GMT+2 and the other is UTC. So your server is already receiving the same datetime as your client. You need to explain why you believe or need to manually create a difference in the 2 dateimes.. – Xotic750 Aug 29 '16 at 08:52
  • THIS WILL FAIL FOR 1 JAN 2022, it will return 1 JAN 2021 – yash Jun 11 '21 at 05:11
2

You don't seem to understand that both of your datetimes are actually the same and are correct. You haven't explained why you think that you need to manually alter the one sent to the server. Here is an example that demonstrates that they are in fact the same, just displayed in different formats in different timezones.

// Values from the local datetime string
var local = {
  year: 2016,
  month: 7,
  day: 26,
  hours: 0,
  minutes: 0,
  seconds: 0,
  milliseconds: 0
};

// Values from the UTC ISO 8601 datetime string
var utc = {
  year: 2016,
  month: 7,
  day: 25,
  hours: 22,
  minutes: 0,
  seconds: 0,
  milliseconds: 0
};

// Create Date object as local
var date1 = new Date(
  local.year,
  local.month,
  local.day,
  local.hours,
  local.minutes,
  local.seconds,
  local.milliseconds
);

// Create Date object as local from UTC
var date2 = new Date(Date.UTC(
  utc.year,
  utc.month,
  utc.day,
  utc.hours,
  utc.minutes,
  utc.seconds,
  utc.milliseconds
));

var pre = document.getElementById('out');
// Display Date1 as local
pre.appendChild(document.createTextNode(date1.toString() + '\n'));
// Display Date2 as local
pre.appendChild(document.createTextNode(date2.toString() + '\n'));
// Display Date2 as UTC
pre.appendChild(document.createTextNode(date2.toUTCString() + '\n'));
// Test if Date1 and Date2 display the same datetime
pre.appendChild(document.createTextNode(
  'Date1 === Date2: ' + (date1.getTime() === date2.getTime())
));
<pre id="out"></pre>

JSON converts Date objects to ISO 8601 (by specification), but let's see what happens if you use the solution that you chose.

// Values from the local datetime string
var local = {
  year: 2016,
  month: 7,
  day: 26,
  hours: 0,
  minutes: 0,
  seconds: 0,
  milliseconds: 0
};

// Create Date object as local
var date = new Date(
  local.year,
  local.month,
  local.day,
  local.hours,
  local.minutes,
  local.seconds,
  local.milliseconds
);

// Your solution
var utcDate = new Date(Date.UTC(
  date.getFullYear(),
  date.getMonth(),
  date.getDate(),
  date.getHours(),
  date.getMinutes()));

var pre = document.getElementById('out');
// Display Date as local format
pre.appendChild(document.createTextNode(date.toString() + '\n'));
// Display utcDate as local format
pre.appendChild(document.createTextNode(utcDate.toString() + '\n'));
// Test if Date and utcDate display the same datetime
pre.appendChild(document.createTextNode(
  'Date1 === Date2: ' + (date.getTime() === utcDate.getTime())
));
<pre id="out"></pre>

You end up with 2 dates that are no longer the same. Don't like ISO 8601 for transmission and storage of datetimes? Well the alternative would be to use the number of milliseconds UTC since the epoch (getTime). You can't make JSON do this conversion instead of ISO 8601, not even using a replacer function. So any conversion would be necessary before using JSON.stringify. So you really need to explain what it is you are trying to achieve and why you think what you have now is incorrect.

Xotic750
  • 22,914
  • 8
  • 57
  • 79
-1

Use this

var result = Json.stringify(dt.toISOString());
  • isostring: YYYY-MM-DDTHH:mm:ss.sssZ <-- i think Z (Zulu) is considered a time zone (the same time zone as UTC, just a different name). – wazz Aug 26 '16 at 10:19
  • Please edit with more information. Code-only and "try this" answers are discouraged, because they contain no searchable content, and don't explain why someone should "try this". – abarisone Aug 26 '16 at 15:27