Ruby: 年に1度だけ発生する夏時間バグ(翻訳)

概要

原著者の許諾を得て翻訳・公開いたします。

日本語タイトルは内容に即したものにしました。

Ruby: 年に1度だけ発生する夏時間バグ(翻訳)

特定の状況でのみ発生するバグがあります。そうしたバグのひとつを踏んだのがまさに今日だったのです(これがヒント)。

小さな変更を加えてpushしたところ、ビルドに失敗しました。修正箇所に対応するテストも更新済みだったので、ビルドの失敗は想定外でした。

例外が発生したのはTicketTransferPolicyという、今回の変更と何の関係もない部分でした。そういうわけで調査を開始しました。

raise DeadlinePassed  if deadline_passed?(event)
def deadline_passed?(event)
  if FT.on?(:extended_tickets_transfer_deadline, organizer_id: event.user_id)
    event.ends_at < Time.current
  else
    event.starts_at < Time.current.advance(days: 1)
  end
end

ヒント: テストの失敗はdeadlineの延長とは無関係です。

失敗したテストをじっくり見てみたところ、ふいに次の行が目に止まりました。

event = test_organizer.create_published_event(starts_at: 25.hours.from_now)

その瞬間なるほどと腑に落ちました。今日は1日が25時間になる日じゃないですか。

訳注: 多くの場合夏時間が始まる日は1日が23時間、夏時間が終わる日は1日が25時間という扱いになります。ただし一部地域では1時間ではなく30分や45分のずれになるところもあります。

個人的には、ここでは25.hours.from_nowではなくTime.current.advance(days: 1, hours: 1)というテストを書くのが、テストの一貫性からもベストだと思います。2526に変えても動きますが😢。

それもこれも夏時間(DST、サマータイムとも)のおかげですよ😜。

関連記事

Ruby: injectとeach_with_objectをうまく使い分ける(翻訳)

Ruby: 問題解決に「再帰」を使った話(翻訳)

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833 コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。 これまでにRuby on Rails チュートリアル第2版の半分ほど、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れてそれぞれ一部を翻訳。 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 実は最近Go言語が好き。 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ