Rubyで日付っぽい文字列を日時や日付に変換するときのこと
Chronicべんり。別に最近のものでもないのだけど、しらなかった。
それまではActiveSupportで頑張っていた。
require 'active_support/core_ext/object'
require 'date'
def parse_date_str(date_str)
case date_str
when /^yesterday$/i then 1.day.ago
when /^today$/i then 0.day.ago
when /^tomorrow$/i then 1.day.since
when /^[0-9]+[\.\s](?:days?|weeks?|months?|years?)[\.\s](?:ago|since)$/i
eval(date_str.gsub(/\s+/, '.'))
else
Date.parse(date_str)
end.to_date
end
parse_date_str '20110101' # => Sat, 01 Jan 2011
parse_date_str 'yesterday' # => Tue, 20 Mar 2012
parse_date_str '1 week ago' # => Wed, 14 Mar 2012
こんなコード書かなくてもよかったんだ!
require 'date'
require 'chronic'
def parse_date_str(date_str)
(Chronic.parse(date_str) || Date.parse(date_str)).to_date
end
parse_date_str '20110101' # => #<Date: 2011-01-01 ((2455563j,0s,0n),+0s,2299161j)>
parse_date_str 'yesterday' # => #<Date: 2012-03-20 ((2456007j,0s,0n),+0s,2299161j)>
parse_date_str '1 week ago' # => #<Date: 2012-03-14 ((2456001j,0s,0n),+0s,2299161j)>
Chronicはparseできなかったときはnilを返す。 Date.parseを残しているのは、YYYYMMDDみたいな形式も使いたかったからで、それを除けばだいたいChronicだけで充分だった。
戻り値の見た目(Date#inspect)が違うのはActiveSupportの拡張っぽい。