import java.util.*;もしも、あなたが参考にしている書籍や、ページが(A)のコードだった場合はすみやかに処 分しましょう。
import java.text.*;
public class hoge{
public static void main(String str[])
{
String _strDate = "2005/05/02 18:00:00";
Date d = null;
//d = new Date(_strDate); …(A)
try{
d = DateFormat.getDateTimeInstance().parse(_strDate); //…(B)
}catch(ParseException pe){
System.err.println("入力された文字列は、日付として認識できません");
pe.printStackTrace();
}
System.out.println("String :" + _strDate );
System.out.println("Date :" + d.toString());
}
}
>java hoge正しく、Stringから、Dateへの変換が行われました。ここで、入力するStringを
String :2005/05/02 18:00:00
Date :Mon May 02 18:00:00 JST 2005
>java hoge例外はスローされません。こ れは、日付の解釈を曖昧に行っているからです。
String :2005/05/50 29:90:135
Date :Mon Jun 20 06:32:15 JST 2005
>java hoge
String :2005/-5/02 18:-20:00
Date :Fri Jul 02 17:40:00 JST 2004
int _Y = Integer.parseInt(_strDate.substring(0,4));
int _M = Integer.parseInt(_strDate.substring(6,7));
int _D = Integer.parseInt(_strDate.substring(8,10));
int _h = Integer.parseInt(_strDate.substring(11,13));
int _m = Integer.parseInt(_strDate.substring(14,16));
int _s = Integer.parseInt(_strDate.substring(17,19));
if(_Y ==2005 && //2005年であること
(0 < _M ) && (_M < 13) //01〜12
&& (0 < _D) && (_D < 32) //01〜31
&& (-1 < _h) && (_h < 24)//01〜23
&& (-1 < _m) && (_m < 60)//00〜59
&& (-1 < _s) && (_s < 60)//00〜59
) ………
……………
† 1
…余談ですが、私がかかわったとある大規模なWEBシステムで、『共通処理クラス』という名前でこのような処理が組
み込まれているのを見たことがあります。 もっとも、その処理では2100年までの閏年となる年や、30日までしかない月等をテーブルで持ち、判断させていましたが…。 また、別の案件では、文字列が日付として妥当がどうかを判断させるために、一旦データベースへinsertし、 その結果内容やSQLの戻り値で判断させていました。もちろん、パフォーマンスや再利用性は皆無であることは言うまでもありません…。 |
import java.util.*;(C)の箇所で例外になるはずですので、実行してみましょう。
import java.text.*;
public class hoge2{
public static void main(String str[])
{
String _strDate = "2005/05/02 18:00:00";
String _strBadDate = "2005/50/-2 970:-5:200";
Date d1 = null,d2 = null,d3 = null,d4 = null;
try{
DateFormat normFmt = DateFormat.getDateTimeInstance();
DateFormat cstmFmt = DateFormat.getDateTimeInstance();
cstmFmt.setLenient(false);
System.out.println("normFmt isLenient()" + normFmt.isLenient());
System.out.println("cstmFmt isLenient()" + cstmFmt.isLenient());
d1 = normFmt.parse(_strDate);
d2 = normFmt.parse(_strBadDate);
d3 = cstmFmt.parse(_strDate);
d4 = cstmFmt.parse(_strBadDate); //… (C)
}catch(ParseException pe){
System.err.println("入力された文字列は、日付として認識できません");
pe.printStackTrace();
}
System.out.println("String :" + _strDate );
System.out.println("String :" + _strBadDate );
System.out.println("Date1 :" + d1.toString());
System.out.println("Date2 :" + d2.toString());
System.out.println("Date3 :" + d3.toString());
System.out.println("Date4 :" + d4.toString());
}
}
>java hoge2正しく例外処理に入りました。(最終行のNullPointerExceptionは、d4が作成できなかった為です。)
normFmt isLenient()true
cstmFmt isLenient()false
入力された文字列は、日付として認識できません
java.text.ParseException: Unparseable date: "2005/50/-2 970:-5:200"
at java.text.DateFormat.parse(DateFormat.java:334)
at hoge2.main(hoge2.java:23)
String :2005/05/02 18:00:00
String :2005/50/-2 970:-5:200
Date1 :Mon May 02 18:00:00 JST 2005
Date2 :Mon Jan 19 16:55:32 JST 2009
Date3 :Mon May 02 18:00:00 JST 2005
Exception in thread "main" java.lang.NullPointerException
at hoge2.main(hoge2.java:35)
import java.util.*;このソースはあくまで例です。実際には、ロケールや、日付表記のパターンなどを考慮しなくてはなりません。
import java.text.*;
public class DateUtil
{
public static boolean isDate(String str)
{
return isDate(str,new ParsePosition(0),false);
}
public static boolean isDate(String str,ParsePosition pos)
{
return isDate(str,pos,false);
}
public static boolean isDate(String str,boolean lenient)
{
return isDate(str,new ParsePosition(0),lenient);
}
public static boolean isDate(String str,ParsePosition pos,boolean lenient)
{
DateFormat fmt = DateFormat.getDateInstance();
fmt.setLenient(lenient);
Date d = fmt.parse(str,pos);
return (d!=null);
}
}
注意:DateFormatをWEBシステムのようなマ
ルチスレッド環境で使う場合には注意が必要です。 DateFormat.parseはスレッドセーフではありません。 同期指定するか、スレッド毎に個別のインスタンスを持たせる必要があります! (DateFormatの同期に関しては既成のJava製品にも結構、同期不足バグが報告されています。) |