2

日付を解析するための次のコードがあります。

public Boolean isDate(String date, String dateFormat) {
        try {
            DateTimeFormat.forPattern(dateFormat).parseDateTime(date);

        } catch(Exception e) {
            return false;
        }

        return true;

    }

20071001これは、 formatのように最近の日付でうまく機能しますyyyyMMdd。ただし、1970 年より前の日付の場合19600101、同じ形式の と同様yyyyMMddに、メソッドは false を返します。

これをどのように整理できるかについてのアイデアは、非常に高く評価されます。

アップデート:

私が得る例外は次のとおりです。

Cannot parse "19400101": Illegal instant due to time zone offset transition (Africa/Nairobi)

そして、これは私がメソッドを呼び出す方法です:

if(validationUtils.isDate(propVal, dateFormat) == false) {
                    String msg = "Not a valid DATE";
                    Quartet<String, String, String, String> t = new Quartet<String, String, String, String>(recNo, field, propVal, msg);
                    errors.add(t);
                }

メソッドを含むクラスisDateは、私が使用してワイヤリングする Bean@Autowired IValidationUtils validationUtilsです。これは私が行っている唯一の検証ではありません。他の検証は成功し、これにより、問題は Joda Time にあるという結論に至りました。

更新(解決策):

@Ettieneの提案(以下の回答)に従って、問題の解決策を得ました。改訂された作業コードは次のとおりです。

public Boolean isDate(String date, String dateFormat) {
        try {
            DateTimeFormatter fmt = DateTimeFormat.forPattern(dateFormat);
            DateTime dt = fmt.withZone(DateTimeZone.UTC).parseDateTime(date);

        } catch(Exception e) {
            return false;
        }

        return true;

    }
4

2 に答える 2

2

この問題は、冬時間から夏時間への移行に関連しているようです。問題は、移行のために一部のタイムゾーンで一部の日付が有効でないことです。

たとえば、フランス/パリのタイムゾーンでは、2013-03-31T02:30 は無効です。これは、この日の午前 2 時に冬時間から夏時間への切り替えが行われたためです。したがって、2013-03-31T01:59 の次の分は 2013-03 です。 -31T03:00。

あなたのタイムゾーン、okello では、1970 年以前は、移行は 1 月 1 日の真夜中に起こっていたと思います。したがって、1960-01-01T00:00 は無効です (ただし、1959-12-31T00:00 および 1960-01-02T00:00 は有効です)。

時刻が指定されていない場合は、午前 0 時と見なされることに注意してください。

于 2013-05-15T12:54:37.610 に答える
1

使用しないparseDateTime()、使用するparseLocalDate()(2.0 以降で使用可能)

これは概念的に正しい方法であり (datetime ではなく日付を解析している)、堅牢です (タイムゾーン、DST 移行、および問題とは完全に無関係なすべてのものについて心配する必要はありません)。

さらに、 catch のみを使用しIllegalArgumentException、他の例外は別の方法で再スローまたはキャッチする必要があります。

于 2013-05-16T17:24:16.500 に答える