なかなかどうして、この有様よ。

へたれ系PG/SEの技術系メモ+育児日記。

Calendar型からDate形に変換する方法3選

概要

年月日がそれぞれ別の項目(セレクトボックスとか)になっているformの値を、Calendar型経由でDate型に変換する際、設定内容によっては時分秒が想定外の値になる。 なので、その現象と対処方法を記載する。

ソースと注釈

単純にCalendar型からgetTimeをすると、インスタンスを生成したタイミングの時分秒ミリ秒が設定されてしまう。
そのため、時分秒ミリ秒を「00:00:00.000」にする方法を3つ記載する。

  1. Calendar型からgetTime()して取得した日付(時分秒0指定)
     これは、Calendarのインスタンスにsetで年月日を設定する際に時分秒ミリ秒を0で設定する方法となる。
     単純に値を設定する項目が増えるだけなので、一番手軽にできる方法だと思われる。
  2. Calendar型から時分秒ミリ秒をクリアしてgetTime()して取得した日付
     これは、Calendarのインスタンスを一旦clearでクリアし、再度setで年月日を設定する方法となる。
     ただ、clearでは時間のクリアが行えないため、時間はsetで0を設定しなければならない。
     現在日付を利用する際に時分秒ミリ秒のクリアが必要な場合は有効であるが、そうでない場合は手間がかかる方法だと思われる。
  3. Calendar型からSimpleDateFormatで「yyyy/MM/dd」にしてparse()して取得した日付
     これは、SimpleDateFormatでフォーマットを年月日のみにし、その後CalendarのインスタンスからgetTimeした値をSimpleDateFormatで設定したフォーマットに変換し、それを再度SimpleDateFormatでDate形にparseする方法となる。
     parseを行うためTry/Catchかエラーのthrowを記載する必要が発生し、手間がかかるのでどうしてもSimpleDateFormatを利用しないといけない場合以外はあまり利用しない方が無難だと思われる。

以下、サンプルソース
(ブログへのコピーがミスっていなければ、そのままで多分動くはず。)

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;


public class TestCalenderToDate {


    public static void main(String[] args) {


         // 値を設定する
        Integer year = 2020;
        Integer month = 1;
        Integer day = 15;


        System.out.println("設定値");
        System.out.println("年:"+ year.toString());
        System.out.println("月:"+ month.toString());
        System.out.println("日:"+ day.toString());
        System.out.println("-----");
        System.out.println("結果を表示");
         getDate001(year, month, day);
        System.out.println("-----");
         getDate004(year, month, day);
        System.out.println("-----");
         getDate002(year, month, day);
        System.out.println("-----");
         getDate003(year, month, day);
        System.out.println("-----");


    }


    /**
    * Calender型からgetTime()して取得した日付.
    *
    * @param year
    * @param month
    * @param day
    */
    private static void getDate001(Integer year, Integer month, Integer day) {


        // 年月日を生成
         Calendar cal = Calendar.getInstance();
        cal.set(year, month - 1, day);
        Date date = cal.getTime();


        System.out.println("●Calender型からgetTime()して取得した日付");


        System.out.println(date.toString());
    }


    /**
    * Calender型からgetTime()して取得した日付(時分秒0指定).
    *
    * @param year
    * @param month
    * @param day
    */
    private static void getDate004(Integer year, Integer month, Integer day) {


        // 年月日を生成
         Calendar cal = Calendar.getInstance();
        cal.set(year, month - 1, day, 0, 0, 0);
        Date date = cal.getTime();


        System.out.println("●Calender型からgetTime()して取得した日付(時分秒0指定)");


        System.out.println(date.toString());
    }




    /**
    * Calender型から時分秒ミリ秒をクリアしてgetTime()して取得した日付.
    *
    * @param year
    * @param month
    * @param day
    */
    private static void getDate002(Integer year, Integer month, Integer day) {


        // 年月日を生成
         Calendar cal = Calendar.getInstance();


        // 時分秒ミリ秒をクリアする
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.clear(Calendar.MINUTE);
        cal.clear(Calendar.SECOND);
        cal.clear(Calendar.MILLISECOND);


        cal.set(year, month - 1, day);
        Date date = cal.getTime();


        System.out.println("●Calender型から時分秒ミリ秒をクリアしてgetTime()して取得した日付");


        System.out.println(date.toString());
    }


    /**
    * Calender型からSimpleDateFormatで「yyyy/MM/dd」にしてparse()して取得した日付.
    *
    * @param year
    * @param month
    * @param day
    */
    private static void getDate003(Integer year, Integer month, Integer day) {


        // 年月日を生成
         Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        cal.set(year, month - 1, day);


        String str = "●Calender型からSimpleDateFormatで「yyyy/MM/dd」にしてparse()して取得した日付";


        try {
            Date date = sdf.parse(sdf.format(cal.getTime()));


            System.out.println(str);
            System.out.println(date.toString());
        } catch (ParseException e) {
            System.out.println(str);
            System.out.println("日付生成エラー");
        }
    }

}

出力結果は以下の様になる。

設定値
年:2020
月:1
日:15
-----
結果を表示
●Calender型からgetTime()して取得した日付
Wed Jan 15 09:14:50 JST 2020
-----
●Calender型からgetTime()して取得した日付(時分秒0指定)
Wed Jan 15 00:00:00 JST 2020
-----
●Calender型から時分秒ミリ秒をクリアしてgetTime()して取得した日付
Wed Jan 15 00:00:00 JST 2020
-----
●Calender型からSimpleDateFormatで「yyyy/MM/dd」にしてparse()して取得した日付
Wed Jan 15 00:00:00 JST 2020
-----