AWSのRDSはUTC固定って知ってましたか?

こんにちは!ぐちです。

AWS RDS

AWSもだいぶ有名になりご利用されている方もいらっしゃると思いますがRDSにてMySQLを使っていた際にハマったといいますか知ったことをご紹介します。

タイムゾーン

サーバなどのコンピュータにはそれがどこの地域を基準に動作しているかを示すタイムゾーンというものを設定することができるのですがAWSのRDSではそれを変更することができません。UTC(Coordinated Universal Time)という協定世界時という世界各地での標準時が基準となっております。

日本のタイムゾーン

日本は国内の標準時間をJSTとして定めておりUTCより9時間進んでいることになります。よく「+0900(JST)」といった表記をみませんか?これはUTCよりプラス9時間ですよという表示になります。各地域でこのプラスやマイナスの時間が異なります。詳しくは協定世界時(Wikipedia)を参照ください。

RDSでの現在日時

日本国内からRDSのMySQLでcurrent_timestampを取得すると現在時刻より9時間遅い時間が取得できるかと思います。

mysql> select current_timestamp;
+---------------------+
| current_timestamp   |
+---------------------+
| 2015-12-03 04:19:23 |
+---------------------+
1 row in set (0.00 sec)

mysql>

上記の結果で何が困るかと言いますとBETWEEN句などを使って今日が登録している日付の範囲内かどうかを判定する際に登録データは日本時間を標準に登録されていたら正確に範囲の判定ができなくなります。

select * from tbl_hoge where current_timestamp between start_date and finish_date;

上記のような感じですね。この場合はcurrent_timestampはUTC時刻を返しstart_datefinish_dateはJST時刻が入っていたら時間単位まで正確に判定することができません。

そこでどういった対応をするかといいますと、、

INTERVAL句

interval句を使います。上記のSQLを正確に判定するには下記のように9時間追加する必要があります。

select * from tbl_hoge where current_timestamp + interval 9 hour between start_date and finish_date;

下記のように国内の標準時間の結果を得られます。

mysql> select current_timestamp + interval 9 hour;
+-------------------------------------+
| current_timestamp + interval 9 hour |
+-------------------------------------+
| 2015-12-03 13:27:13                 |
+-------------------------------------+
1 row in set (0.00 sec)

mysql>

日本国内に限定したWebサービスであれば上記の対応で問題なく動作させることができますが世界共通で動いているシステムであればそうも簡単にいきません。UTCからの差異をテーブルなどに保持してアクセス元の地域時刻との計算を行う必要があります。

この記事を書いたのがお昼時ってバレちゃいますね。笑

では今回はこの辺で。