1. ホーム
  2. php

[解決済み] MySQLのdatetimeフィールドとサマータイム -- 「余分な」時間を参照するには?

2023-01-20 19:12:57

質問

私はアメリカ/ニューヨークのタイムゾーンを使用しています。 秋になると、午前 2 時に 1 時間遅れて、事実上 1 時間増えます。 この移行点では次のようなことが起こります。

01:59:00 -04:00 です。

と表示され、1分後には

01:00:00 -05:00

つまり、単に "1:30am" と言った場合、1回目の1:30を指しているのか、2回目を指しているのか、曖昧になってしまうのです。 MySQL データベースにスケジュールデータを保存しようとしているのですが、時間を正しく保存する方法がわかりません。

ここに問題があります。

"2009-11-01 00:30:00" は、内部的には 2009-11-01 00:30:00 -04:00 として保存されます。

"2009-11-01:30:00"は、内部的には2009-11-01 01:30:00として格納されます。 -05:00

これは問題なく、かなり予想通りです。 しかし、01:30:00 に何かを保存するにはどうすればよいのでしょうか。 -04:00 ? その ドキュメント はオフセットを指定するためのサポートを一切示しておらず、したがって、私がオフセットを指定しようとしたとき、それは正当に無視されました。

私が考えた唯一の解決策は、サーバーを夏時間を使用しないタイムゾーンに設定し、私のスクリプト (私はこのために PHP を使用しています) で必要な変換を行うことです。 しかし、それは必要ないように思われます。

あらゆる提案に感謝します。

どのように解決するのですか?

MySQL の日付タイプは、率直に言って、壊れており、以下のものを保存できません。 すべて を正しく格納することができません。(私は MySQL 5.0.45 を使用しています)。

これは 夏時間が終了する前の1時間は保存できないからです。 . どのように日付を入力しても、すべての日付関数はこれらの時刻を切り替え後の1時間の間であるかのように扱います。

私のシステムのタイムゾーンは America/New_York . 1257051600 (Sun, 01 Nov 2009 06:00:00 +0100) を保存してみましょう。

ここでは、独自のINTERVAL構文を使っています。

SELECT UNIX_TIMESTAMP('2009-11-01 00:00:00' + INTERVAL 3599 SECOND); # 1257051599
SELECT UNIX_TIMESTAMP('2009-11-01 00:00:00' + INTERVAL 3600 SECOND); # 1257055200

SELECT UNIX_TIMESTAMP('2009-11-01 01:00:00' - INTERVAL 1 SECOND); # 1257051599
SELECT UNIX_TIMESTAMP('2009-11-01 01:00:00' - INTERVAL 0 SECOND); # 1257055200

偶数 FROM_UNIXTIME() でも正確な時刻を返さない。

SELECT UNIX_TIMESTAMP(FROM_UNIXTIME(1257051599)); # 1257051599
SELECT UNIX_TIMESTAMP(FROM_UNIXTIME(1257051600)); # 1257055200

変な話ですが、DATETIME は、夏時間が始まったときに、quot;lost" 時間内の時間を保存して返します (文字列形式のみ!)。 2009-03-08 02:59:59 ). しかし、MySQL 関数でこれらの日付を使用することは危険です。

SELECT UNIX_TIMESTAMP('2009-03-08 01:59:59'); # 1236495599
SELECT UNIX_TIMESTAMP('2009-03-08 02:00:00'); # 1236495600
# ...
SELECT UNIX_TIMESTAMP('2009-03-08 02:59:59'); # 1236495600
SELECT UNIX_TIMESTAMP('2009-03-08 03:00:00'); # 1236495600

要点は を保存し、取り出す必要がある場合 ごとに を保存し、取り出す必要がある場合、いくつかの望ましくない選択肢があります。

  1. システムのタイムゾーンを GMT + ある一定のオフセットに設定する。例: UTC
  2. 日付をINTで保存(Aaronが発見したように、TIMESTAMPは信頼性すらない)。

  3. DATETIME型が、ある一定のオフセットタイムゾーンを持つように見せかけます。例:もしあなたが America/New_York にいるならば、日付を GMT-5 に変換します。 が MySQL の外部で に変換し、DATETIMEとして保存します(これは重要であることが判明しました:Aaronの回答を参照してください)。MySQL の日付/時刻関数の使用には十分な注意が必要で、システム タイムゾーンの値を想定するものもあれば、タイムゾーンに依存しないものもあります(特に時刻演算関数)。

Aaron と私は、自動生成される TIMESTAMP 列も壊れていると考えています。両方とも 2009-11-01 01:30 -04002009-11-01 01:30 -0500 は、曖昧な 2009-11-01 01:30 .