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';