web-dev-qa-db-ja.com

PHP / MySQLでUTCとして日時を保存する

時間をユーザーのタイムゾーンに変換することについて読んだどこでも、最良の方法は日付と時刻をUTCで保存し、ユーザーのタイムゾーンオフセットをこの時間に追加することであると述べています。

UTC時間で日付を保存するにはどうすればよいですか? MySQLのDATETIMEフィールドを使用します。

PHP)コードでMySQLに新しいレコードを追加するとき、now()を使用してMySQL DATETIMEに挿入します。

UTC時間を保存するためにnow()とは異なるものを使用する必要がありますか?

44
JasonDavis

MySQL: UTC_TIMESTAMP()

現在のUTC日付と時刻を、関数が文字列コンテキストで使用されるか数値コンテキストで使用されるかに応じて、「YYYY-MM-DD HH:MM:SS」またはYYYYMMDDHHMMSS.uuuuuu形式の値として返します。

PHP: gmdate()

また、PHP date_default_timezone_set() はPHPでスクリプトの現在のタイムゾーンを設定するために使用されます。すべての書式設定関数が現地時間で時刻を返すように、クライアントのタイムゾーンに設定します。

実際のところ、私はこれを機能させるのに苦労し、常にいくつかの落とし穴に遭遇しました。例えば。 MySQLから返される時間情報は「UTC」としてフォーマットされていないため、注意しないと strtotime はローカル時間に変換します。誰かがこの問題の信頼できるソリューションを持っているかどうか聞いてみたいです、日付がメディアの境界を越えても壊れない(HTTP-> PHP -> MySQLおよびMySQL-> PHP-> HTTP)、XMLおよびRSS/Atomも考慮します。

44
Remus Rusanu

UTCタイムゾーンに日付を挿入することをお勧めします。これにより、夏時間の問題で将来的に多くの頭痛の種が軽減されます。

INSERT INTO abc_table (registrationtime) VALUES (UTC_TIMESTAMP())

データをクエリするとき、次のPHPスクリプトを使用します。

<?php

while($row = mysql_fetch_array($registration)) { 

  $dt_obj = new DateTime($row['message_sent_timestamp'] ." UTC");
  $dt_obj->setTimezone(new DateTimeZone('Europe/Istanbul'));
  echo $formatted_date_long=date_format($dt_obj, 'Y-m-d H:i:s');
}
?>

DateTimeZoneの値は、利用可能な PHPタイムゾーン のいずれかに置き換えることができます。

40
Haluk

NOW()は、データベースを実行しているシステムの時間(タイムゾーンオフセットを含む)を提供します。 UTCの日付/時刻を取得するには、 MySQLリファレンスマニュアル で説明されているUTC_TIMESTAMP()を使用する必要があります。

7
user156676

https://dba.stackexchange.com/questions/20217/mysql-set-utc-time-as-default-timestamp

削除の場合に上記のリンクからすべての回答を引用する:

@ypercubeのコメントCURRENT_TIMESTAMPはUTCとして保存されますが、現在のタイムゾーンとして取得されます。取得の -default_time_zone オプションを使用すると、サーバーのタイムゾーン設定に影響を与えることができます。これにより、検索は常にUTCになります。

デフォルトでは、オプションは「SYSTEM」です。これは、システムのタイムゾーンの設定方法です(UTCである場合とそうでない場合があります)。

mysql> SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| SYSTEM             | SYSTEM              |
+--------------------+---------------------+
1 row in set (0.00 sec)

mysql> SELECT CURRENT_TIMESTAMP();
+---------------------+
| CURRENT_TIMESTAMP() |
+---------------------+
| 2012-09-25 16:28:45 |
+---------------------+
1 row in set (0.00 sec)

これを動的に設定できます。

mysql> SET @@session.time_zone='+00:00';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| SYSTEM             | +00:00              |
+--------------------+---------------------+
1 row in set (0.00 sec)

または、my.cnfで永続的に:

[mysqld]
**other variables**
default_time_zone='+00:00'

サーバーを再起動すると、変更が表示されます。

mysql> SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| +00:00             | +00:00              |
+--------------------+---------------------+
1 row in set (0.00 sec)

mysql> SELECT CURRENT_TIMESTAMP();
+---------------------+
| CURRENT_TIMESTAMP() |
+---------------------+
| 2012-09-25 20:27:50 |
+---------------------+
1 row in set (0.01 sec)
6
TheFrost

@Halukが示唆するように、日付をUTC datetimeとして保存できます。挿入したい日付がPHPコードであり、それがどのように機能するかについてのいくつかの詳細を追加する場合の状況に対する彼の答えを補完しています:

$pdo = new PDO('mysql:Host=mydbname.mysql.db;dbname=mydbname', 'myusername', 'mypassword');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$insertStmt = $pdo->prepare("insert into test (last_modified)"
    ." values(:last_modified)");
$insertStmt->bindParam(':last_modified', $lastModified, PDO::PARAM_STR);
$lastModified = gmdate("Y-m-d H:i:s");
$insertStmt->execute();

実際にdatetime in PHPにはタイムゾーンが関連付けられていません。PDOに渡されるのは、日付を表すMySQLが認識する形式の1つでの単なる文字列ですたとえば、日付が2015-10-21 19:32:33 UTC+2:00の場合、上記のコードはMySQLに2015-10-21 17:32:33を挿入するよう指示するだけです[gmtdate("Y-m-d H:i:s")はそのような形式で現在の日付を提供します。必要なことは、UTC時間で挿入する日付を表す文字列を作成することだけです。

次に、日付を読むときに、PHP取得した日付のタイムゾーンがUTCであることを伝える必要があります。これにはHalukの回答のコードを使用してください。

2
yannick1976

ランダム:UTC_TIMESTAMP(6)は、6桁のマイクロ秒の時間です。

MySQL 5.7以降

0
Rahim Khoja