Jag hanterade denna situation utförligt i en PHP/MySQL-applikation som jag skrev för en privat jetoperatör för lite över ett år sedan. Det finns olika strategier för att hantera tidszoner i dessa två plattformar, men jag kommer att förklara hur jag gjorde det. Jag ställer in MySQL-servern på UTC och kör varje PHP-skript i den tidszon som användaren anger under registreringsprocessen för användarprofilen.
MySQL och PHP (PHP 5.2 och senare) har båda inbyggda datetime-datatyper. MySQL:s datetime är en primitiv datatyp, medan PHP 5.2 och högre erbjuder den inbyggda DateTime-klass . Datatypen MySQL datetime inkluderar inte metadata för tidszonen, men ett PHP DateTime-objekt inkluderar alltid en tidszon. Om PHP datetime-konstruktorn inte anger den valfria tidszonen i det andra argumentet, använder PHP-datetime-konstruktorn miljövariabeln php.
Både MySQL och PHP har förinställd tidszon i konfigurationsfilerna. MySQL använder datumtid som anges i konfigurationsfilen för varje db-anslutning om inte användaren anger en annan tidszon efter att anslutningen har startat med kommandot SET time_zone = [timezone];
. PHP ställer också in en tidszonsmiljövariabel för varje skript med den tidszon som är inställd i serverns konfigurationsfil, och denna miljövariabel kan åsidosättas med PHP-funktionen date_default_timezone_set()
efter att skriptet startar.
PHP DateTime-klassen har en egenskap som heter tidszon , som är ett PHP DateTimeZone-objekt . DateTimeZone-objektet specificeras med en sträng för den exakta tidszonen. listan över tidszoner är omfattande och har hundratals individuella tidszoner över hela världen. PHP-tidszonerna tar automatiskt hänsyn till sommartid.
När användaren genererar en datetime i webbappen, konstruera ett PHP datetime-objekt i tidszonen för användarens profil. Använd sedan setTimezone
metod för att ändra DateTime-objektet till UTC-tidszonen. Nu har du användarens datetime i UTC, och du kan lagra värdet i databasen. Använd format
DateTime.
metod för att uttrycka data som en sträng i det format som accepteras av MySQL.
Så användaren genererar en datetime, och du skapar ett PHP datetime-objekt i användarens angivna tidszon:
// set using an include file for user profile
$user_timezone = new DateTimeZone('America/New_York');
// 1st arg in format accepted by PHP strtotime
$date_object1 = new DateTime('8/9/2012 5:19 PM', $user_timezone);
$date_object1->setTimezone(new DateTimeZone('UTC'));
$formated_string = $date_object1->format('Y-m-d H:i:s');
$query_string = "INSERT INTO `t_table1` (`datetime1`) VALUES('$formated_string')";
När du hämtar värdet från databasen, konstruera i UTC och konvertera sedan till användarens tidszon.
$query_string = "SELECT `datetime1` FROM `t_table1`";
$date_object1 = new DateTime($datetime_string_from_mysql, new DateTimeZone('UTC'));
$date_object1->setTimezone($user_timezone);
$string_for_display_in_application = $date_object1->format('m/d/Y g:i a');
Med den här metoden lagras dina datetime-värden alltid i UTC inuti db, och användaren upplever alltid värdena i sin profils tidszon. PHP kommer att korrigera för sommartid om det behövs för varje tidszon.
One gotcha:Den här förklaringen täcker inte MySQL-tidsstämpeldatatypen. Jag rekommenderar att du använder MySQL datetime datetype för att lagra datetime-värden, inte tidsstämpeldatatypen. Tidsstämpeldatatypen täcks av manualen här .
Redigera: Du kan skapa en array som innehåller varje PHP-tidszonsträng med listIdentifiers , som är en statisk metod för klassen DateTimeZone.