Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript/PHP and timezones

I'd like to be able to guess the user's timezone offset and whether or not daylight savings is being applied. Currently, the most definitive code that I've found for this is here:

http://www.michaelapproved.com/articles/daylight-saving-time-dst-detect/

So this gives me the offset along with the DST indicator.

Now, I want to use these in my PHP scripts in order to ouput the local date/time for the user....but what's best for this? I figure I have 2 options:

a) Pick a random timezone which has the same offset and DST setting from the output of timezone_abbreviations_list(). Then call date_timezone_set() with this in order to apply the correct treatment to the time.

b) Continue treating the date as UTC but just do some timestamp addition to add the appropriate number of hours on.

My feeling is that option B is the best way. The reason for this is that with A, I could be using a timezone which although correct in terms of offset/dst, may have some obscur rules in place behind the scene that could give surprising results (I don't know of any but nonetheless I don't think I can rule it out).

I'd then re-check the timezone using Javascript at the start of each session in order to capture when either the user's timezone changes (very unlikely) or they pass in to the DST period.

Sorry for the brain dump - I'm really just after some sort of reassurance that the approaches above are valid.

Thanks,

James.

like image 373
James Avatar asked Feb 23 '10 15:02

James


3 Answers

To robustly determine a user's timezone using javascript. Check out jsTimezoneDetect.

It will give you an Olsen timezone database key that you can use for server side datetime calculations.

like image 130
Jon Nylander Avatar answered Sep 30 '22 13:09

Jon Nylander


If this is a poll, then "b" is my vote.

Firstly, all times should be stored in UTC. This is dogma. It's very sensible dogma, the kind about which you end up saying "I sure wish I had followed that," after your project gets more complicated. Among other things, it is the only unambiguous, consistent way to store all points in time. Any timezone with daylight savings time has ambiguous time references around the switch (1:30 am usually happens twice, for example). Also, when converting between timezones, most of the time you end up using UTC as an intermediary anyway.

Second of all, you have to decide whether your site is international or not. If not, then you make rules for the six U.S. time zones and end it. With three browsers reporting timestamps in their own whacky ways, that's still only 18 cases, and it should be possible to handle them. Anything beyond that, and you should assume that it requires an advanced degree to anticipate daylight savings time differences. The times switch on different days in different places.

Your biggest problem with b is that, if this is a calendar-like application, scheduling will still be an issue if you can't accurately determine what time zone someone is in. For example, suppose it's February. No one is on DST. Someone schedules something for 6pm (local) on May 5. You see the offset is UTC-4. How do you know whether that person is in New Brunswick, which observes DST (in which case the time meant is 2100 UTC), or Puerto Rico, which does not (in which case the time meant is 2200 UTC? It's a tricky question. This post may have some help.

like image 26
David Berger Avatar answered Sep 30 '22 15:09

David Berger


If you want to rely on javascript you can simply send the utc time/timestamp back and forth and let the client convert it to its local time representation.

edit: simple self-contained example (using jquery)

<html>
  <head>
    <title>...</title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
    <script type="text/javascript">
      function foo(){
        $('.time').each( function() {
          var t = $(this);
          var d = new Date(Date.parse(t.text()));
          t.text(d.toLocaleString());
        });
      }
    </script>
  </head>
  <body>
    <div class="time"><?php echo gmdate(DateTime::RFC1123); ?></div>
    <button onclick="foo()">local time</button>
  </body>
</html>

If javascript is not available the user still sees a date/time though it's in UTC.
edit2: And there is a javascript library (or was it even a jquery plugin?) that does this kind of things plus some nifty conversions like "an hour ago", "last week" ..something like that. But I forgot the name :(

like image 23
VolkerK Avatar answered Sep 30 '22 14:09

VolkerK