Ruby で 24 時超えの時間を楽ちんにパースする方法


はじめに

みなさん、2014-08-14 26:00 みたいな時間を扱おうとして困ってませんか?
文字として保存するだけならまだしも、これを元に現在時刻と比較して・・・とかやろうとすると色々大変です。

この記事ではそんな24時間超えの時間を楽ちんに扱うことができる Chronic という gem を紹介します。

そもそも何が困るのか

Ruby の time ライブラリには大変便利な Time.parse メソッドがあります。
が、困ったことにこいつは 26:00 みたいな時間は理解してくれません。
irb で実行してみると以下の様なエラーがでます。

>> Time.parse('2014-08-14 26:00')
ArgumentError: argument out of range

日付は 2014-02-31 とかでも良きに計らってくれるのに、時間はすごくきっちりしています。
24:00:00 までは通してくれますが、24:00:01 になるとエラーになります。
つまり、24時超えの時間を扱おうと思ったら「24時を過ぎていたら日付を一日進めて時間からは24引いて・・・」とかやったりしないといけないわけですね。
なんとめんどくさい!

でもご安心ください、世の中には便利な gem が存在してます。

Chronic で快適パース生活

24時超えの時間を扱いたい、けど自分で頑張って色々処理をするのはめんどくさい。
そんなあなたに Chronic

>> Chronic.parse('2014-08-14 26:00')
Fri, 15 Aug 2014 02:00:00 JST +09:00

この通り良きに計らってくれます、素敵ですね!
これ以外にも自然言語的な記述も良きに計らってくれて、以下の様な文字列もパースできます。

>> Chronic.parse('friday 13:00')
Fri, 15 Aug 2014 13:00:00 JST +09:00

これはすごい!
詳しくは Chronic のドキュメントの御覧ください、びっくりするくらい色々なフォーマットに対応しています。

参考:https://github.com/mojombo/chronic#examples

Rails と組み合わせて使うには

Chronic はデフォルトだと rubyTime クラスを使って時間を生成します。
つまり、Rails の Time.zone を利用してくれません。

そんな時でも大丈夫!
Chronic は時間を生成する際に利用するクラスを指定できるようになってます。

initializer で以下の様なコードを記述しておけば、Time.zone 経由で時間を作ってくれるようになります。

chronic.rb
Chronic.time_class = Time.zone

これでシステム時刻のタイムゾーンと Rails のタイムゾーンが合ってない、とかいう場合も安心です。

まとめ

Ruby や Rails で 24 時超えの時間を扱いたい場合は Chronic を利用するととても簡単にパースすることができます。
また、Railsとの組み合わせも容易にできるので、使い勝手もいいですね。

日付周りのパースで困ってる方は、ぜひお試しを。