この記事は ex-mixi Advent Calendar 2017 22 日目のエントリーです。
こんにちは、sota2502です。
mixiには2008年の新卒で入り、2015年の6月まで、なので7年3ヶ月在籍していました。
一貫してSNS mixiのサービスに関わっていて、その中で、メッセージ → 日記 → つぶやき → ページ → コミュニティと担当サービスを変えていました。
その後、10ヶ月ほど税務関連のシステム開発を行い、現在はFiNCでヘルスケア関連のシステム開発に携わっています。
今回は、mixiとFiNCの間に在籍した会社で直面した日本のサマータイム問題について書きました。
日本のサマータイム問題(1948-1951年)
これは以前 Qiitaにも記事を書きました。
あるユーザーの誕生日をdatetimeでMySQLに保存しておき、それをTomcatのアプリがXHRでブラウザに返して、JavaScriptでDateオブジェクトにして表示していました。
しかし、このとき、例えば 1951-05-07 00:00:00
をUnixTimeにしてブラウザに返し、JavaScriptでDateにすると 1951-05-06
になるという現象に遭遇しました。
これは1948年から1951年のGHQ統治下でサマータイムが導入されており、このサマータイムの調整のために、ある時点で1時間分調整が入りUnixTimeが1時間ずれます。
そのため、さきほどの 1951-05-07 00:00:00
のUnixTimeはJavaScriptでは 1951-05-06 23:00:00
と解釈されます。
このときJava側の変数のTimeZoneは JST
ではなく JDT
となります。
Ruby
Java以外の、他の言語ではどうなってるかが気になったので調べました。
まずはRubyです。
p Time.local(1951, 5, 7, 0, 0, 0).zone
=> "JDT"
ということでサマータイムに対応しています。
もう少し詳しく見ていきます。
(0..3).each do |hour|
dt = Time.local(1951, 5, 6, hour, 0, 0)
p [dt, dt.zone, dt.dst?]
end
=> [1951-05-06 00:00:00 +0900, "JST", false]
[1951-05-06 01:00:00 +0900, "JST", false]
[1951-05-06 03:00:00 +1000, "JDT", true]
[1951-05-06 03:00:00 +1000, "JDT", true]
1951-05-06 02:00:00
でサマータイムになります。
Perl
今度はPerlで見ていきます。
ここではDateTimeを使っています。
use strict;
use warnings;
use DateTime;
foreach my $hour (0..3) {
eval {
printf "1951-05-06 %02d:00:00\n", $hour;
my $dt = DateTime->new(
year => 1951,
month => 5,
day => 6,
hour => $hour,
minute => 0,
second => 0,
time_zone => 'Asia/Tokyo',
);
printf "%s, %s\n", $dt->time_zone->name, $dt->is_dst;
};
print $@ if ( $@ );
}
結果は以下のようになります。
1951-05-06 00:00:00
Asia/Tokyo, 0
1951-05-06 01:00:00
Asia/Tokyo, 0
1951-05-06 02:00:00
Invalid local time for date in time zone: Asia/Tokyo
1951-05-06 03:00:00
Asia/Tokyo, 1
PerlのDateTimeでも JDT
を扱ってはくれています。
しかし、1951-05-06 02:00:00
を与えるとオブジェクトの生成に失敗しました。
コードを追っていくと DateTime::TimeZone
でoffsetを算出する際に、_spans_binary_searchで JDT
や JST
ごとに持っているrangeと与えられた時間の比較してoffsetを決定しているのですが、 1951-05-06 02:00:00
の場合はこのoffsetの取得に失敗し、 最終的にTimeZoneオブジェクトが作れなくなっていました。
まとめ
真面目にタイムゾーンについて考えたのは サハラ砂漠にマラソン しにいって以来でした。
いやー、タイムゾーンってホントに奥が深いですね!
時間の関係で他の言語については調べられませんでしたが、いつか他の言語での扱いも調べたいと思います。
明日は hnakagawa さんのエントリです。
よろしくお願いします。