こんにちは、さるまりんです。
日付の文字列が有効か否かをチェックする方法です。
文字列をDateオブジェクトに変換
文字列を受け取ってそれがDate
オブジェクトに変換できたら有効、そうでなければ無効で考えてみました。
public boolean isValidDate(String str) {
// 日付文字列の形式はyyyy/MM/dd
DateFormat df = new SimpleDateFormat("yyyy/MM/dd");
Date dt;
try {
// 文字列strをDateに変換
dt = df.parse(str);
} catch (ParseException e) {
// 変換できなければ無効
return false;
}
// 変換できれば有効
return true;
}
次のように試してみます。
dateStr = "2019/05/31"; // 有効
if(isValidDate(dateStr)) {
System.out.println(dateStr + " 有効");
} else {
System.out.println(dateStr + " 無効");
}
dateStr = "2019/06/31"; // 無効
if(isValidDate(dateStr)) {
System.out.println(dateStr + " 有効");
} else {
System.out.println(dateStr + " 無効");
}
実行すると次のように表示されます。
2019/05/31 有効
2019/06/31 有効
ん?あれ?6月31日が有効だと?
そうなんです。上の方法では有効か否かのチェックには不十分なんです。
できたDateオブジェクトはどうなってるの?
ParseException
が発生せずに進んだのですからDateオブジェクトができているはずです。
ではそれはどうなってるのかSystem.out.println(df.format(dt));
でチェックしてみました。
中身の日付は
2019/07/01
でした。
なるほどです。6月の31日は7月の1日。溢れた分を無理やり?存在する日に変換してくれています。これでは6月31日が有効になってしまいます。
日付の文字列が有効か否かをチェックする方法
改良します。上の方法で不十分なので、変換されたDateを文字列に戻して、変換前と比較して同じなら有効としたらいいですね。
改良版のメソッドは次の通りです。
public boolean isValidDate(String str) {
// 日時の文字列の形式はyyyy/MM/dd
DateFormat df = new SimpleDateFormat("yyyy/MM/dd");
Date dt;
try {
// 文字列strをDateに変換
dt = df.parse(str);
} catch (ParseException e) {
// 変換できなければfalse
return false;
}
// 文字列に戻す
String dateString = df.format(dt);
// 元の文字列と戻した文字列が一致すればtrue
return dateString.equals(str);
}
同じように試してみます。
2019/05/31 有効
2019/06/31 無効
成功です!
うまく動作してくれるようになりました。
これは気をつけないとハマりますね〜。注意が必要ですね。
思い込みだけでは危険です。テストって大切ですね。
読んでくださってありがとうございます。
ではまた!