検索

キーワード


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

  • 公開日:2021-01-26 08:21:20
  • 最終更新日:2021-01-25 14:11:24
【Java】Date/Calendarの日時フォーマット/日時比較/日時計算クラス使い方解説

こんにちは、研修を終えたばかりの駆け出しエンジニアの伊藤です。
東京ITカレッジのJava研修で学んだ内容を復習も兼ねて記事にしたいと思います。

今回は、DateクラスとCalendarクラスを使ったフォーマット、比較、日付時刻計算について説明します。
この記事では、最低限覚えておいてほしいクラスとして、基本的な操作方法を紹介します。

また、Java8から採用された新API(DateAndTimeAPI)についてのフォーマット、比較、日付時刻計算や基本的な操作方法等は別記事で説明しているので、関連記事からご覧ください。
Javaやプログラムについて勉強し始めた方の参考になれば幸いです!
(eclipseを使用して計算を行っています)


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

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

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

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

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

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

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




フォーマットの使い方

Date型とCalendar型のフォーマット


フォーマットとは

フォーマットとは、Date、Calendarで取得した日時を見やすい形に表示するための物です。
Dateを使って日時を取得した場合と、SimpleDateFormatで設定した場合以下のように表示されます。

  <Date型で取得した場合>

  現在時刻:Mon Jul 27 15:55:45 GMT +9:00 2020

  <SimpleDateFormatで設定した場合>

  現在時刻:2020年07月27日月曜日15時55分45秒


SimpleDateFormatでフォーマットを指定した日時の方がパッと見て理解しやすいと思います。
それでは、どのようにSimpleDateFormatを設定しているかを見てみましょう。


関連記事:SimpleDateFormatクラスJavaDoc




フォーマットの使用方法

フォーマットを指定するには、SimpleDateFormatクラスを使用します。

・SimpleDateFormatの指定

   SimpleDateFormat 変数名 = new SimpleDateFormat();

今回は、フォーマットサンプルでフォーマットの指定を見てみましょう。


//フォーマット表示サンプル
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

public class SimpleDateFormatSample {

	public static void main(String[] args) {
		Date date = new Date();
		Calendar calendar = Calendar.getInstance();
		System.out.println("---取得結果--------------------");
		SimpleDateFormat defo = new SimpleDateFormat();
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("Gyyyy年MM月dd日E曜日H時mm分ss秒");
		SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("EEEE MMM dd HH:mm:s.S yyyy", Locale.ENGLISH);
		System.out.println("デフォルトフォーマット(Date)    : " + defo.format(date));
		System.out.println("デフォルトフォーマット(Calendar): " + defo.format(calendar.getTime()));
		System.out.println("指定フォーマット(Date)          : " + simpleDateFormat.format(date));
		System.out.println("指定フォーマット(Calendar)      : " + simpleDateFormat.format(calendar.getTime()));
		System.out.println("指定フォーマット(Date)          : " + simpleDateFormat2.format(date));
		System.out.println("指定フォーマット(Calendar)      : " + simpleDateFormat2.format(calendar.getTime()));
        //和暦表示
        Locale jp = new Locale("ja", "JP", "JP");
		Calendar calendarJp = Calendar.getInstance();
		DateFormat simpleDateFormatJp = new SimpleDateFormat("Gyy年MM月dd日", jp);
		String date1 = simpleDateFormatJp.format(calendarJp.getTime());
		System.out.println("和暦表示             : " + date1);
	}
}

---取得結果--------------------
デフォルトフォーマット(Date)    : 2020/08/07 15:20
デフォルトフォーマット(Calendar): 2020/08/07 15:20
指定フォーマット(Date)          : 西暦2020年08月07日金曜日15時20分38秒
指定フォーマット(Calendar)      : 西暦2020年08月07日金曜日15時20分38秒
指定フォーマット(Date)          : Friday Aug 07 15:20:38.472 2020
指定フォーマット(Calendar)      : Friday Aug 07 15:20:38.492 2020
和暦表示              : 令和02年08月07日

サンプルプログラムでは始めにDateで現在日時を取得します。

次にSimpleDateFormatをインスタンス化し、指定したフォーマットで表示されるようにしています。

また、フォーマット指定をしないと取得結果のデフォルトフォーマットの日時が表示されます。
フォーマットの指定は、コンストラクタでの指定と設定用のメソッド「applyPattern(String pattern)」があります。


SimpleDateFormatでは、Localeを設定することで、「y」が西暦か和暦かを判別しています。
サンプル結果の指定フォーマットと和暦表示では、西暦「2020」、和暦「02」と判別されているのが分かります。
「G」もLocaleを設定することで結果表示が、「西暦」「令和」になっているところも、きちんと判別されていますね。

よく使われる代表的なパターン文字

年号	G		西暦/和暦

年	  yyyy	2020
	  yy		20

月	  MM		07
	  MMM		Jul
	  MMMMM	July

日	  d		7
	  dd		07

曜日	E		Fri
     EEEE		Friday

時	  H		1
	  HH		10

分	  m		1
	  mm		10

秒	  s		1
	  ss		10

ミリ秒	S		1
	  SSS		001

英語の月(MMM)、曜日(EEE)表記を出力したい場合は、new SimpleDateFormatの引数にLocalの設定が必要になります。
設定をしないと 「8月月」 と言うような出力になるので、どのような出力フォーマットにしたいかをよく考えて使いましょう。
他にも多くのパターン文字がありますので、詳しくはJavaDocのクラスSimpleDateFormatを参照してください。


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




String型とDate型の相互変換

String型からDate型への変換(parseメソッド)

文字列をDate型に変換することで、日時を取得することができます。
ここで扱う parseメソッドは、SimpleDateFormatクラスに実装されているメソッドです。

  SimpleDateFormat 変数名1 = new SimpleDateFormat("日時フォーマット指定");
  Date 変数名2 = 変数名1.parse("文字列日時指定");

parseメソッドを使用する場合、ParseExceptionをthrowする必要があるので、気を付けてください。
詳しくはサンプルプログラムで見てみましょう。

//parseメソッド変換サンプル
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateSample {

	public static void main(String[] args) throws ParseException {
		//日時設定
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
		Date date1 = simpleDateFormat.parse("2020年07月31日");
		Date date2 = simpleDateFormat.parse("2020年08月01日");
		System.out.println("---取得結果--------------------");
        System.out.println("date1 : " + simpleDateFormat.format(date1));
        System.out.println("date2 : " + simpleDateFormat.format(date2));
	}
}


---取得結果--------------------
date1 : 2020年07月31日
date2 : 2020年08月01日


SimpleDateFormatの引数設定した日時フォーマット指定と文字列日時指定のフォーマットが違っていた場合、ParseExceptionエラーが発生します。

必ずフォーマット同士は合わせるようにしましょう。



Date型からStringへの変換(formatメソッド、toStringメソッド)

先ほどとは反対に、Date型の日付を文字列に変換することもできます。
ここではformatメソッドとtoStringメソッドの2つを使ってStringへの変換を行います。
formatメソッドでは、SimpleDateFormatでフォーマットを指定し、Dateで日時を取得後、formatメソッドで変換をします。

  SimpleDateFormat 変数名1 = new SimpleDateFormat("日時フォーマット指定");
  Date 変数名2 = new Date();
  String 変数名3 = 変数名1.format(変数名2); 

下記、サンプルコードでは、formatメソッドの時とtoStringメソッドの時の2例のフォーマットを表示しているので見てみましょう。


//formatメソッド、toStringメソッド変換サンプル
import java.text.SimpleDateFormat;
import java.util.Date;

public class StringSample {

	public static void main(String[] args){
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
		Date date = new Date();
		//formatメソッド
		String stringDate1 = simpleDateFormat.format(date);
		//toStringメソッド
		String stringDate2 = date.toString();
        System.out.println("---取得結果--------------------");
        System.out.println("stringDate1 : " + stringDate1);
        System.out.println("stringDate2 : " + stringDate2);
	}
}


---取得結果--------------------
stringDate1 : 2020年07月27日
stringDate2 : Mon Jul 27 09:25:11 GMT+09:00 2020


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



日時比較

日付比較の種類

DateやCalendarで取得した日時を比較することで、2つの取得時間のどちらが先かを判定したり、かかった時間を測ったりすることができます。

・指定日時より前にあるか判断(beforeメソッド)

  変数名1.before(変数名2)
   変数名2よりも変数名1が前であれば、true
   それ以外は、false

・指定日時より後にあるか判断(afterメソッド)

  変数名1.after(変数名2)
   変数名2よりも変数名1が後であれば、true
   それ以外は、false

・指定日時と同じか判断(equalsメソッド)

  変数名1.equals(変数名2)
   変数名2と変数名1が同じであれば、true
   変数名2と変数名1が同じでなければ、false

・compareToメソッドでの比較

  Dateは経過時間をlong型の値として持っており、long型数値での比較を行っています。
  そのため、基準日時から経過時間が大きい→未来、小さい→過去となります。
  また、大小比較( < , > , ==)も可能です。

  変数名1.compareTo(変数名2)
	  変数名1が変数名2より過去であれば、-1
    変数名1が変数名2より未来であれば、1
    変数名1と変数名2が同時であれば、 0
   
  変数名1 < 変数名2	//変数名1は変数名2より過去
  変数名1 > 変数名2	//変数名1は変数名2より未来
  変数名1 == 変数名2	//変数名1と変数名2は同日

日時判定には以上の4つのメソッドを使います。



Date型の日時判定

Dateクラスでの日時判定は下記のサンプルのように行います。

//Dateクラスでの日時判定サンプル
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateSample {

	public static void main(String[] args) throws ParseException {

		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日hh時mm分ss秒Sミリ秒");
		Date date1 = simpleDateFormat.parse("2020年07月31日12時23分34秒5ミリ秒");
		Date date2 = simpleDateFormat.parse("2020年08月01日12時23分34秒5ミリ秒");
		Date date3 = simpleDateFormat.parse("2020年08月01日12時23分34秒5ミリ秒");
		long long1 = date1.getTime();
		long long2 = date2.getTime();
		long long3 = date3.getTime();
		System.out.println("---取得結果--------------------");
		System.out.println("date1 : " + simpleDateFormat.format(date1) + " (long : " + long1 + ")");
		System.out.println("date2 : " + simpleDateFormat.format(date2) + " (long : " + long2 + ")");
		System.out.println("date3 : " + simpleDateFormat.format(date2) + " (long : " + long3 + ")");
		//before
		System.out.println("date1 は date2 より前 :" + date1.before(date2));
		System.out.println("date2 は date3 より前 :" + date2.before(date3));
		//after
		System.out.println("date1 は date2 より後 :" + date1.after(date2));
		System.out.println("date2 は date3 より後 :" + date2.after(date3));
		//equals
		System.out.println("date1 と date2 は同日 :" + date1.equals(date2));
		System.out.println("date2 と date3 は同日 :" + date2.equals(date3));
		//compareTo
		System.out.println("過去      :" + date1.compareTo(date2));
		System.out.println("未来      :" + date2.compareTo(date1));
		System.out.println("同日      :" + date2.compareTo(date3));
		if (long1 < long2) {
			System.out.println("date1はdata2より過去です 。");
		} else if (long1 > long2) {
			System.out.println("data1はdata2より未来です。");
		} else if (long1 == long2) {
			System.out.println("data1はdata2と同日です。");
		}
	}
}

---取得結果--------------------
date1 : 2020年07月31日12時23分34秒5ミリ秒 (long : 1596122614005)
date2 : 2020年08月01日12時23分34秒5ミリ秒 (long : 1596209014005)
date3 : 2020年08月01日12時23分34秒5ミリ秒 (long : 1596209014005)
date1 は date2 より前 :true
date2 は date3 より前 :false
date1 は date2 より後 :false
date2 は date3 より後 :false
date1 と date2 は同日 :false
date2 と date3 は同日 :true
過去      :-1
未来      :1
同日      :0
date1はdata2より過去です 。

注意する点では、before、after共に比較同士が全く同じ日時だった場合、上記で解説したように「それ以外」となるので falseが返ります。
これは、Calendarでの比較を行った際も共通です。




Calendar型での日時判定

Dateクラスでの日時判定は下記のサンプルのように行います。

//Calendarクラスでの日時判定サンプル
import java.text.SimpleDateFormat;
import java.util.Calendar;

public class CalendarSample {

	public static void main(String[] args){
		Calendar calendar1 = Calendar.getInstance();
		Calendar calendar2 = Calendar.getInstance();
		//フォーマット指定
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
		calendar1.set(2020, 7-1, 31);	//2020年7月31日を表示
		calendar2.set(2020, 8-1, 1);	//2020年8月1日を表示
		System.out.println("---取得結果--------------------");
		//before、after、equals
		System.out.println("calendar1 : " + simpleDateFormat.format(calendar1.getTime()));
		System.out.println("calendar2 : " + simpleDateFormat.format(calendar2.getTime()));
		if (calendar1.before(calendar2)){
			System.out.println("calendar1 は calendar2 より前の日付です。");
		} else if (calendar1.after(calendar2)) {
			System.out.println("calendar1 は calendar2 より後の日付です。");
		} else if (calendar1.equals(calendar2)) {
			System.out.println("calendar1 と calendar2 は同じの日付です。");
		}
		//compareTo
		int cal1 = calendar1.compareTo(calendar2);
		if (cal1 == -1) {
			System.out.println("calendar1 は calendar2 より過去です。");
		} else if (cal1 == 1) {
			System.out.println("calendar1 は calendar2 より未来です。");
		} else if (cal1 == 0) {
			System.out.println("calendar1 と calendar2 は同じ日付です。");
		}
	}
}


---取得結果--------------------
calendar1 : 2020年07月31日
calendar2 : 2020年08月01日
calendar1 は calendar2 より前の日付です。
calendar1 は calendar2 より過去です。

Calendarでは月に関して、月またぎがあるため表示したい月から -1することでその月を表せます。

詳しくは、日時取得の Date/Calendar クラスの基本と使い方を解説をご覧ください。




日時計算

日時などの細かい計算はDateクラスではなくCalendarクラスのメソッドを使用します。

日時の加算、減算(addメソッド)

Calendarクラスメソッドで取得した日時を基準に、値を加算・減算する場合、addメソッド を使用します。

  変数名.add(Calendar.日時フィールド,);


引数に指定した値のだけ加算ができます。また、値にマイナスを付けると減算になります。
また、日時フィールドは『日時取得の Date/Calendar クラスの基本と使い方を解説』の setメソッドに説明がありますので、ご覧ください。

//日時計算サンプル
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class AddSample {

	public static void main(String[] args)  throws ParseException {
		//フォーマット指定
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
		Calendar calendar1 = Calendar.getInstance();
		Calendar calendar2 = Calendar.getInstance();
		//年月日を指定 Date型
		Date date = simpleDateFormat.parse("2015年8月10日");
		calendar2.setTime(date);
		//年月日を指定 Calendar型
		calendar1.set(2015, 8-1, 10);
		System.out.println("---取得結果(Date型)----------------");
		System.out.println("指定日時 :" + simpleDateFormat.format(calendar2.getTime()));
		//Date型の計算
		calendar2.add(Calendar.YEAR, 5);
		date = calendar2.getTime();
		System.out.println("5年後  :" + simpleDateFormat.format(date));
		calendar2.add(Calendar.DAY_OF_MONTH, -10);
		date = calendar2.getTime();
		System.out.println("10日前 :" + simpleDateFormat.format(date));
		//Calendar型の計算
		System.out.println("---取得結果(Calendar型)------------");
        System.out.println("指定日時 :" + simpleDateFormat.format(calendar1.getTime()));
		calendar1.add(Calendar.MONTH, 2);
		System.out.println("2月後  :" + simpleDateFormat.format(calendar1.getTime()));
		calendar1.add(Calendar.DAY_OF_MONTH, -10);
		System.out.println("10日前 :" + simpleDateFormat.format(calendar1.getTime()));
	}
}


---取得結果(Date型)----------------
指定日時 :2015年08月10日
5年後  :2020年08月10日
10日前 :2020年07月31日
---取得結果(Calendar型)------------
指定日時 :2015年08月10日
2月後  :2015年10月10日
10日前 :2015年09月30日

Date型、Calendar型の日付計算ができました。
上記サンプルのようにDate型とCalendar型を変換しあうことで、Date型の計算もできます。
Date型とCalendar型の相互変換については『日付時刻の変換方法(新旧 API 相互変換、Data/Calendar の変換)』をご覧ください。


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

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




まとめ


日時フォーマット、比較、日付計算の方法は分かったでしょうか?

日時を扱うことはプログラム上よくあるので、ぜひ押さえておきたいですね。



【著者】

伊藤

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】値?変数?型??しっかり解説!『データ型(プリミティブ型と参照型)』

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