LoginSignup
6
5

More than 5 years have passed since last update.

うるう日爆弾 [SimpleDateFormat]

Last updated at Posted at 2016-03-01

先日のうるう日に関するバグについてメモ

❐事例 : SimpleDateFormat クラスにて日付をParseした際に予期せぬ日付が返却

サンプルソース

java

public class DateUruuYear {

    public static void main(String args[]){
        // うるう年テスト
        //----------------------------------------------------
        SimpleDateFormat fmt = new SimpleDateFormat("MM/dd");

        try{
            fmt.setLenient(false);
            Date dt = fmt.parse("02/29");
            System.out.println(dt.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


□概要

上記のコードの場合、
parseする際に"yyyy"の指定がないと、デフォルトの1970年が入る動きになるみたい。
1970年はうるう年じゃないので"1970/2/29"なんて日付は存在しないので、
日付変換でparseエラーになるというのが想定されます。
しかし、

"1970/03/01"の日付で正常終了して日付が流れてしまった。

というのが今回の落とし穴。。

ちゃんとsetLenient(false)しているのにと、思ったところです。

そもそも "MM/dd"のみでDate変換していることが良くないのですが、

日付チェックしていればParseExceptionが発生して落ちるところが落ちなかったことが
影響を与えたましたと。

□原因

調査した結果、

Java1.4環境だと、setLenient(false)効かない

とのことがわかりました。
自分で立証したわけではないので断言出来ないのですが、
少し調査してみると、確かにバージョンの部分は非互換であるそうです。

SimpleDateFormat returns incorrect date on jdk1.4
http://stackoverflow.com/questions/2385588/simpledateformat-returns-incorrect-date-on-jdk1-4
●回答
Only a gues, there is a bug for java 1.4, for ignoring the setLenient(false) setting.
Java 1.5 does not have this bug and since there are no 20 months in a year fails to parse your input and returns null instead.

(このページでは2500年が返却されるって記載があるけど、そうなのかな。。)

□検証

Java1.4をアーカイブから自端末に入れてみようと思ってインストールしてみようかとおもったけど、
Eclipse(Merse)がjre認識してくれなかったので時間の関係上検証出来ずにクローズすることにしました。。
(Win10 64bitとかでは使えないのかな。深追いできずです。)
情報少なくてすみません。。

自分も地雷を埋め込むことのないように気をつけます。

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5