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

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 the time of it with mine, but the date_default_timezone_set function does not use numbers, how can I help using the number returned by the JavaScript function ?

    
asked by anonymous 19.04.2015 / 16:42

3 answers

1

PHP (server side) works on timezone defined by you, or the server default if you do not define yourself. And if the code is as it should it will be 1 unique timezone regardless of where the client is.

JavaScript (client side) tables with the timezone where the client is, which in most cases is the timezone the client has configured on your system operative / browser.

Is there a way for both client and server to speak the same language / timezone?

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

How do I know the time variation of the client relative to UTC?

For this you do not have to go to the server. You can tell the difference between UTC and the region where the user can use:

var agora = new Date();
var diferenca = agora.getTimezoneOffset() * 60 * 1000; // milisegundos
// -7200000 ms no meu caso (Suécia)
    
19.04.2015 / 18:58
0

I answered to someone else about a question very similar to that.

What I indicated for her was to use UTC timezone, since javascript converts local time to UTC, and UTC to Local, and PHP can work with UTC.

See: PHP and JavaScript time synchronization

    
19.04.2015 / 17:56
0

If I understand correctly, I want to update the server time (by timezone), if it is in Brazil and the server is US wants the scripts to run with Brazilian time.

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

Why does getTimezoneOffset return 180?

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

  new Date().getTimezoneOffset();

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

Set 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 file 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 on 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 DateTime class (it may be easier to work with than the function date ):

<?php
require_once 'global.php';

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

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

But there is a problem that can get in the way, the user's computer may have some invalid configuration (even for lack of battery).

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

Adjust timezone using only the backend

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

  • link
  • link
  • 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';
    
        
    30.05.2016 / 06:21