JMemo037

SimpleDateFormatが5桁の西暦を受け付ける

こんな感じのプログラムを作った。
日付の範囲を指定して、データベースからデータを取得するような処理だ。
入力情報である日付Fromと日付ToはdateCheckメソッドにてチェックされ、不正な日付の場合は代わりの日付が指定される仕組みだ。

   /** データ取得処理 */
   public List<Object> select(Connection conn, String dateFrom, String dateTo) {
       List<Object> result = new ArrayList<Object>();
       dateFrom = dateCheck(dateFrom, "2000/01/01");
       dateTo = dateCheck(dateTo, "2020/12/31");
       String sql = "SELECT * FROM TARGET_TABLE "
                  + " WHERE ENTRY_DATE BETWEEN TO_DATE(?, 'yyyy/mm/dd') AND TO_DATE(?, 'yyyy/mm/dd')";
       PreparedStatement ps = null;
       ResultSet rs = null;
       try {
           ps = conn.prepareStatement(sql);
           ps.setString(1, dateFrom);
           ps.setString(2, dateFrom);
           rs = ps.executeQuery();
           // データ取得&リスト格納処理
           // ...
       } catch (SQLException e) {
       } finally {
           // クローズ処理
       }
       return result;
   }
   /** 日付チェック */
   private String dateCheck(String dateString, String alternativeDateString) {
       String result = "";
       DateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
       sdf.setLenient(false);
       try {
           sdf.parse(dateString);
           result = dateString;
       } catch (ParseException e) {
           result = alternativeDateString;
       }
       return result;
   }

どこが問題かというと、「20001/1/1」みたいな、西暦年が5桁の日付を与えてみたところ、dateCheckをクリアしてしまった、というところだ。
どうやらSimpleDateFormatは西暦年が5桁でもしれっと処理してしまうらしい。
こんなプログラムも書いてみたが↓

   public static void main(String[] args) throws ParseException {
       String s = "20001/1/1";
       SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
       sdf.setLenient(false);
       Date d = sdf.parse(s);
       System.out.println(d);
   }

コンソールには「Mon Jan 01 00:00:00 JST 20001」と表示された。

で、これだけならいいのだが、データベース(発見時はOracleを使用)が西暦年5桁は受け入れてくれなかったりする。すなわち、最初に例示した類のプログラムを実行すると

java.sql.SQLException: ORA-01861: リテラルが書式文字列と一致しません

になってしまう。

解決するためには、正規表現によるチェックか文字列の長さチェックでSimpleDateFormat#parseの穴を補うしかないかもしれない。また、値が画面から入力される類のものであるならば、その画面に入力制限をつけて不正な日付を入力させない、などの処置が必要になると思う。

2020/05/19 追記

  • SQLの yyyy を yyyyy に変えたら解決しないかなぁ?
最終更新:2020年05月19日 11:33