高木のブログ

【Ruby】存在しない日付に対してのDate.parseとTime.parseの挙動の違い

2020/12/04

毎月29日対してにごにょごにょしないといけない要件があり、以下のようにDate.parseメソッド使った。

Date.parse('29')
#=> #<Date: 2020-12-29 ((2459213j,0s,0n),+0s,2299161j)>

# 引数が文字列2桁だとその月の日にちになる

これで問題ないと思ったが、閏年ではない年の2月の場合、29日が存在しないのでコケることが判明。 (閏年ではない年のこと平年いうらしい。以下、平年という。)

条件分岐で2月だけいい感じにするコードを書かないといけないのはなんだかなと思っていたが、結論から言うとTime.parseに変更し、.to_dateすることで事なきを得た。

Time.parse('29').to_date
#=> #<Date: 2020-12-29 ((2459213j,0s,0n),+0s,2299161j)>

挙動の違い

2パターンだけだが、挙動を確認したので記録として残しておく。

平年の2月29日

Date.parseはinvalid dateになるのに対し、Time.parseは次の日になる。

require 'date'
Date.parse('2021-02-29')
#=> Date::Error (invalid date)

require 'time'
Time.parse('2021-02-29')
#=> 2021-03-01 00:00:00 +0900

絶対存在することがない3月32日

流石にTime.parseでもダメっぽい。

require 'date'
Date.parse('2021-03-32')
#=> Date::Error (invalid date)

require 'time'
Time.parse('2021-03-32')
#=> ArgumentError (argument out of range)

参考

Ruby 日付が存在するか知りたい - かもメモ


Written by ytkg, Twitter, GitHub

Pixela