J'ai un serveur qui est défini sur EST, et tous les enregistrements de la base de données sont définis sur EST. Je voudrais savoir comment le régler sur GMT. Je souhaite proposer une option de fuseau horaire à mes utilisateurs.
Quel que soit le fuseau horaire GMT du serveur, voici un moyen extrêmement simple d'obtenir l'heure et la date pour n'importe quel fuseau horaire. Cela se fait avec les fonctions time()
et gmdate()
. La fonction gmdate()
nous donne normalement l'heure GMT, mais en faisant un tour avec la fonction time()
nous pouvons obtenir GMT + N ou GMT-N, ce qui signifie que nous pouvons obtenir l'heure pour n'importe quel GMT fuseau horaire.
Par exemple, si vous devez obtenir l'heure pour GMT + 5, vous pouvez le faire comme suit
<?php
$offset=5*60*60; //converting 5 hours to seconds.
$dateFormat="d-m-Y H:i";
$timeNdate=gmdate($dateFormat, time()+$offset);
?>
Maintenant, si vous devez obtenir l'heure pour GMT-5, vous pouvez simplement soustraire l'offset de la time()
au lieu de l'ajouter, comme dans l'exemple suivant où nous obtenons l'heure pour GMT-4
<?php
$offset=4*60*60; //converting 4 hours to seconds.
$dateFormat="d-m-Y H:i"; //set the date format
$timeNdate=gmdate($dateFormat, time()-$offset); //get GMT date - 4
?>
Je voudrais fortement suggérer d'éviter de jouer avec les horodatages UNIX pour le faire ressembler à un fuseau horaire différent. C'est une leçon que j'ai apprise à la dure, bien trop de fois.
Un horodatage est le nombre de secondes écoulées depuis minuit le 1er janvier 1970, GMT. Peu importe où vous vous trouvez dans le monde, un horodatage donné représente exactement le même moment dans le temps, quels que soient les fuseaux horaires. Oui, l'horodatage "0" signifie 10h 1/1/70 en Australie, Midnight 1/1/70 à Londres et 17h 31/12/69 à LA, mais cela ne signifie pas que vous pouvez simplement ajouter ou soustraire des valeurs et garantir précision.
L'exemple en or qui me bourrait chaque année depuis trop longtemps était celui de l'heure d'été. L'heure d'été signifie qu'il existe des "heures d'horloge" qui n'existent pas dans certaines parties du monde. Par exemple, dans la plupart des régions des États-Unis, il n'y avait pas d'heure à 2 h 01 le 2 avril 2006.
Assez de diatribes quasi-intelligibles cependant. Mon conseil est de stocker vos dates dans la base de données sous forme d'horodatages, puis ...
date()
gmdate()
date_default_timezone_set()
puis date()
Par exemple,
$timestamp = time();
echo "BRISBANE: " . date('r', $timestamp) . "\n";
echo " UTC: " . gmdate('r', $timestamp) . "\n";
date_default_timezone_set('Africa/Johannesburg');
echo " JOBURG: " . date('r', $timestamp) . "\n";
// BRISBANE: Tue, 12 May 2009 18:28:20 +1000
// UTC: Tue, 12 May 2009 08:28:20 +0000
// JOBURG: Tue, 12 May 2009 10:28:20 +0200
Cela gardera vos valeurs propres (vous n'avez pas à vous soucier d'ajouter des décalages, puis de les soustraire avant d'enregistrer), cela respectera toutes les règles de l'heure d'été, et vous n'aurez même pas à rechercher le fuseau horaire de l'endroit tu veux.
Il est important de noter que si vous utilisez date ('Z') pour convertir une date qui est stockée dans une base de données que vous donnez à la date l'horodatage comme deuxième argument, sinon votre résultat ne sera pas précis.
par exemple.
Au Royaume-Uni, parfois la date ('Z') donnera 3600, parfois elle donnera 0.
echo date('Z', strtotime('2012-01-01'));
Donne 0
echo date('Z', strtotime('2012-07-01'));
Donne 3600
Donc, en utilisant uniquement strtotime ($ dbDateValue) - la date ('Z') peut être erronée
Utilisez plutôt:
$dbDateTimestamp = strtotime($dbDateValue); // where $dbDateValue something like 2012-01-01 22:34:00
$utcTimestamp = strtotime($dbDateTimestamp) - date('Z', $dbDateTimestamp);
Bien sûr, cela repose sur PHP et la base de données étant tous deux définis sur le même fuseau horaire.
Voici une liste des fuseaux horaires différents de GMT, j'espère que cela vous sera utile!
echo '<pre>';
$zones_array = array();
$timestamp = time();
# to maintain the original timezone, store before
$default_timezone = date_default_timezone_get();
foreach (timezone_identifiers_list() as $key => $zone) {
date_default_timezone_set($zone);
$zones_array[$key]['zone'] = $zone;
$zones_array[$key]['diff_from_GMT'] = date('P', $timestamp);
}
# to maintain the original timezone, re-set after
date_default_timezone_set($default_timezone);
print_r($zones_array);
Merci!
J'ai été inspiré par cette question pour écrire une fonction alternative pour convertir un horodatage en un fuseau horaire nécessaire.
Ainsi, les étapes de la procédure CORRECT pour enregistrer, afficher (convertir) le temps:
1) record timestamp with time()
2) If you need to get a different timezone, use:
2.1) Class based:
2.1.1) DateTime class + setTimezone
or
2.1.2) date_default_timezone_set() and then date()
2.1.1) is better and more flexible than 2.1.2)
Function:
function getLTime_class($ts, $uTZ, $format_str="Y.m.d H:i", $sTZ="America/Toronto"){
// $ts - timestamp recorded with time(); if have date => convert to timestamp: strtotime($date_input); //for ex strtotime('2012-02-17 12:00:00'); => 1345219200 - same value for summer and winter (for toronto timezone);
// $uTZ - TZ string (ex: 'America/Toronto'); convert timestamp to this TimeZone
// $sTZ - TZ string (ex: 'America/Toronto'); convert timestamp from this TimeZone
$TimeZone_server=new DateTimeZone($sTZ);
$date_obj=new DateTime("@$ts", $TimeZone_server);
$TimeZone_local=new DateTimeZone($uTZ);
$date_obj->setTimeZone($TimeZone_local);
return $date_obj->format($format_str);
}
Usage:
$date_input=$_POST['date_input']; //read from POST
$ts=strtotime($date_input); //for ex strtotime('2012-02-17 12:00:00'); => 1345219200 - same value for summer and winter (for toronto timezone);
$userTZ='America/Toronto'; //read from user params
$result=getLTime_class($ts, $userTZ, 'Y-m-d H:i:s');
2.2) Non-Class based:
Function:
//this function replaces the function with DateTime class. It's faster. $uTZoffset is integer.
function getLTime_nonclass($ts, $uTZoffset, $format_str="Y.m.d H:i"){
// $ts - timestamp recorded with time(); if have date => convert to timestamp: strtotime($date_input); //for ex strtotime('2012-02-17 12:00:00'); => 1345219200 - same value for summer and winter (for toronto timezone);
// $uTZoffset - TZ offset (integer) $uTZoffset must consider DTS (for ex: in summer $uTZoffset=-4; in winter $uTZoffset=-5)
$ts_offset=date('Z',$ts);
if ($uTZoffset) $add_offset=$ts_offset-date('Z'); //when not UTC
else $add_offset=0; //when UTC
return date($format_str,$ts-$ts_offset+$uTZoffset*3600+$add_offset);
}
Usage:
$date_input=$_POST['date_input']; //read from POST
$ts=strtotime($date_input); //for ex strtotime('2012-02-17 12:00:00'); => 1345219200 - same value for summer and winter (for toronto timezone);
$uTZoffset=-4; //read from user params. $uTZoffset - TZ offset (integer) $uTZoffset must consider DTS (for ex: in summer $uTZoffset=-4; in winter $uTZoffset=-5)
$result=getLTime_nonclass($ts, $uTZoffset, 'Y-m-d H:i:s');
Résultats:
$ date_input = 2012-08-17 12:00:00
Server date: summer (2013-08-26)
getLTime_class => $userTZ='America/Toronto' => 2012-08-17 12:00:00
getLTime_nonclass => $uTZoffset=-4 => 2012-08-17 12:00:00
getLTime_class => $userTZ='UTC' => 2012-08-17 16:00:00
getLTime_nonclass => $uTZoffset=0 => 2012-08-17 16:00:00
Server date: winter (2013-02-26)
getLTime_class => $userTZ='America/Toronto' => 2012-08-17 12:00:00
getLTime_nonclass => $uTZoffset=-5 => 2012-08-17 12:00:00
getLTime_class => $userTZ='UTC' => 2012-08-17 16:00:00
getLTime_nonclass => $uTZoffset=0 => 2012-08-17 16:00:00
$ date_input = 2012-02-17 12:00:00
Server date: summer (2013-08-26)
getLTime_class => $userTZ='America/Toronto' => 2012-02-17 12:00:00
getLTime_nonclass => $uTZoffset=-4 => 2012-02-17 12:00:00
getLTime_class => $userTZ='UTC' => 2012-02-17 17:00:00
getLTime_nonclass => $uTZoffset=0 => 2012-02-17 17:00:00
Server date: winter (2013-02-26)
getLTime_class => $userTZ='America/Toronto' => 2012-02-17 12:00:00
getLTime_nonclass => $uTZoffset=-5 => 2012-02-17 12:00:00
getLTime_class => $userTZ='UTC' => 2012-02-17 17:00:00
getLTime_nonclass => $uTZoffset=0 => 2012-02-17 17:00:00
J'ai décidé d'obtenir getLTime_nonclass dans l'espoir de rendre la conversion plus rapide que d'utiliser des classes. Tout ce que je demande, c'est de confirmer que getLTime_nonclass est un remplacement valide pour getLTime_class. N'hésitez pas à exprimer votre opinion. Merci
Il y a beaucoup de temps quand il faut enregistrer le temps dans la base de données en GMT + 0, mais la fonction time () renverra l'heure du serveur. Sa résolution possible par la fonction suivante:
/**
* Converts a local Unix timestamp to GMT
*
* @param int Unix timestamp
* @return int
*/
function local_to_gmt($time = '')
{
if ($time === '')
{
$time = time();
}
return mktime(
gmdate('G', $time),
gmdate('i', $time),
gmdate('s', $time),
gmdate('n', $time),
gmdate('j', $time),
gmdate('Y', $time)
);
}