0

I know this is probably a question for ServerFault but I am having difficulty logging in.

I have an Ubuntu instance in the cloud running Nginx + PHP5-fpm.

I have set the timezone in php.ini to Asia/Singapore and verified it is set in phpinfo().

I have set the OS timezone using dpkg-reconfigure tzdata as well.

For some time, I've been having trouble with wrong dates set in my application. I initially thought this might be something I did in my PHP setup, so in my bootstrap script, I included:

date_default_timezone_set('Asia/Singapore');

Tried installing timezonedb via PECL as suggested in this post: Setting default timezone does not work despite timezone being valid

A user set date set on a webform still gets translated to "yesterday" when processed. I have tried both date() & gmdate() in PHP with the same results.

Edit

A little more information in case.

  1. User selects a date with jQuery DatePicker

  2. On form submission, I send the timestamp back to the server for PHP to process & store. I divide the timestamp by 1000 in PHP before storing.

    <?php $timestamp = (int) $_POST['birthday'] / 1000
    // this is received from a form.
    
  3. Upon echoing the date & timestamp,

        <?php echo date('dS F Y', (int) $timestamp);
         // when rendering to HTML...
         // computes to 13th April 1981
    
        //JS
        new Date(data.timestamp * 1e3).toString()
        // the exact same timestamp from earlier but received from server.
        // computes to Tue Apr 14 1981 23:30:00 GMT+0730 (SGT)
    

Any ideas?

Community
  • 1
  • 1
Jason J. Nathan
  • 7,422
  • 2
  • 26
  • 37

2 Answers2

0

Your clock is assumed to be in UTC/GMT, but the "humanising"/ conversion to a string adds the time zone offset. The HTTP header being in GMT will be on the original value. This is generally how Unix clocks work, it makes global traffic routing possible.

<?php

# my locale is configured for London
var_dump(time(), date('Y-m-d H:i:s'));

date_default_timezone_set('Asia/Singapore');
var_dump(time(), date('Y-m-d H:i:s')); # MySQL, locale
var_dump(time(), date('r')); # RFC 2822 
var_dump(time(), date('c')); # ISO 8601 

Your server is reporting the correct time in UTC. To fix, could you emit that header inside the PHP? This will override the first value...

header("Date: ".date('r', time()+8*60*60));

Edit

As you changed the question, more text response...

I think its necessary to confirm all the date-as-int operations are done with UTC/GMT time. If your user in in Singapore the time will be sent to the server in +8h offset. Are you transmitting as text or an int? All of the jQuery dates I have used return a string. If you unpack via strtotime(), it corrects the time offset.

The /1000 should have no computation significance, 8h = (60*60*8)s = 28800s which is >1000.

What does your client say for the timezone ~ gettimezoneoffset

It looks like one of the convert-to-int operations didn't remove the timezone offset.

Owen Beresford
  • 712
  • 4
  • 10
  • Thanks for the clarification, I suppose the HTTP header is not the problem then. Script still results in wrong time set. I'll update the question – Jason J. Nathan Aug 16 '13 at 01:47
0

There was a bug listed and patched in Ubuntu launchpad. timestamps are working after updating PHP. An excerpt of the bug:

[Impact]

A regression of timezone handling between Precise and Quantal means that PHP scripts that depend on the system timezone now use UTC instead. This breaks arbitrary PHP scripts - eg. cactus stops working as expected.

Not affected: 5.3.10-1ubuntu3.4 (Precise) Affected: 5.4.6-1ubuntu1 (Quantal) Not affected: 5.4.4-7 (sid)

Workaround: edit /etc/php5/*/php.ini, uncomment the "date.timezone" line and set it to what you need.

[Test Case]

  1. Set a timezone other than UTC using "dpkg reconfigure tzdata".
  2. $ php -r 'echo date_default_timezone_get()."\n";'

Expected results: system timezone (eg. "Europe/London")

Actual results: PHP Warning: date_default_timezone_get(): It is not safe to rely on the system's timezone settings. You are required to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in Command line code on line 1 UTC

(where in this case UTC is the system timezone).

Jason J. Nathan
  • 7,422
  • 2
  • 26
  • 37