38

I send this date from my controller in java (Spring-MVC) the type in mysql is datetime

@Temporal(TemporalType.TIMESTAMP) 
@Column(name = "..") public Date getYy() { 
    return this.yy; 
}

as : [2015-09-30 00:00:00.0]

When i get this dates with ajax as 1443567600000 :

new Date(1443567600000) convert to Tue Sep 29 2015 23:00:00 GMT+0000 (Maroc)

So why i get wrong date off by one hour?

SOLUTION

We resolve it by

d = new Date(value) ;
d.setTime( d.getTime() + d.getTimezoneOffset()*60*1000 );

because it was Daylight saving time (DST) or summer time problem. good article

mike rodent
  • 14,126
  • 11
  • 103
  • 157
Hayi
  • 6,972
  • 26
  • 80
  • 139

4 Answers4

10

I think maybe this is a Daylight Saving Time problem. You can check your client's timezone, and your server's timezone. (web server or SQL Server)

Crazy Crab
  • 694
  • 6
  • 16
  • 2
    But how can i solve my problem whatever the client's timezone is ? – Hayi Sep 09 '15 at 09:46
  • 1
    You can read this [article](http://stackoverflow.com/questions/1091372/getting-the-clients-timezone-in-javascript) – Crazy Crab Sep 09 '15 at 09:51
  • 7
    thanks man it was a summer time (DSL) problem so we resolve it like this `d = new Date(value) ; d.setTime( d.getTime() - new Date().getTimezoneOffset()*60*1000 );` – Hayi Sep 09 '15 at 20:47
  • 1
    @Youssef your solution doesn't *seem* to be quite right. `new Date()` will give you the datetime **now**, not at `d`. So you have to go `d.getTimezoneOffset()*60*1000` ... I think. – mike rodent Aug 27 '17 at 18:22
9

This JS handling of Date is a quite a head-flip.

I'm in the UK... "easy" because we're on GMT (UTC)... except during the summer months, when there's DST (British Summer Time, BST). Clocks go forward in summer and back in winter (stupidly by the way, but that's another issue!) by one hour. One day in March what is 4pm GMT is now called 5pm (BST).

summer month:

If you do new Date( '2017-08-08' ) this will give you (toString) 'Date 2017-08-08T00:00:00.000Z'.

If you do new Date( '2017-08-08 00:00' ), however, this will give you 'Date 2017-08-07T23:00:00.000Z'!

In the second case it appears JS is trying to be "helpful" by assuming that because you stipulated the hour you were specifying BST time. So it adjusts to GMT/UTC. Otherwise it doesn't... though (of course) it still produces a Date object which is specific right down to the milliseconds. Quite a gotcha!

Confirmation: a winter month... when BST is not applied: new Date( '2018-01-01 00:00' )/ new Date( '2018-01-01' ): both give 'Date 2018-01-01T00:00:00.000Z'

As for adjusting, it appears that to undo the automatic adjustment you just go

jsDate.setTime( jsDate.getTime() + jsDate.getTimezoneOffset() * 60 * 1000 );

... this is a bit like what Youssef has written... except you have to obtain the offset from the specific Date in question... and my experiments seem to prove that you add this, not subtract it.

Really it would be much more helpful if the default string representation of JS Date gave the UTC time followed by the TZ (time zone) offset information, as with some of the ISO date formats: clearly, this information is included.

mike rodent
  • 14,126
  • 11
  • 103
  • 157
  • Would that explain why "2020-01-01 00:00" shows "2019-12-31 23:00" ? somehow on my app the dates shows the one hour late version (it's disturbing seeing a truthy comparison even though the log at first doesn't show it) so equivalent to .toISOString() yet using my browser console I get the toString() format when console logging the date ? – adaba Apr 21 '21 at 16:07
5

We should probably need more data about it, but it could be that nothing is wrong here, it depends how you set and get back your date.

Basically 1443567600000 doesn't contains timezone. It represent Tue Sep 29 2015 23:00:00 from Greenwich. It's a moment in time that, of course, it different from any location that has a different timezone. The same moment, happens at different time (the midnight of GMT+1 is the 11pm of GMT).

You have to store both the time and the timezone in your DB, and possibly send back to JS, otherwise it will be always interpreted differently depends by the local time of the client.

To make an example:

var d = new Date(2015, 8, 30);
console.log(d.toJSON()); // In my case I got "2015-09-29T22:00:00.000Z"
console.log(d.toDateString()); // "Wed Sep 30 2015"
ZER0
  • 24,846
  • 5
  • 51
  • 54
5

To be more specific

 time = new Date("2018-06-01 " + time);
            var offset = time.getTimezoneOffset();
            offset = Math.abs(offset / 60);
            time.setHours(time.getHours() + offset);

in this case time is equal to hours with leading zeros:minutes with leading zeros. This will add the hours difference to the UTC. If you pass a string to date it is treated as UTC.

Daniel Santos
  • 429
  • 5
  • 15