How to update PHP Timezone with javascript using the Date.getTimezoneOffset function?

Asked

Viewed 487 times

4

I’m getting the TMZ end user with this code:

TMZ = new Date().getTimezoneOffset()

for me it returns 180 and this number I send to the server, so that it adjusts his time with mine, but the function date_default_timezone_set does not use numbers, as I can help using the number returned by the Javascript function?

  • What is the server Timezone?

  • It doesn’t solve your problem (actually it does, but it’s not the answer you’re looking for), but this lib can help you: http://pellepim.bitbucket.org/jstz/.

  • @Sergio the server Timezone is irrelevant, it has to adapt to the user, but in case he is using the Brasilia.

  • @Eduardosilva found it interesting, I’ll wait for Sergio’s opinion..

  • @Elaine each user has 1 server? or the server is yours and knows your Timezone?

  • @Sergio no, the user just needs to send his tmz to the server for the server to return with the correct time..

  • If I understand you want to adjust the server time through something on the front end? That’s it?

  • @Guilhermenascimento getting something from the front end to adapt the server time. For example, I’m in Brazil but the server is German, so something from the front end should be sent to the server to set the time next to me (front end)

Show 3 more comments

3 answers

1

PHP (server side) works on Timezone default server if you do not define tu. And if the code is as it should be, it will be 1 single Timezone regardless of where the customer is.

Javascript (client side) works with the Timezone where the customer is, which in most cases is the Timezone that the client has configured in its operating system/browser.

There is a way for both client and server to speak in the same/Timezone language?

Yes, there is, the UTC. In Javascript you can use .getTime() to give the number of milliseconds since January 1, 1970 on Timezone UTC. This is the secret because if the server is also using UTC, then they are using the same reference.

How to know the hourly variation of the client relative to UTC?

No need to go to the server for this. You can know the difference between UTC and the region where the user is:

var agora = new Date();
var diferenca = agora.getTimezoneOffset() * 60 * 1000; // milisegundos
// -7200000 ms no meu caso (Suécia)
  • Yes, I set my server to Timezone UTC, and the difference between UTC and the user’s Timezone is sent to the server, how to make the server consider the user’s difference to the server (UTC) whenever it sends a message that contains time(), date().. for that X user?

  • @Elaine if you know the difference that the user has, in minutes for example, you can do $horaCliente = time() + ($difCliente * 60); and so you get a timestamp in seconds. That’s what you’re looking for?

  • I think I get it, just do the talking.. Yes what I look for is to tailor the server time (momentarily for a request response) to the client’s time

  • @Elaine ok, tell me if you need more help. If so, give me a concrete example of what you’re doing so I can answer more specifically as well.

  • 1

    Pardon, it was a mistake of definition, I found banal and removed. Thank you!

0

I answered someone else about a question that looked just like that.

What I pointed out to her was to use Timezone UTC, because javascript converts the local time to UTC, and UTC to Local, and PHP can work with UTC.

Behold: Time Sync() PHP and Javascript

0

If I understand well want to update the server time (by Timezone), if you are in Brazil and the server is American (US) want the scripts run with the Brazilian time.

There are two paths to take, the first and what I recommend is not to change the server time "directly", I mean can change the Timezone yes, but in all registry functions, as enter data in the database prefer to use UTC (or GMT) and at the time of reading the database data you would adjust for the user Timezone.

Why getTimezoneOffset returns 180?

I will first explain the reason of the 180, when it is in Brazil and we run the command:

  new Date().getTimezoneOffset();

He will return 180, this value must be divided by 60, that will give the number 3, Brazil and reference to UTC -3 hours. So the 180 is correct, but this I did in hours, you can use the 180 making the script to be -180 seconds, but it gets a little harder maybe, because you would have to use gmmktime of PHP combined with gmdate (functions that work with GMT) or else use DateTime::modify which may be easier (see example below).

Adjust Timezone with javascript

Basically (whether it’s automatic or not) you can do something like an update via ajax:

<?php session_start(); ?>

<?php if (empty($_SESSION['timezonesec'])): ?>

    <script>
    (function () {
        var oReq = new XMLHttpRequest();
        var tz = -(new Date().getTimezoneOffset());

        oReq.open("GET", "/update-timezone.php?sec=" + tz, true);

        oReq.onreadystatechange = function()
        {
            if (oReq.readyState === 4) {
                console.log(oReq.responseText);
            }
        };

        oReq.send(null);
    })();
    </script>

<?php endif; ?>

The archive update-timezone.php would look something like:

<?php
session_start();

if (!empty($_GET['sec'])) {
    $_SESSION['timezonesec'] = $_GET['sec'];
}

Then create a "global" file (if you already have one just put UTC at the top) that contains something like:

global.php

<?php
session_start();
date_default_timezone_set('UTC');

if (empty($_SESSION['timezonesec'])) {
     //Emite "erro" (exceção se não conseguir configurar a timezone)
     throw new Exception('Timezone não pode ser definida');
}

$tzs = $_SESSION['timezonesec'];
$sec = ($tzs < 0 ? '-' : '+') . $tzs;

//Ajusta pra plural ou singular (realmente não sei se isto faz diferença para o php)
$sp  = ' second' . ($tzs < -1 || $tzs > 1 ? 's' : "");

define('TIMEZONE_SECONDS', $sec . $sp);

And the other scripts you can use the class Datetime (it can be easier to work than function date):

<?php
require_once 'global.php';

$time = new DateTime();
$time->modify(TIMEZONE_SECONDS);

echo $date->format('Y-m-d h:i:s');

Only that there is a problem that can disturb, the user’s computer may be with some invalid configuration (even for lack of battery).

From my point of view the best is to always record in UTC (or GMT) and adjust the time when displaying the data, if it is an authenticated user you can give the option of it even choose the Timezone desired (I think many sites do this way), the user selects the country and the setting is automatic (like facebook).

Adjust Timezone using back-end only

Something that would be safer against crashes if you want the automatic detection I found on SOEN would use the API of the site maxmind, download both:

  1. http://www.maxmind.com/download/geoip/api/php/php-latest.tar.gz
  2. http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz

Then create a global.php file like this:

<?php
session_start();

//Pega o IP do usuário (proxies podem alterar isto)
$ip = $_SERVER['REMOTE_ADDR'];

if (empty($_SESSION['timezone:' . $ip])) {
    //Le os dados, o GeoLiteCity.dat é o arquivo que você baixou
    $gi = geoip_open("GeoLiteCity.dat", GEOIP_STANDARD);
    $record = geoip_record_by_addr($gi, $ip);

    if(isset($record)) {
        //Usa a função da API do maxmind e salva em uma sessão
        $_SESSION['timezone:' . $ip] = get_time_zone($record->country_code, ($record->region!='') ? $record->region : 0);
    }
}

if (empty($_SESSION['timezone:' . $ip])) {
     //Emite "erro" (exceção se não conseguir configurar a timezone)
     throw new Exception('Timezone não pode ser definida');
}

date_default_timezone_set($_SESSION['timezone:' . $ip]);

And add and all your files this:

<?php
require_once 'global.php';

Browser other questions tagged

You are not signed in. Login or sign up in order to post.