QA@IT

apacheのcommons-validatorのDateValidatorについて質問です。

3159 PV

こちらのDateValidatorの動作について質問です。
http://commons.apache.org/proper/commons-validator/apidocs/org/apache/commons/validator/routines/DateValidator.html

この結果が、trueで返ってくるのはなぜでしょうか?

DateValidator.isValid("2013/03/1a","yyyy/MM/dd",true)

ちなみに、これだとfalseで帰ってきます。
DateValidator.isValid("2013/03/11a","yyyy/MM/dd",true)

これらは、trueで帰ってきます。
DateValidator.isValid("2013/03/1z","yyyy/MM/dd",true)
DateValidator.isValid("2013/03/9a","yyyy/MM/dd",true)

なぜなのでしょうか?

回答

どうやらお使いのDataValidatorクラスは、1.4では非推奨の方のDateValidatorを使っているようです。
非推奨:org.apache.commons.validator.DateValidator
1.4では:org.apache.commons.validator.routine.DateValidator

routineパッケージの方のDateValidatorで以下を試したところfalseになってました。
(非推奨のはtrueでしたね)

validator.isValid("2013/03/1a", "yyyy/MM/dd")

※ちなみに、1.4のDateValidatorの第3引数はロケールなどで、booleanは受け取りません。

編集 履歴 (0)
  • すごい!解らないから投げてしまってたんです。本当にありがとうございます!全然違う実装しちゃったお…。
    ほんとうにごめんなさい。この事はちゃんと今後に生かしますね!
    -

興味があったのでソースを見てみました。
環境は

  • Windows 8
  • JavaSE 1.7
  • commons-validator-1.4.0 です。

目的のソースは以下の様になっています。
SimpleDateFormatがパースできて("2013/03/1z" → "2013/03/1"にパースされます)、
厳密チェックがtrueの場合はフォーマットの文字列と長さが同じであればOK。
というつくりの様です。

2013/03/11a がfalseになるのは文字数が違うからということですね。

いろいろなフォーマットを受け入れられるとはいえ、
formatter.setLenient(false);
なのに通るんですねぇ。

public boolean isValid(String value, String datePattern, boolean strict) {

        if (value == null
                || datePattern == null
                || datePattern.length() <= 0) {

            return false;
        }

        SimpleDateFormat formatter = new SimpleDateFormat(datePattern);
        formatter.setLenient(false);

        try {
            formatter.parse(value);
        } catch(ParseException e) {
            return false;
        }

        if (strict && (datePattern.length() != value.length())) {
            return false;
        }

        return true;
    }
編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。