Rubyで うるう秒 の表現
Google Apps Scriptでうるう秒は問題になるか を考えた時に、Rubyでは うるう秒(閏秒)をどう扱うのか気になりました。
2012年6月31日(GMT)にうるう秒がありました(ちょっと古い話ですいません)。手元の環境で、特に何も指定せずにうるう秒の時刻を指定すると
% ruby -e 't=Time.utc(2012, 6, 30, 23, 59, 59); (0..2).each{|n| puts [t+n, (t+n).to_i].join(" # ") }'
2012-06-30 23:59:59 UTC # 1341100799
2012-07-01 00:00:00 UTC # 1341100800
2012-07-01 00:00:01 UTC # 1341100801
となり、うるう秒は無かったように扱われます。
しかし、ここで環境変数 TZ
を使うと
% TZ=right/Japan ruby -e 't=Time.utc(2012, 6, 30, 23, 59, 59); (0..2).each{|n| puts [t+n, (t+n).to_i].join(" # ") }'
2012-06-30 23:59:59 UTC # 1341100823
2012-06-30 23:59:60 UTC # 1341100824
2012-07-01 00:00:00 UTC # 1341100825
と見事にうるう秒が表現されました。
このうるう秒は25回目のうるう秒なので #to_i()
で取得できる起算時からの経過秒数も25秒ずれています。
この日は一日の秒数も 86400秒ではなく
% TZ=right/Japan ruby -e 't1=Time.utc(2012, 6, 30); t2=Time.utc(2012, 7, 1); p t2-t1'
86401.0
86401秒になってますね。次の日を計算するために86400を足すコードはトラブルを生みそうです。
開発者の注意
Time
がうるう秒をどう扱うかは実行時の環境変数に依存するので、コードを書く人はそこのところを忘れないようにしないといけません。気まぐれな?システム管理者がrightにしてるかも。
DateTimeクラスの憂鬱
date
ライブラリのDateTime
クラスではうるう秒は扱えません。
% TZ=right/Japan ruby -r date -e 't=Time.utc(2012, 6, 30, 23, 59, 59); (0..2).each{|n| puts [t+n, DateTime.parse((t+n).to_s)].join(" # ") }'
2012-06-30 23:59:59 UTC # 2012-06-30T23:59:59+00:00
2012-06-30 23:59:60 UTC # 2012-06-30T23:59:59+00:00
2012-07-01 00:00:00 UTC # 2012-07-01T00:00:00+00:00
Ruby以外
環境変数TZを使う言語や環境は、もちろんRubyに限りません。date
コマンドもそうですね。下の参考記事を参照してください。
Pythonでは
https://docs.python.jp/3/library/datetime.html
time モジュールと違い、 datetime モジュールはうるう秒をサポートしていません。
のようで、Rubyと似ていますね。(Rubyが似てるのか)
JavaScriptではうるう秒は扱わないようです。
In time values leap seconds are ignored. It is assumed that there are exactly 86,400,000 milliseconds per day.
関連記事
Google Apps Scriptでうるう秒は問題になるか
参考
Ruby 2.4.0 リファレンスマニュアル Timeクラス
https://docs.ruby-lang.org/ja/latest/class/Time.html
Linux Programmer's Manual (3) Man page of TZSET
https://linuxjm.osdn.jp/html/LDP_man-pages/man3/tzset.3.html
RubyとRailsにおけるTime, Date, DateTime, TimeWithZoneの違い
http://qiita.com/jnchito/items/cae89ee43c30f5d6fa2c
Ruby, MySQL のうるう秒の扱い - @tmtms のメモ
http://tmtms.hatenablog.com/entry/2015/01/10/leap-second
Linux 2015/7/1 うるう秒調査 - dropooiの日記
http://dropooi.hatenablog.com/entry/20150131/1422713365