GroovyのStringを引数に取るDateのコンストラクタは「1582/01/01」-「1582/10/14」の期間に予想外の値を返す

そもそもコンストラクタだけなのかどうかも調べてないですが。。。

結論

Groovyで「1582/01/01」〜「1582/10/14」は正しく日付がとれなかった。

  • 少なくてもStringを引数に取るコンストラクタを使用した場合。(他は調べてない。)
assert new Date("1582/10/15") as String == "Fri Oct 15 00:00:00 JST 1582" // 1582/10/15以降は正常
assert new Date("1582/10/14") as String == "Thu Oct 04 00:00:00 JST 1582"
assert new Date("1582/10/05") as String == "Tue Sep 25 00:00:00 JST 1582"
assert new Date("1582/10/04") as String == "Mon Sep 24 00:00:00 JST 1582"
assert new Date("1582/01/01") as String == "Fri Dec 22 00:00:00 JST 1581"
assert new Date("1581/12/31") as String == "Sun Dec 31 00:00:00 JST 1581" // 1581/12/31以前は正常
assert new Date("1581/01/01") as String == "Sun Jan 01 00:00:00 JST 1581"
assert new Date("1000/01/01") as String == "Mon Jan 01 00:00:00 JST 1000"
  • 多分、Groovyで追加しているこのコンストラクタの実装がそんな感じになっている。
  • っというか、多分そこで使っているJavaのクラスの仕様だと思われる。

環境

[c:\]
$ java -version
java version "1.8.0_20"
Java(TM) SE Runtime Environment (build 1.8.0_20-b26)
Java HotSpot(TM) Client VM (build 25.20-b23, mixed mode, sharing)
[c:\]
$ groovy -version
Groovy Version: 2.3.4 JVM: 1.7.0_51 Vendor: Oracle Corporation OS: Windows 7

蛇足というかなんでこんな事に気づいたとか。

  • ↓を読んで、Groovyで試してみたら予想外な値を返してビックリする。

いろんなプログラミング言語で1582年10月5日を扱ってみる| mwSoft

  • 下記のコードは正しく動かないのは何故?
def d = "1582/10/05"
Date dt1 = new java.text.SimpleDateFormat("yyyy/MM/dd").parse(d);
assert dt1 == new Date(d) // Assertion failed
  • Javaは「1582/10/05」を渡すと「1982/10/15」として処理されるけど、GroovyのStringを引数にとるコンストラクタに「1582/10/05」を渡すと「1582/09/25」となる。っという事に気づく。
def d1 = "1582/10/05"
def javaDate1 = new java.text.SimpleDateFormat("yyyy/MM/dd").parse(d1)
assert javaDate1 as String == "Fri Oct 15 00:00:00 JST 1582"

def groovyDate1 = new Date(d1)
assert groovyDate1 == "Tue Sep 25 00:00:00 JST 1582"
  • で、↑の結論に至るという話。
assert new Date("1582/10/15") as String == "Fri Oct 15 00:00:00 JST 1582" // 1582/10/15以降は正常
assert new Date("1582/10/14") as String == "Thu Oct 04 00:00:00 JST 1582"
assert new Date("1582/10/05") as String == "Tue Sep 25 00:00:00 JST 1582"
assert new Date("1582/10/04") as String == "Mon Sep 24 00:00:00 JST 1582"
assert new Date("1582/01/01") as String == "Fri Dec 22 00:00:00 JST 1581"
assert new Date("1581/12/31") as String == "Sun Dec 31 00:00:00 JST 1581" // 1581/12/31以前は正常
assert new Date("1581/01/01") as String == "Sun Jan 01 00:00:00 JST 1581"
assert new Date("1000/01/01") as String == "Mon Jan 01 00:00:00 JST 1000"