0

In an Symfony/Angular project, i use a datepicker (Bootstrap datepicker) to select a date. This gives me an object value i then want to send to php to be persisted.

The problem is there is an time offset giving me the wrong value in the database.

I'm in a french setup, i've defined in php.ini the correct timezone.

  • In the datepicker, i choose : 17/11/2016 which is translated in Thu Nov 17 2016 00:00:00 GMT+0100 (CET)
  • but when i send to php with ajax call : i have 2016-11-16T23:00:00.000Z php side
  • then in my Db with doctrine, the datetime field contains : 2016-11-16 23:00:00
  • When i want to display back the saved values, it naturally gives in the datepicker : 16/11/2016 which is in fact if i do a console.log() : {"date":"2016-11-16 23:00:00.000000","timezone_type":3,"timezone":"Europe/Paris"}

I don't use any conversion in the process. I did try to "cast" the js : start.toUTCString(), i also tried to set afterward the time to 0 in php : $start.setTime(0, 0, 0); without success.

So, how can i save and display the correct date ?

Overdose
  • 585
  • 7
  • 30
  • Keep an eye on this part `GMT+0100`, its all about timezones on server/client side – JustOnUnderMillions Nov 16 '16 at 14:12
  • 1
    The short answer? **DON'T**. Always, *always* work in Zulu time. Timezones are for users, not data. You will experience nothing but pain if you plot any other course. – Jared Smith Nov 16 '16 at 14:13
  • @JustOnUnderMillions : i figured so, but then how can i send a js date to php with no timezone problem ? – Overdose Nov 16 '16 at 14:21
  • Look here, all sayed before: http://stackoverflow.com/questions/18124462/how-to-deal-with-timezones-between-server-and-client or take another answer from SO – JustOnUnderMillions Nov 16 '16 at 14:21
  • http://stackoverflow.com/questions/1638337/the-best-way-to-synchronize-client-side-javascript-clock-with-server-date just google a little – JustOnUnderMillions Nov 16 '16 at 14:23
  • @JaredSmith : "The short answer? DON'T." don't what ? don't use timezone ? but then in which format would you save a date in DB ? how would you juggle back and forth that date with js/php ? – Overdose Nov 16 '16 at 14:24
  • You're problem is that you are converting the Zulu date string you are getting from JavaScript into the Paris timezone *without adjusting the hour/date for the offset*. Rather than trying to convert it correctly, just don't convert it at all. Your JavaScript and PHP look correct, I'd suspect the DB as culprit. `2016-11-16T23:00:00.000Z === Thu Nov 17 2016 00:00:00 GMT+0100 (CET)`, but neither is equal to `{"date":"2016-11-16 23:00:00.000000","timezone_type":3,"timezone":"Europe/Paris"}`. – Jared Smith Nov 16 '16 at 14:35
  • @JaredSmith if the data is not properly saved in MySQL, what format would you suggest ? I'm using datetime. Should i use timestamp ? I'm using Doctrine which has a datetimetz format, but this is not usable in MySQL ... – Overdose Nov 16 '16 at 14:39
  • Hard for me to say, as I use postgresql and don't really know mysql, but I know how dates work and I can tell you that the one you have in PHP before you write to your store is not the same one you're reading back out. You'll have to dig through the relevant docs. I would edit the question and change the title to reflect that its a doctrine/mysql question rather than a JavaScript/PHP question. – Jared Smith Nov 16 '16 at 14:41

1 Answers1

0

Here is my tip:

Whenever you work with timestamps use epoch timestamp. The epoch timestamp (unix timestamp) begins from Jan 01st 1970 and is calculated in seconds (for most cases). So for example today would be (16th November 2016):

1479307079 seconds since Jan 01 1970. (UTC)

Now you can save that value to a database or an object which you can give through to JavaScript or back to PHP depends from where that value comes.

To display the correct time you can and should use momentJS as long as you are in a JavaScript enviroment.

Why momentJS?

You do not have to worry about timezones, momentJS is doing the work for you:

moment().format();     // 2013-02-04T10:35:24-08:00
moment.utc().format(); // 2013-02-04T18:35:24+00:00

You can parse unix timestamps (seconds or milliseconds) into moment objects and work with them:

let day = moment.unix(1318781876); // will display only the day

You can convert current dates into epoch timestamps too so you can go the way back in reverse and save values from user input like your datepicker. Here are the docs to momentJS.


Beware of the Year 2038 problem!

The Year 2038 problem is an issue for computing and data storage situations in which time values are stored or calculated as a signed 32-bit integer, and this number is interpreted as the number of seconds since 00:00:00 UTC on 1 January 1970 ("the epoch"). [...]

Read more: https://en.wikipedia.org/wiki/Year_2038_problem

In short: you are safe to use epoch timestamps until:

19th January 2038 03:14:07 UTC 

Hope this helps.

Regards, Megajin

Megajin
  • 2,648
  • 2
  • 25
  • 44