LoginSignup
3
2

More than 5 years have passed since last update.

Ruby等でのうるう秒とtimezone環境変数TZとの関係

Last updated at Posted at 2017-09-14

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

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2