Saya menangani situasi ini secara ekstensif dalam aplikasi PHP/MySQL yang saya tulis untuk operator jet pribadi lebih dari setahun yang lalu. Ada strategi berbeda untuk menangani zona waktu di kedua platform ini, tetapi saya akan menjelaskan bagaimana saya melakukannya. Saya menyetel server MySQL ke UTC dan menjalankan setiap skrip PHP di zona waktu yang ditentukan pengguna selama proses pendaftaran untuk profil pengguna.
MySQL dan PHP (PHP 5.2 dan di atasnya) keduanya memiliki tipe data datetime asli. Datetime MySQL adalah tipe data primitif, sedangkan PHP 5.2 dan di atasnya menawarkan Kelas DateTime . Tipe data datetime MySQL tidak menyertakan metadata untuk zona waktu, tetapi objek PHP DateTime selalu menyertakan zona waktu. Jika konstruktor datetime PHP tidak menentukan zona waktu opsional dalam argumen kedua, maka konstruktor datetime PHP menggunakan variabel lingkungan php.
Baik MySQL dan PHP memiliki zona waktu default yang ditetapkan dalam file konfigurasi. MySQL menggunakan datetime yang disetel dalam file konfigurasi untuk setiap koneksi db kecuali pengguna menentukan zona waktu yang berbeda setelah koneksi dimulai dengan perintah SET time_zone = [timezone];
. PHP juga menetapkan variabel lingkungan zona waktu untuk setiap skrip menggunakan zona waktu yang ditetapkan dalam file konfigurasi server, dan variabel lingkungan ini dapat diganti menggunakan fungsi PHP date_default_timezone_set()
setelah skrip dimulai.
Kelas PHP DateTime memiliki properti yang disebut zona waktu , yang merupakan objek DateTimeZone PHP . Objek DateTimeZone ditentukan menggunakan string untuk zona waktu yang tepat. Daftar zona waktu komprehensif, memiliki ratusan zona waktu individu di seluruh dunia. Zona waktu PHP akan memperhitungkan waktu musim panas secara otomatis.
Saat pengguna membuat datetime di aplikasi web, buat objek datetime PHP di zona waktu profil pengguna. Kemudian gunakan setTimezone
metode untuk mengubah objek DateTime ke zona waktu UTC. Sekarang Anda memiliki waktu pengguna dalam UTC, dan Anda dapat menyimpan nilainya dalam database. Gunakan format
DateTime
metode untuk mengekspresikan data sebagai string dalam format yang diterima oleh MySQL.
Jadi pengguna membuat waktu tanggal, dan Anda membuat objek waktu waktu PHP di zona waktu yang ditentukan pengguna:
// 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')";
Saat Anda mengambil nilai dari database, buat dalam UTC lalu konversikan ke zona waktu pengguna.
$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');
Dengan menggunakan metode ini, nilai datetime Anda selalu disimpan dalam UTC di dalam db, dan pengguna selalu mengalami nilai di zona waktu profilnya. PHP akan mengoreksi Waktu Musim Panas jika diperlukan untuk setiap zona waktu.
Satu gotcha:Penjelasan ini tidak mencakup tipe data stempel waktu MySQL. Saya merekomendasikan menggunakan datetype MySQL datetime untuk menyimpan nilai datetime, bukan tipe data timestamp. Tipe data cap waktu tercakup dalam manual di sini .
Sunting: Anda dapat menghasilkan larik yang berisi setiap string zona waktu PHP menggunakan listIdentifiers , yang merupakan metode statis dari kelas DateTimeZone.