1000/02/29をRubyでinvalidな日付として扱う方法、もしくはRubyで1582年以前の暦をユリウス暦ではなくグレゴリオ暦で扱う方法

結論

RubyのDateクラスには startを引数に指定できるメソッドがある。 docs.ruby-lang.org startはグレゴリオ暦をつかい始めた日をあらわすユリウス日を表す。 引数のstartにDate::GREGORIANを指定すると、常にグレゴリオ暦で処理してくれる。

Date.valid_date?(1000, 2, 29, Date::GREGORIAN)
=> false

Date.parse('1000-2-29', true, Date::GREGORIAN)
=> ArgumentError (invalid date) 

経緯

MySQLは日付カラムに 1000-2-29 をいれるとinvalidな日付として扱われエラーになるが、RubyのDate#valid_date?メソッドを使って判定するとtrueが返ってくる。
これはMySQL先発グレゴリオ暦を使っているからだった*1

先発グレゴリオ暦とは、1582年から施行されたグレゴリオ暦暦法を、1582年以前にも適用したものである。

なのでユリウス暦だと1000-2-29 は存在するが、グレゴリオ暦だと 1000-2-29 は存在しないということらしい。

で、本題だが、Ruby1000-2-29をinvalidな日付として判定する方法がないか探してみたところ、上の結論に行きついた。

参考

MySQL :: MySQL 5.6 リファレンスマニュアル :: 12.8 MySQL で使用されるカレンダー

tech.furyu.jp

*1:標準SQLがそうなのでPostgreSQLも先発グレゴリオ暦を使っている