検索

キーワード


【Java】日時取得の Date/Calendar クラスの基本と使い方を解説

  • 公開日:2021-01-26 08:21:20
  • 最終更新日:2021-01-25 13:42:40
【Java】日時取得の Date/Calendar クラスの基本と使い方を解説

こんにちは、研修を終えたばかりの駆け出しエンジニアの伊藤です。
東京ITカレッジのJava研修で学んだ内容を復習も兼ねて記事にしたいと思います。
今回は、「java.util.Date」「java.util.Calendar」を使った日付取得方法について説明します。
この記事では、最低限覚えておいてほしいクラスとして、日付と時刻を表すクラスと基本的な操作方法のみを紹介します。
日付操作やフォーマットについて、またJava8から採用された新API(DateAndTimeAPI)についての使い方や基本的な操作方法等は、別記事でご紹介しますので、関連記事を参考にしてください。

Javaやプログラムについて勉強し始めた方の参考になれば幸いです!(eclipseを使用して計算を行っています)


関連記事:よく使う日時クラス解説まとめ

     Date/Calendarの日時フォーマット/日時計算/日時比較クラス使い方解説

     Java8からの現在や指定日時取得 9クラスの基本と使い方を解説

     Java8からの日時計算/日時比較クラスの使い方を解説

     Java8からの日時フォーマットクラスの使い方解説

     日付時刻の変換方法(新旧 API 相互変換、Data/Calendar の変換)

     処理時間(経過時間)計測に使える2つのメソッドを解説




日付時刻(従来のAPI)


DateクラスとCalendarクラスの違い(概要)

両クラス共に日付を扱いますが、機能に違いがあります。


 Dateクラス  :特定の日付や時間取得

 Calendarクラス:日時の演算処理や細かい日時等の取得


関連記事:Dateクラス(Oracle)

     Calendarクラス(Oracle)



現在時刻を取得する方法


Dateクラス(java.util.Date)

Dateクラスでインスタンスを作成し、現在時刻を取得します。


 ・現在時刻の取得

  Date 変数名 = new Date();


new演算子で、インスタンスを生成した時点の日時が反映されます。
また反映された日時は、西暦1970年1月1日 午前0時0分0秒 (1970/01/01 00:00:00(GTM))を基点とした生成時の経過ミリ秒が保持されます。


//現在時刻の取得サンプル(Date)
import java.util.Date;

public class DateSample {

	public static void main(String[] args) {

		//現在時刻の生成、取得
		Date date = new Date();
		System.out.println("---取得結果--------------------");
		System.out.println("現在時刻:" + date);
    }
}


---取得結果--------------------
現在時刻:Mon Jul 20 12:44:26 GMT+09:00 2020


Dateインスタンスを生成し、現在時刻の取得ができました。

現在時刻:Mon Jul 20 12:44:26 GMT+09:00 2020
         曜日 月  日 時::秒 GMT+9:00  西暦

で現在時刻を表しています。(GMTは、グリニッジ標準時のことです。日本は、標準時であるイギリスのグリニッジ天文台から約9時間の時差があるため、+9:00と表記されます)

2020/07/20 12:44:26というような、スラッシュでの表示にする場合は、フォーマットの設定が必要になります。
フォーマットについては、こちら「日付時刻(従来API)-操作(計算、比較、フォーマット)」に詳しく使い方を載せているので、併せてご覧ください。



long型とDate型(経過ミリ秒からDate型変換)

上記のDateクラスの説明であった通り、Dateインスタンスが保持するのは経過時間です。
しかしプログラム内部では、1970/01/01 00:00:00 から何年何日…と経過時間が計算されているわけではありません。
Dateインスタンスは経過時間をlong型の数値で持ち、それを人間が見やすい形式に変換しているのです。
実際にプログラム内部ではどのように日時データを保持しているのか、サンプルで見てみましょう。


//long型からDate型への変換サンプル
import java.util.Date;
public class DateSample {

	public static void main(String[] args) {

		//基準日時 1970/01/01 00:00:00
		System.out.println("---取得結果--------------------");
		//基準日時 から 1秒(1,000)後の時間表示
		long long1 = 1000L;
		Date date1 = new Date(long1);
		System.out.println(" 1秒後:" + date1);
		//基準日時から 1日後の日時
		long long2 = 86400000L; //1000L * 24 * 60 * 60;
		Date date2 = new Date(long2);
		System.out.println(" 1日後:" + date2);
		//基準日時から 1年後の日時
		long long3 = 31536000000L; //1000L * 365 * 24 * 60 * 60;
		Date date3 = new Date(long3);
		System.out.println(" 1年後:" + date3);
		//基準日時から2020年1月1日の経過時間
		long long4 = 1577836800000L;
		Date date4 = new Date(long4);
		System.out.println("指定日:" + date4);
	}
}


---取得結果--------------------
 1秒後:Thu Jan 01 09:00:01 GMT+09:00 1970
 1日後:Fri Jan 02 09:00:00 GMT+09:00 1970
 1年後:Fri Jan 01 09:00:00 GMT+09:00 1971
指定日:Wed Jan 01 09:00:00 GMT+09:00 2020

     ※ 1秒 = 1,000ミリ秒

long型の整数値をDateインスタンスを生成する際に引数として渡すと、その引数(コンストラクタ)を使ってインスタンスが生成されます。上記のサンプルで、long型から指定日時の取得ができることが分かります。
Date型はこのようにlongの整数値として日付を保持します。(このlongは経過時間のミリ秒表現です)
また、1970/01/01 よりも前の日時を表示するには、マイナスのlong型整数値を指定すれば取得することができます。



経過ミリ秒の取得

Date型からlong型変換

今度は逆にDateインスタンスからlong型の経過時間のミリ秒数を取得してみます。


//経過ミリ秒をDate型に変換(経過ミリ秒から日時を取得)
import java.util.Date;

public class UnixTimeSample {

	public static void main(String[] args) {

		//Date型から経過ミリ秒の取得
		System.out.println("---取得結果--------------------");
		Date date = new Date();
		long unixTime = date.getTime();
		System.out.println("経過ミリ秒:" + unixTime);
		//取得したミリ秒をDate型に戻す
		Date returnDate = new Date(unixTime);
		System.out.println("取得日時 :" + returnDate);
	}
}


---取得結果--------------------
経過ミリ秒:1595908376400
取得日時 :Tue Jul 28 12:52:56 GMT+09:00 2020


変数名.getTime(); で変数に格納された値を取得することができます。
この時の経過ミリ秒は、何度も出てきている通り基準時である1970/01/01 00:00:00からの経過時間です。
日時を数値化することによって、簡単に計算することができるようになります。
このように日時をlong型で持つことによる利点は、計算や比較などが容易にできる、ということです。
また、この経過秒数をUNIX時間(または、UNIX時刻)と言います。

関連記事:処理時間(経過時間)計測 ー UNIX時間について



currentTimeMillisメソッド

currentTimeMillisメソッドを使っても経過ミリ秒を取得することができます。


//経過ミリ秒をcurrentTimeMillisメソッドで取得
import java.util.Date;

public class UnixTimeSample {

	public static void main(String[] args) {

		//Date型から経過ミリ秒の取得
		System.out.println("---取得結果--------------------");
		Date date = new Date();
		long unixTime = date.getTime();
		System.out.println("経過ミリ秒(long)       :" + unixTime);
		//取得したミリ秒をDate型に戻す
		Date returnDate = new Date(unixTime);
		System.out.println("取得日時(long)        :" + returnDate);
		//System.currentTimeMillisメソッドを使った、経過ミリ秒の取得
		long currentTime = System.currentTimeMillis();
		System.out.println("経過ミリ秒(currentTime):" + currentTime);
		//System.currentTimeMillisメソッドを使い取得したミリ秒をDate型に戻す
		Date currentTimeDate = new Date(currentTime);
		System.out.println("取得日時(currentTime) :" + currentTimeDate);
	}
}


---取得結果--------------------
経過ミリ秒(long)1596078810239
取得日時(long)        :Thu Jul 30 12:13:30 GMT+09:00 2020
経過ミリ秒(currentTime)1596078810273
取得日時(currentTime) :Thu Jul 30 12:13:30 GMT+09:00 2020


今回のサンプルプログラムは、Date型からlong型変換の「経過ミリ秒をDate型に変換」プログラムと見比べられるように書かれています。
プログラムソースは、上から順に処理を行っていきます。
その為、取得結果でも経過ミリ秒に差が出ています。しかし、Date型は秒までの表示なので取得日時結果には違いは見られませんね。
より正確な時間が欲しい場合は、ナノ秒を使うと良いでしょう。
新APIを使用すると、ナノ秒までを簡単に取得することができます。


Calendarクラス(java.util.Calendar)

getメソッド

Dateクラスでは、日付から時差まで全てが取得できました。
しかし、西暦だけ欲しい、日付だけ使いたい、という細かい日時の取得は難しいです。
そこで、細かい日時の取得にはCalendarクラスを用います。
Calendarクラスのインスタンスを生成した後、日時を取得します。

  ・現在時刻を保持したインスタンスの生成

   Calendar 変数名 = Calendar.getInstance();


  ・インスタンスで保持した現在時刻から、欲しい日時を指定し取得

   int 変数名2 = 変数名.get(Calendar.日時名);


Calendarクラスでは、getInstanceメソッドを使用して、生成時点の日付と時刻を保持したインスタンスを生成しています。
getメソッドを使用して、引数に取得したい日時の種類を指定します。getInstanceで生成した現在時刻から指定した日時を取得しています。


//現在日時の取得サンプル(Calendar.get)
import java.util.Calendar;

public class CalendarTest {

	public static void main(String[] args) {

		//Calendarクラスのオブジェクトを生成
		Calendar calendar =Calendar.getInstance();
		//欲しい日時の取得
		System.out.println("---取得結果--------------------");
		System.out.println("西暦 :" + calendar.get(Calendar.YEAR));
		System.out.println("月  :" + calendar.get(Calendar.MONTH));
		System.out.println("現在月:" + calendar.get(Calendar.MONTH)+1);
		System.out.println("日にち:" + calendar.get(Calendar.DATE));
		System.out.println("時刻 :" + calendar.get(Calendar.HOUR));
		System.out.println("分  :" + calendar.get(Calendar.MINUTE));
		System.out.println("何日目:" + calendar.get(Calendar.DAY_OF_YEAR));
		//繋げて表示する場合
		System.out.println();
		int year = calendar.get(Calendar.YEAR);
		int month = calendar.get(Calendar.MONTH)+1;
		int date = calendar.get(Calendar.DATE);
		int hour = calendar.get(Calendar.HOUR);
		int minute = calendar.get(Calendar.MINUTE);
		int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR);
		System.out.println("今日は西暦" + year + "年"
					+ month + "月" + date + "日"
					+ hour + "時" + minute + "分です。");
		System.out.println("そして、" + year + "年が始まってから" + dayOfYear + "日目になります。");
	}
}


---取得結果--------------------
西暦 :2020
月  :6
現在月:7
日にち:20
時刻 :2
分  :58
何日目:202

今日は西暦2020720258分です。
そして、2020年が始まってから202日目になります。


Calendarクラスでは、月の取得の際に注意することがあります。
例えば、現在月が7月とします。 get(Calendar.MONTH) を使用し現在月を取得しようとすると、取得結果は6月になってしまいます。(上記テストプログラム参照)
それは、Calendarインスタンスを生成した際、保持する月は 0から11まで、となっているからです。
1月が 0 、2月が 1 、3月が 2 としてインスタンスに保持されているということです。
そのため、Calendarクラスで現在月を取得するには、get(Calendar.MONTH)に +1 をすることが必要となるので、気を付けてください。



setメソッド

getメソッドを使用すれば、現在日時の取得ができました。
今度は、指定した年月日の取得をしてみましょう。


//指定日時の取得サンプル(Calendar.set)
import java.util.Calendar;

public class CalendarSetSample {

	public static void main(String[] args) {

		//Calendarクラスのオブジェクトを生成
		Calendar calendar = Calendar.getInstance();
		System.out.println("---取得結果--------------------");
		//現在日時の取得
		System.out.println("現在日時:" + calendar.getTime());
		//西暦変換(2020 → 2010)
		calendar.set(Calendar.YEAR, 2010);
		System.out.println("2010年  :" + calendar.getTime());
		//月変換(7月 → 12月)
		calendar.set(Calendar.MONTH, 12 - 1);
		System.out.println("12月    :" + calendar.getTime());
		//日付変換(29日 → 1日)
		calendar.set(Calendar.DATE, 01);
		System.out.println("1日     :" + calendar.getTime());
		//午前午後変換(AM → PM)
		calendar.set(Calendar.AM_PM, 1);
		System.out.println("午後    :" + calendar.getTime());
		//時間変換(22時 → 14時)
		calendar.set(Calendar.HOUR, 2);
		System.out.println("14時    :" + calendar.getTime());
		//曜日変換(火曜 → 日曜)
		calendar.set(Calendar.DAY_OF_WEEK, 1);
		System.out.println("日曜    :" + calendar.getTime());
		System.out.println("---指定日時をまとめて取得------");
		//年月日を指定
		calendar.set(2000, 01, 15);
		System.out.println("年月日指定      :" + calendar.getTime());
		//年月日時分秒で指定
		calendar.set(2000, 01, 15, 18, 22, 30);
		System.out.println("年月日時分秒指定:" + calendar.getTime());
	}
}


---取得結果--------------------
現在日時:Fri Jul 31 16:52:54 GMT+09:00 2020
2010年  :Sat Jul 31 16:52:54 GMT+09:00 2010
12月    :Fri Dec 31 16:52:54 GMT+09:00 2010
1日     :Wed Dec 01 16:52:54 GMT+09:00 2010
午後    :Wed Dec 01 16:52:54 GMT+09:00 2010
14時    :Wed Dec 01 14:52:54 GMT+09:00 2010
日曜    :Sun Nov 28 14:52:54 GMT+09:00 2010
---指定日時をまとめて取得------
年月日指定      :Tue Feb 15 14:52:54 GMT+09:00 2000
年月日時分秒指定:Tue Feb 15 18:22:30 GMT+09:00 2000



サンプルでは、変数名.getTime(); で1970/01/01 00:00:00からの経過時間ミリ秒を取得し、Date型に変換し表示しています。
取得結果では、指定した要素以外は前の値を保ったままになります。


曜日取得に関しては、週の始まりが日曜日となっています。
上記サンプル結果では 12月1日(水)の週の日曜日が 11月28日(日)なので、日付と月も変わっています。


注意するフィールド

Calendarクラスでは、日時を操作するための様々なフィールドが用意されています。

全フィールドの詳細についてはJavaDocを参照してください。

ここでは、値を設定する際に注意が必要なフィールドについて説明します。



MONTH

 MONTHフィールドの値は 0から11 です。


  0    1月 January(Jan)

    1    2月 February(Feb)

    2    3月 March(Mar)

    3    4月 April(Apr)

    4    5月 May(May)

    5    6月 June(Jun)

    6    7月 July(Jul)

    7    8月 August(Aug)

    8    9月 September(Sep)

    9   10月 October(Oct)

    10    11月 November(Nov)

    11    12月 December(Dec)


  MONTHを取得、指定する場合は欲しい指定月(setメソッド)からマイナス1 することを忘れないようにしましょう。
 (getメソッドの場合はプラス1 になるので、間違えないようしてください)



AM_PM

 HOUR が正午より前であるかあとであるかを示します
 AM_PMフィールドの値は 0、1 です。

 0  AM
   1  PM


HOUR

 午前または午後の何時かを示します
 HOURフィールドは 12時間制(0から11)です。
 真夜中、正午どちらもHOURフィールドでは、12 ではなく 0 で表されるので注意してください。
 11 以上の 12時 13時としてもエラーは出ず、結果は出力されます。
 しかし、日付や曜日が指定したところから変わってしまうこともあるので、0 から 11 以内で指定した方が欲しい値を取得できます。
    午前、午後の時間は持ちませんので、AM_PMフィールドと共に使うのが良いです。
 (HOUR_OF_DAY は 24時間制です)


DAY_OF_WEEK

 DAY_OF_WEEKフィールドの値は 1から7 です。


 1  日曜日 Sunday(Sun)

   2  月曜日 Monday(Mon)

   3  火曜日 Tuesday(Tue)

   4  水曜日 Wednesday(Wed)

   5  木曜日 Thursday(Thu)

   6  金曜日 Friday(Fri)

   7  土曜日 Saturday(Sat)


setメソッドを使用すると、年、月、日などの単位ごとや、年月日をまとめて取得することができます。
また、MONTH、AM_PM、DAY_OF_WEEK、各フィールドにはそれぞれに値が定数として用意されています。
(AM_PMフィールドであれば、Calendar.PM と書くことができ、その際の PM が定数で値は 1 になります)
使用する場面に応じて、定数で使用した方が良い場合と、数値としてそのまま値を使用し方が良い場合があるので、使い分けができると良いでしょう。

曜日は値が 1から始まるので、上記フィールドと違っているので気を付けてください。
注意するフィールド値は、getメソッドも同様です。




まとめ

日時の取得方法はわかったでしょうか?
他の記事も読んでみると、日時クラスに関する理解度が上がると思いますので、ぜひ読んでみてください。


関連記事:よく使う日時クラス解説まとめ

     Date/Calendarの日時フォーマット/日時計算/日時比較クラス使い方解説

     Java8からの現在や指定日時取得 9クラスの基本と使い方を解説

     Java8からの日時計算/日時比較クラスの使い方を解説

     Java8からの日時フォーマットクラスの使い方解説

     日付時刻の変換方法(新旧 API 相互変換、Data/Calendar の変換)

     処理時間(経過時間)計測に使える2つのメソッドを解説


【著者】

伊藤

Javaを研修で3か月学んだ、駆け出しのエンジニアです。
現在は、ベンダー資格を取得するため、勉強を日課にできるよう努力中です。

よく読まれている記事
【Java】JSPでタグライブラリを使う(JSTL)

【Java】JSPでタグライブラリを使う(JSTL)

こんにちは。エンジニアの新田です!ここでは、システムエンジニアとして働いている私が、システム開発手法や開発言語について紹介していこうと思います。今回は、JSPの標準タグライブラリ「JSTL」について紹介します。Javaについて勉強している方、Webアプリケーションを構築したいと思っている方の参考になれば幸いです!関連記事リンク: 【Java】JSPの基本的な構文/【Java】JSPのアクションタグ

【Java】Stringクラス文字列を操作するメソッドの使い方まとめ!実例も紹介!

【Java】Stringクラス文字列を操作するメソッドの使い方まとめ!実例も紹介!

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者✅にも、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!そもそもStringとは何?『 String 』... Java言語において文字列のデータ型を指します。基本デ

【Java】文字列の置き換え(String#format)!エスケープシーケンスのまとめも!!

【Java】文字列の置き換え(String#format)!エスケープシーケンスのまとめも!!

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者✅にも、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!Stringクラスformatメソッドの文字列整形【java.utilパッケージ】Formatterクラスfo

【Java】文字列格納後に変更可能!?StringBufferクラスとStringBuilderクラス!

【Java】文字列格納後に変更可能!?StringBufferクラスとStringBuilderクラス!

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者にも✅、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!文字列を扱う3つのクラス【java.langパッケージ】java.langパッケージの文字列を扱うクラスにはS

【Java】値?変数?型??しっかり解説!『データ型(プリミティブ型と参照型)』

【Java】値?変数?型??しっかり解説!『データ型(プリミティブ型と参照型)』

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者✅にも、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!プリミティブ型と参照型プログラム開発では型を持った変数を使ってデータのやり取りをしますが、データ型によって仕様