はじめに
株式会社ピー・アール・オーのアドベントカレンダー15日目を書きます。
もうすぐクリスマスですがサマータイム問題について書きます。
具体的なバージョンは記載しませんがタグにある構成でサマータイムに該当する日付をMySQLに保存すると、なぜか1日マイナスされた日付が登録されてしまいました。
1948-07-02 を登録しようとすると 1948-07-01 が登録されてしまうといった感じです。
日本のサマータイムについて
自分は、そもそも日本にもサマータイムって導入されてたの!?というところからで、
意外だったのですが調べてみると戦後間もないころに導入されてた時期があったようです。
1948年(昭和23年) - 五月の第一土曜日の翌日(日曜)から九月の第二土曜日まで (附則第二項)
1949年(昭和24年) - 四月の第一土曜日の翌日(日曜)から九月の第二土曜日まで (本則)
1950年(昭和25年)及び1951年(昭和26年) - 五月の第一土曜日の翌日(日曜)から九月の第二土曜日まで (改> 正法)
1952年(昭和27年)以降 - 廃止
つまり下記の日付を登録しようとすると冒頭のような事象が発生することを確認しました。
1948-05-02(日)~1948-09-11(土)
1949-04-03(日)~1949-09-10(土)
1950-05-07(日)~1950-09-09(土)
1951-05-06(日)~1951-09-08(土)
対処法
PlayFrameworkのORMであるEbeanにおいては java.time.LocalDate が使えそうでタイムゾーンに依存することなく保存されること期待してたのですが、うまく保存することができず NULL が登録されてしまいました…
そもそもなにか認識が誤っているのか、扱いを間違えてるのかもしれません。
ひとまず下記のように1時間プラスして登録することにしました。
Date date;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
date = sdf.parse("1948-07-02 01:00:00");
} catch (ParseException e) {
System.out.println("An invalid date" + e.getMessage());
}
サマータイム以外の日付も1時間プラスしてることになりますが日付の登録なので特に問題はありません。
別のサマータイム問題も
冒頭にあげた事象の前に発生していた別の問題があったので、そちらについても紹介したいと思います。
サマータイムの開始日に問題がありまして、、、
サマータイムというのは1時間早めるという制度なので開始日である 1948-05-02 00:00 ~ 00:59 という時間帯は JST においては存在しない時間ということになります。
日本時間では以下の日時が存在しない。
1948-05-02 00:00 ~ 00:59
1949-04-03 00:00 ~ 00:59
1950-05-07 00:00 ~ 00:59
1951-05-06 00:00 ~ 00:59
なので上記の値を PlayFramework からMySQLに保存したときに例外発生しました。
対処法
MySQLの ServerTimezone をグリニッジ標準時 GMT+9時間と設定することで回避しました。
このあたりの日付を扱うシーンは少ないかもしれませんが誕生日を登録する機能でこの問題に遭遇しました。
以上、日本におけるサマータイム問題のご紹介でした。
最後まで読んで頂きありがとうございます。
尚、対処法に記載した内容については自分が対応したのではなく弊社のスペシャルなエンジニアが対応した対処法になります。
尊敬するエンジニアの1人です