Is there a standard way for a web server to be able to determine a user\'s timezone within a web page?
Perhaps from an HTTP header or part of the user-agent
JavaScript is the easiest way to get the client's local time. I would suggest using an XMLHttpRequest to send back the local time, and if that fails, fall back to the timezone detected based on their IP address.
As far as geolocation, I've used MaxMind GeoIP on several projects and it works well, though I'm not sure if they provide timezone data. It's a service you pay for and they provide monthly updates to your database. They provide wrappers in several web languages.
Try this PHP code:
<?php
$ip = $_SERVER['REMOTE_ADDR'];
$json = file_get_contents("http://api.easyjquery.com/ips/?ip=" . $ip . "&full=true");
$json = json_decode($json,true);
$timezone = $json['LocalTimeZone'];
?>
It is simple with JavaScript and PHP:
Even though the user can mess with his/her internal clock and/or timezone, the best way I found so far, to get the offset, remains new Date().getTimezoneOffset();
. It's non-invasive, doesn't give head-aches and eliminates the need to rely on third parties.
Say I have a table, users
, that contains a field date_created int(13)
, for storing Unix timestamps;
Assuming a client creates a new account
, data is received by post
, and I need to insert/update
the date_created column
with the client's Unix timestamp, not the server's.
Since the timezoneOffset is needed at the time of insert/update, it is passed as an extra $_POST element when the client submits the form, thus eliminating the need to store it in sessions and/or cookies, and no additional server hits either.
var off = (-new Date().getTimezoneOffset()/60).toString();//note the '-' in front which makes it return positive for negative offsets and negative for positive offsets
var tzo = off == '0' ? 'GMT' : off.indexOf('-') > -1 ? 'GMT'+off : 'GMT+'+off;
Say the server receives tzo
as $_POST['tzo']
;
$ts = new DateTime('now', new DateTimeZone($_POST['tzo']);
$user_time = $ts->format("F j, Y, g:i a");//will return the users current time in readable format, regardless of whether date_default_timezone() is set or not.
$user_timestamp = strtotime($user_time);
Insert/update date_created=$user_timestamp
.
When retrieving the date_created, you can convert the timestamp like so:
$date_created = // Get from the database
$created = date("F j, Y, g:i a",$date_created); // Return it to the user or whatever
Now, this example may fit one's needs, when it comes to inserting a first
timestamp... When it comes to an additional timestamp, or table, you may want to consider inserting the tzo value into the users table for future reference, or setting it as session or as a cookie.
P.S. BUT what if the user travels and switches timezones. Logs in at GMT+4, travels fast to GMT-1 and logs in again. Last login would be in the future.
I think... we think too much.
-new Date().getTimezoneOffset()/60;
The method getTimezoneOffset()
will subtract your time from GMT and return the number of minutes. So if you live in GMT-8, it will return 480.
To put this into hours, divide by 60. Also, notice that the sign is the opposite of what you need - it's calculating GMT's offset from your time zone, not your time zone's offset from GMT. To fix this, simply multiply by -1.
Also note that w3school says:
The returned value is not a constant, because of the practice of using Daylight Saving Time.
To submit the timezone offset as an HTTP header on AJAX requests with jQuery
$.ajaxSetup({
beforeSend: function(xhr, settings) {
xhr.setRequestHeader("X-TZ-Offset", -new Date().getTimezoneOffset()/60);
}
});
You can also do something similar to get the actual time zone name by using moment.tz.guess();
from http://momentjs.com/timezone/docs/#/using-timezones/guessing-user-timezone/
Don't use the IP address to definitively determine location (and hence timezone)-- that's because with NAT, proxies (increasingly popular), and VPNs, IP addresses do not necessarily realistically reflect the user's actual location, but the location at which the servers implementing those protocols reside.
Similar to how US area codes are no longer useful for locating a telephone user, given the popularity of number portability.
IP address and other techniques shown above are useful for suggesting a default that the user can adjust/correct.