web-dev-qa-db-ja.com

タイムゾーン情報を使用してMySQLに日時を保存する方法

タンザニアで撮影された何千枚もの写真があり、各写真が撮影された日付と時刻をMySQLデータベースに保存したいと思います。ただし、サーバーは米国にあり、春の夏時間(米国)の「無効」時間内にあるタンザニアの日付時刻を保存しようとすると、問題が発生します。タンザニアはDSTを行っていないため、時刻は実際に有効な時刻です。

さらに複雑なのは、データベースに保存されている日時の値にアクセスする必要のあるさまざまなタイムゾーンの協力者がいることです。私は彼らにalwaysであり、さまざまな協力者がいる現地時間ではなく、タンザニアの時間として出てほしい。

誰かがセッション時間を設定するのを忘れてしまい、時間をまったく間違えると問題が発生することを知っているので、私はセッション時間を設定することに消極的です。そして、私はサーバーについて何も変更する権限を持っていません。

読みました: 夏時間とタイムゾーンのベストプラクティス および MySQL日時フィールドと夏時間-「余分な」時間を参照するにはどうすればよいですか および- PHP/MySQLでUTCとして日時を保存する

しかし、それらのどれも私の特定の問題に対処していないようです。私はSQLの専門家ではありません。 DATETIMEを設定するときにタイムゾーンを指定する方法はありますか?まだ見ていません。それ以外の場合は、この問題に対処する方法に関する提案を歓迎します。

編集:これは私が遭遇している問題の例です。コマンドを送信します:

INSERT INTO Images (CaptureEvent, SequenceNum, PathFilename, TimestampJPG) 
VALUES (122,1,"S2/B04/B04_R1/IMAG0148.JPG","2011-03-13 02:49:10")

そして、私はエラーを取得します:

Error 1292: Incorrect datetime value: '2011-03-13 02:49:10' for column 'TimestampJPG'

この日付と時刻はタンザニアにありますが、データベースがある米国にはありません。

57
mkosmala

あなたが言った:

さまざまな協力者がいる現地の時間ではなく、常にタンザニアの時間として出てくるようにしたいです。

その場合は、UTCを使用しないでくださいnot。必要なことは、DATETIME型の代わりにMySQLでTIMESTAMP型を使用することだけです。

MySQLドキュメントから

MySQLはTIMESTAMP値を現在のタイムゾーンから保存のためにUTCに変換し、取得のためにUTCから現在のタイムゾーンに戻します。 (これは、DATETIMEなどの他のタイプでは発生しません。)

DATETIME型を使用しているalreadyである場合、ローカル時間までに設定してはいけません。ここでは説明しませんでしたが、データベースではなく、アプリケーションコードに重点を置く必要があります。問題と解決策は言語によって大幅に異なるため、質問には必ずアプリケーションコードの適切な言語でタグを付けてください。

51

あなたが説明するすべての症状は、どのタイムゾーンを使用するかをMySQLに決して伝えないことを示唆しているので、デフォルトはシステムのゾーンになります。考えてみてください。もしそれが'2011-03-13 02:49:10'だけなら、それが地元のタンザニアの日付だとどうやって推測できますか?

私の知る限り、MySQLは日付のタイムゾーン情報を指定する構文を提供していません。 接続ごと ;に変更する必要があります。何かのようなもの:

SET time_zone = 'EAT';

これが機能しない場合(名前付きゾーンを使用するには、 サーバーが構成されている が必要です。そうでない場合がよくあります)、UTCオフセットを使用できます。

SET time_zone = '+03:00';
5

MySQLはDATETIMEタイムゾーン情報なしで保存します。たとえば、「2019-01-01 20:00:00」をDATETIMEフィールドに格納すると、知っているはずの値を取得するときにそれが属するタイムゾーン。

したがって、あなたの場合、DATETIMEフィールドに値を保存するときは、タンザニア時間であることを確認してください。それからそれを取り出すとき、それはタンザニアの時間になります。わーい!

さて、難しい質問は次のとおりです。INSERT/ UPDATEを行うとき、値がタンザニア時間であることを確認するにはどうすればよいですか。 2つのケース:

  1. INSERT INTO table (dateCreated) VALUES (CURRENT_TIMESTAMP or NOW())を実行します。

  2. INSERT INTO table (dateCreated) VALUES (?)を実行し、アプリケーションコードから現在の時刻を指定します。

ケース#1

MySQLは現在の時間を使用します。つまり、タンザニア時間の「2019-01-01 20:00:00」です。次に、MySQLはUTCに変換し、これは「2019-01-01 17:00:00」になり、that値をフィールドに入力します。

それでは、タンザニアの時間(「20:00:00」)を取得して、フィールドに格納するにはどうすればよいですか?不可能です。このフィールドから読み取る場合、コードはUTC時間を想定する必要があります。

ケース#2

?として渡す値のタイプによって異なります。 「2019-01-01 20:00:00」という文字列を渡すと、それが適切です。これがまさにDBに保存されます。何らかのDateオブジェクトを渡す場合、dbドライバーがそのDateオブジェクトをどのように解釈するか、最終的には「YYYY-MM -DD HH:mm:ss '文字列は、ストレージ用にMySQLに提供します。 dbドライバーのドキュメントをご覧ください。

4
Hai Phan