web-dev-qa-db-ja.com

MySQLがTIMESTAMPをINTEGERに変換する-タイムゾーン

MySQL(InnoDB)DBで一部のTIMESTAMPフィールドをINTに変換する必要があります。 TIMESTAMPをINTに変換するのは珍しいことだと思いますが、それでもまだ必要です:)

それを行うのは簡単なようですが、いくつかのタイムゾーンと夏時間のエラーがあります。

列ごとにSQLコードを生成するスクリプトがあります。たとえば、以下を生成します。

_ALTER TABLE alarmLog ADD COLUMN started_tmp INT UNSIGNED;
UPDATE alarmLog SET started_tmp = UNIX_TIMESTAMP(started);
ALTER TABLE alarmLog DROP started;
alter TABLE alarmLog CHANGE started_tmp started INT UNSIGNED NULL DEFAULT 0;
_

select FROM_UNIXTIME(1291788036);を使用して前後のデータを比較すると、結果は良好です。

次に、すべてのクライアント側ソフトウェアをUTCに変換するように変更し、そのINTを格納するときに使用します。取得すると、そのINTは現在のタイムゾーンに変換されます。

しかし、その後、ドキュメント 警告する このシナリオについて(CETの夏時間):

_mysql> SELECT UNIX_TIMESTAMP('2005-03-27 02:00:00');
+---------------------------------------+
| UNIX_TIMESTAMP('2005-03-27 02:00:00') |
+---------------------------------------+
|                            1111885200 |
+---------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT UNIX_TIMESTAMP('2005-03-27 03:00:00');
+---------------------------------------+
| UNIX_TIMESTAMP('2005-03-27 03:00:00') |
+---------------------------------------+
|                            1111885200 |
+---------------------------------------+
1 row in set (0.00 sec)
_

APIとOSは通常どのように夏時間に対応しますか?私のPCにはUTCの時計があり、夏にはOSに2時間、冬には1時間追加されます。私はそれがDSTであるかどうかを決定するためにUTC時間を使用すると思います。

それで、私はこれにどのように対処しますか? DSTオフセットを指定するためにデータベースにフィールドを追加する唯一の解決策はありますか?

11
Halfgaar

INTに時間を格納する必要はありません。 MySQLのTIMESTAMP型はとにかくそれを行い(標準のUNIXタイムスタンプを使用して時刻を格納します)、それらは常にUTCです。

セッションのタイムゾーンを設定するだけでよく、すべてのTIMESTAMP列は、更新または選択したときにゾーンとの間で変換されます。

接続/初期化時にゾーンを一度設定できます。

SET time_zone = '+10:00';

そして、あなたはあなたのゾーンの時間を直接選択/更新することができます

SELECT timesamp_column FROM table ...

日時ライブラリーについてはあまり詳しくありませんが、提供されたタイムゾーンと問題の時間を使用して、タイムゾーンと夏時間のオフセットを決定していると思います。

あなたが提供した例では、クロックは01:59:59から03:00:00にジャンプし、02:00:00は実際には発生しなかったため、値の1つは実際には無効であると思います。その場合、UNIX_TIMESTAMP関数はおそらく最も近い秒を返します。

6
Vatev