タイトル大げさだけど実用的なテクニックなのでおすすめです。
タイムゾーンをまたぐ複数拠点でソフトウェア開発をしていると、日付処理に関するコードのテストが特定の拠点でだけ頻繁に落ちることがある。考えなしにローカルタイムを使うのは論外だが、うっかり書いてテストもレビューもパスしてしまうことはあるし、タイムゾーンを意識したテストコードを書いてるにもかかわらず時間帯合わせが漏れてしまうこともある。
こういうテストはフラストレーションがたまるし発見も修正もけっこう難しいので、 Fail-fast の精神でテスト実行時のタイムゾーンを「誰のローカルタイムゾーンでもない」ものにしてしまうとよい。根本的な解決にはならないが、壊れ方がそこそこ分散するので不公平感が減る。
具体的には、 RSpec でいうと spec_helper.rb
にこう書く。 Quipper の場合 London (GMT、しかしサマータイム期間中は BST UTC+1) Tokyo (UTC+9) Manila (UTC+8) に開発者がいるので、どれでもない EST (UTC-5) に設定している。
# It's good idea to set timezone to somewhere other than GMT / London / Tokyo to detect timezone bugs Time.zone = TZInfo::Timezone.get('EST')
この状態で、指定したタイムゾーンにおける現在時刻 Time.zone.now
UTC における現在時刻 Time.now.utc
ローカルタイムゾーンにおける現在時刻 Time.now
をみるとそれぞれこういう感じになる。ローカルタイムゾーンはもちろん Asia/Tokyo (UTC+9)
p Time.zone p [Time.zone.now, Time.now.utc, Time.now] #=> #<ActiveSupport::TimeZone:0x007f98e51412b8 @name="EST", @utc_offset=nil, @tzinfo=#<TZInfo::DataTimezone: EST>, @current_period=#<TZInfo::TimezonePeriod: nil,nil,#<TZInfo::TimezoneOffset: -18000,0,EST>>>> #=> [Thu, 30 Jul 2015 21:13:41 EST -05:00, 2015-07-31 02:13:41 UTC, 2015-07-31 11:13:41 +0900]
EST と BST では 6 時間ずれるので、このように日付が変わってしまうこともそこそこの頻度でおこる。もちろん EST と JST ならもっとずれるし日付がずれる頻度も多い。こうやって時刻操作に関する知見を深めつつ、タイムゾーンへのリテラシーを高めている。
Quipper メキシコオフィス(メキシコシティ)で開発者を採用したら UTC-6 (夏時間は UTC-5) なのでちょうどよさそう。いまはまだ開発者ポジションは募集してないけど、メキシコとかラテンアメリカで教育サービスの開発をしたいんや!というガッツのある方はご連絡ください。
バランスを考えるとロシア (モスクワ, UTC+3) インド (UTC+5:30) ハワイ (UTC-10) ニュージーランド (UTC+12) あたりにも開発拠点欲しくなってきた。オーストラリア (タスマニア, UTC+10) にはパートタイムの開発者が一人いるけど JST とほぼ差がないので「散らし」の観点ではあまり意味がなくて残念。