32

I'm writting an application using Zend_Framework (so the solution can rely on it).

How to get client's timezone?

For example, if someone in Moscow, Russia, I want to get 3*60*60 (because there is UTC+3). If he is in UK, I want zero. If he uses UTC-3:30 (Canada?), I want -3.5*60*60.

(it's not a question about a format - I'm ok with getting 'Europe/Moscow' or 'UTC-3' for St. Petersburg, Russia, it's rather about getting timezone client uses. But delta in seconds is preferred)

The only solution which comes to mind is letting javascript get the local time for me and redirect.

Valentin Golev
  • 9,965
  • 10
  • 60
  • 84
  • 2
    Note, all of the answers in this question are flawed because they only get the *current* offset. See "Time Zone != Offset" in [the timezone tag wiki](http://stackoverflow.com/tags/timezone/info), and see the dup question and its answers. – Matt Johnson-Pint Nov 26 '15 at 02:06

4 Answers4

12

I wrote a function using jQuery and PHP. This is tested, and does work!

On the PHP page where you are want to have the timezone as a variable, have this snippet of code somewhere near the top of the page:

<?php    
    session_start();
    $timezone = $_SESSION['time'];
?>

This will read the session variable "time", which we are now about to create.

On the same page, in the , you need to first of all include jQuery:

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>

Also in the , below the jQuery, paste this:

<script type="text/javascript">
    $(document).ready(function() {
        if("<?php echo $timezone; ?>".length==0){
            var visitortime = new Date();
            var visitortimezone = "GMT " + -visitortime.getTimezoneOffset()/60;
            $.ajax({
                type: "GET",
                url: "http://domain.com/timezone.php",
                data: 'time='+ visitortimezone,
                success: function(){
                    location.reload();
                }
            });
        }
    });
</script>

You may or may not have noticed, but you need to change the url to your actual domain.

One last thing. You are probably wondering what the heck timezone.php is. Well, it is simply this: (create a new file called timezone.php and point to it with the above url)

<?php
    session_start();
    $_SESSION['time'] = $_GET['time'];
?>

If this works correctly, it will first load the page, execute the JavaScript, and reload the page. You will then be able to read the $timezone variable and use it to your pleasure! It returns the current UTC/GMT time zone offset (GMT -7) or whatever timezone you are in.

oldmud0
  • 147
  • 2
  • 11
Westy92
  • 19,087
  • 4
  • 72
  • 54
  • 1
    Mixing javascript and php-code? Are you seriously? – drull Oct 31 '14 at 21:48
  • 4
    Why not? Unless I'm mistaken, the time zone can only be declared from the client side, and having it in the php session adds a lot of flexibility. – americanknight Dec 02 '14 at 20:22
  • Yes, ofc, you need javascript to do this. But i'm talking about embedding pure php into html: it's monkey-coding. Better use templates. I would be fired next day if i do something like this :) – drull Apr 02 '15 at 20:59
  • 2
    templating engines convert your template code to straight php at some point. – Adam Rodriguez Jul 13 '15 at 19:00
  • According to [Wikipedia](https://en.wikipedia.org/wiki/Time_zone) there are few zones with offset from UTC by 30 or 45 minutes (_e.g. Newfoundland Standard Time is UTC−03:30, Nepal Standard Time is UTC+05:45, and Indian Standard Time is UTC+05:30_), so straighforward dividing by 60 may yield somewhat strange results... – AntonK Feb 26 '18 at 21:59
  • so basically: `var visitortimezone = "GMT " + -new Date().getTimezoneOffset()/60;` – Taufik Nur Rahmanda May 04 '18 at 05:50
  • 1
    @drull please hold the criticism down until you are willing to share better code not subject to the complaint. – Dennis May 06 '22 at 13:07
8

Check out this article on how to detect the timezone by setting a Cookie through JavaScript that will hold the client's timezone. It's rather lenghty, but that is because it is quite verbose. I've implemented a solution along these lines in one of my own apps and it works quite well.

You could also send the timezone via Ajax to the server and have it do whatever you need to do it with then. Or, if you are not doing any serverside calculations with it, just apply the timezone client side where needed. Really depends on your usecase.

In addition to that, I suggest you let the visitor set his timezone himself and store that in the Cookie or a Session.

Gordon
  • 312,688
  • 75
  • 539
  • 559
  • 8
    That link is broken. This might be a copy: http://blog.codez.in/php5-time-zone-solution/web-development/2010/07/09 – Jose M Vidal Feb 10 '11 at 21:09
  • 1
    @Jose thanks for pointing out AND supplying alternative – Gordon Feb 10 '11 at 21:26
  • 2
    both links now broken :-( – rmirabelle Jul 29 '17 at 04:19
  • 1
    Both pages are available in the mighty WebArchive: [www.incoherent.ch](http://web.archive.org/web/20090830054014/http://www.incoherent.ch/blog/2008/02/20/php5-time-zone-solution/) and [blog.codez.in](http://web.archive.org/web/20111228211223/http://blog.codez.in/php5-time-zone-solution/web-development/2010/07/09) – AntonK Feb 26 '18 at 21:52
2

This is a cookie solution with very little overhead:

  echo <<<EOE
   <script type="text/javascript">
     if (navigator.cookieEnabled)
       document.cookie = "tzo="+ (- new Date().getTimezoneOffset());
   </script>
EOE;
  if (!isset($_COOKIE['tzo'])) {
    echo <<<EOE
      <script type="text/javascript">
        if (navigator.cookieEnabled) document.reload();
        else alert("Cookies must be enabled!");
      </script>
EOE;
    die();
  }
  $ts = new DateTime('now', new DateTimeZone('GMT'));
  $ts->add(DateInterval::createFromDateString($_COOKIE['tzo'].' minutes'));
Lauber Bernhard
  • 175
  • 1
  • 1
  • 6
  • 1
    `new DateTime('now', new DateTimeZone('GMT'));` should probably be using `UTC` instead of `GMT` per MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset – Gifford N. Apr 26 '17 at 06:03
  • UTC and GMT are practically the same. – Zoltán Hajdú Aug 28 '23 at 19:48
1

I think your best bet is to guess based on the Accept-Language header sent over by the client.

Myles
  • 20,860
  • 4
  • 28
  • 37
  • to retrieve the country and city I can use geoip. But timezones like 'Europe/Moscow' can be set only for specific cities, while client can be from anywhere – Valentin Golev Dec 15 '09 at 05:56
  • It's true, and the Accept-Language will most likely cover a large area of timezones, but the client doesn't really send anything else over that indicates their timezone. The most accurate would be your suggestion of redirecting based on javascript, but that is too bad to have two page loads per page request... – Myles Dec 15 '09 at 05:59
  • I can store it in a session then :) It's only one additional request. I think, I gonna go this way if I don't find anything else. – Valentin Golev Dec 15 '09 at 06:05
  • 1
    Some Geo-IP services provides a timezone for an IP-address. So, here I did an example: http://stackoverflow.com/questions/4746249/get-user-timezone/10103105#10103105 – Mikhus Apr 11 '12 at 09:20