検索

キーワード


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

  • 公開日:2021-01-26 08:21:20
  • 最終更新日:2020-12-24 21:31:16
【Java】日付時刻の変換方法(新旧 API 相互変換、Data/Calendar の変換)

こんにちは、研修を終えたばかりの駆け出しエンジニアの伊藤です。

東京ITカレッジのJava研修で学んだ内容を復習も兼ねて記事にしたいと思います。

今回は、日付時刻の変換に焦点をあてて、Date・CalendarクラスとDateAndTimeAPI(新API)の相互変換、DateとCalendarの相互変換の方法について説明します。

この記事では、最低限覚えておいてほしいクラスとして、基本的な操作方法やメソッドを紹介します。

日付時刻のインスタンス生成等については「日時取得(新API‐Java8)」と「日時取得(旧API)」で説明しているので、ぜひご覧ください。
Javaやプログラムについて勉強し始めた方の参考になれば幸いです!
(eclipseを使用して計算を行っています)


関連記事:

日付時刻のまとめ

日時取得(従来API)-java.util.Date, java.util.Calendar

日付時刻(従来のAPI) - 操作(計算、比較、フォーマット)

日時取得(新API-Java8)

日付時刻(新API‐Java8) - 日時比較・日時演算

日付時刻(新API‐Java8) - フォーマット

処理時間(経過時間)計測 ー UNIX時間について



新旧 API の相互変換(従来の API と新 API <DateAndTimeAPI>)

java.util.Date、java.util.Calendar は、Javaの初期から採用されている日付時刻を扱うクラスでした。

しかし、スレッドセーフではない、ミュータブルである等使いにくいところがあり、Java8より DateAndTimeAPI として新たに日付時刻を扱うクラスが作られました。
(それぞれの違い/特徴については、「日時取得(新API‐Java8)」に解説があります)

DateやCalendarは現在でも有用なクラスですが、非推奨となっているメソッドもあり、過去に作った日時に関連するプログラムはDateAndTimeAPIに対応させるためのメソッドが存在します。

変換パターン1.Instant クラス(タイムラインを基にした相互変換)

DateAndTimeAPIでは、タイムライン(経過時間)を表す Instantクラスがあります。

このInstantクラスは、UNIX時間(1970年1月1日午前0時0分0秒からの経過時間)を情報として持ちます。

従来のDateクラス、Calendarクラス共にこのUNIX時間のタイムラインを持つため、相互変換が可能です。
※Instantクラスの変換メソッドからCalendarへ変換するメソッドは用意されていません。


Date → Instant

Date 変数名1 = new Date();
Instant 変数名2 = 変数名1.toInstant();

Instant → Date

Instant 変数名1 = Instant.now();
Date 変数名2 = Date.from(変数名1);

Calendar → Instant

Calendar 変数名1 = Calendar.getInstance();
Instant 変数名2 = 変数名1.toInstant();

サンプルプログラム:Instant クラスを基にした新旧 API 日付の相互変換

//Date・Calendar ⇔ Instant変換サンプル
import java.time.Instant;
import java.util.Calendar;
import java.util.Date;

public class InstantSample {

	public static void main(String[] args) {
		//Date → Instant
		Date date1 = new Date();
		Instant ins1 = date1.toInstant();
		System.out.println("---取得結果--------------------");
		System.out.println("Date            : " + date1);
		System.out.println("Date → Instant : " + ins1);
		//
		//Instant → Date
		Instant ins2 = Instant.now();
		Date date2 = Date.from(ins2);
		System.out.println("---Instant → Date-------------");
		System.out.println("Instant         : " + ins2);
		System.out.println("Instant → Date : " + date2);
		//
		//Calendar → Instant
		System.out.println("---Calendar → Instant---------");
		Calendar cal1 = Calendar.getInstance();
		Instant ins3 = cal1.toInstant();
		System.out.println("Calendar            : " + cal1);
		System.out.println("Calendar → Instant : " + ins3);
	}
}


---取得結果--------------------
Date            : Fri Aug 28 17:08:23 GMT+09:00 2020
Date → Instant : 2020-08-28T08:08:23.612Z
---Instant → Date-------------
Instant         : 2020-08-28T08:08:23.655689200Z
Instant → Date : Fri Aug 28 17:08:23 GMT+09:00 2020
---Calendar → Instant---------
Calendar            : java.util.GregorianCalendar[time=1598602103656,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="GMT+09:00",offset=32400000,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2020,MONTH=7,WEEK_OF_YEAR=35,WEEK_OF_MONTH=5,DAY_OF_MONTH=28,DAY_OF_YEAR=241,DAY_OF_WEEK=6,DAY_OF_WEEK_IN_MONTH=4,AM_PM=1,HOUR=5,HOUR_OF_DAY=17,MINUTE=8,SECOND=23,MILLISECOND=656,ZONE_OFFSET=32400000,DST_OFFSET=0]
Calendar → Instant : 2020-08-28T08:08:23.656Z


関連記事:

処理時間(経過時間)計測 ー UNIX時間について

日時取得(従来API)-java.util.Date, java.util.Calendar



変換パターン2.Date/Calendar → DateAndTimeAPI 変換

Instant変換メソッドを介することで、LocalDateTime等との変換が簡単にできます。

LocalDateTimeやOffsetDateTime等、XXDateTimeというクラスには、LocalDateやLocalTime、またYear、Hour等への変換メソッドが用意されています。

その為、Date、CalendarをDateAndTimeAPIのXXDateTimeに変換することで、色々な日時の変換が可能になります。

ただし、Instantクラスだけでは時差やタイムゾーンが不明なので、XXDateTime等にするには「ZoneId」か「ZoneOffset」が必要になります。
システムデフォルトのZoneIdはZoneId.systemDefault()で取得ができます。


サンプルプログラム:Date/Calendar から DateAndTimeAPI への日付変換

//Date・Calendar → DateAndTimeAPI変換サンプル
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Date;

public class InstantSample2 {

	public static void main(String[] args) {
		//Date → Instant
		Date date1 = new Date();
		Instant ins1 = date1.toInstant();
		//Calendar → Instant
		Calendar cal = Calendar.getInstance();
		Instant ins2 = cal.toInstant();
		ZoneId zone1 = ZoneId.systemDefault();
		System.out.println("---取得結果--------------------");
		//Date → LocalDateTime
		LocalDateTime ldt = LocalDateTime.ofInstant(ins1, zone1);
		System.out.println("Date → LocalDateTime  : " + ldt);
		//LocalDateTime → LocalDate
		LocalDate ld2 = LocalDate.of(ldt.getYear(), ldt.getMonth(), ldt.getDayOfMonth());
		System.out.println("Date → LocalDate      : " + ld2);
		//LocalDateTime → LocalTime
		LocalTime lt = LocalTime.of(ldt.getHour(), ldt.getMinute());
		System.out.println("Date → LocalTime      : " + lt);
		//
		//Date → OffsetDateTime(ZoneOffset)
		ZoneOffset offset = ZoneOffset.ofHours(9);
		OffsetDateTime odt = ins1.atOffset(offset);
		System.out.println("Date → OffsetDateTime : " + odt);
		//Date → OffsetDateTime(ZoneID)
		OffsetDateTime odt2 = OffsetDateTime.ofInstant(ins1, zone1);
		System.out.println("Date → OffsetDateTime : " + odt2);
		//
		//Date → ZonedDateTime
		ZonedDateTime zdt1 = ZonedDateTime.ofInstant(ins2, zone1);
		System.out.println("Date → ZonedDateTime  : " + zdt1);
	}
}


---取得結果--------------------
Date → LocalDateTime  : 2020-08-28T18:09:48.854
Date → LocalDate      : 2020-08-28
Date → LocalTime      : 18:09
Date → OffsetDateTime : 2020-08-28T18:09:48.854+09:00
Date → OffsetDateTime : 2020-08-28T18:09:48.854+09:00
Date → ZonedDateTime  : 2020-08-28T18:09:48.874+09:00[GMT+09:00]

OffsetDateTimeに関しては、ZoneId、ZoneOffsetどちらのメソッドからでも生成することができます。


関連記事:

日時取得(従来API)-java.util.Date, java.util.Calendar

日時取得(新API-Java8)



変換パターン3.DateAndTimeAPI → Date/Calendar 変換

Date・Calendarへの変換において、LocalDateTimeは直接Instant変換メソッドで作ることができません。

LocalDateTimeは時差、タイムゾーン情報を保持していないためDate・Calendarへの変換のためのInstantが生成できないのです。

そのため、OffsetDateTime か ZonedDateTime を経由してInstantを作ります。

また、Instantクラスにもありましたが、Instant → Calendarへのメソッドはないため、Instant → Date → CalendarとDateを経由しての変換手順になります。


サンプルプログラム:DateAndTimeAPI から Date/Calendar への日付変換

//DateAndTimeAPI → Date・Calendar変換サンプル
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Date;

public class InstantSample3 {

	public static void main(String[] args) {
		System.out.println("---取得結果--------------------");
		//OffsetDateTime → Date
		OffsetDateTime odt = OffsetDateTime.now();
		Instant ins1 = odt.toInstant();
		Date date1 = Date.from(ins1);
		System.out.println("OffsetDateTime → Date : " + date1);
		//
		//ZonedDatetime → Date
		ZonedDateTime zdt = ZonedDateTime.now();
		ins1 = zdt.toInstant();
		date1 = Date.from(ins1);
		System.out.println("ZonedDateTime → Date  : " + date1);
		//
		//LocalDateTime → Date
		LocalDateTime ldt = LocalDateTime.now();
		ZoneId zone = ZoneId.systemDefault();
		zdt = ZonedDateTime.of(ldt, zone);
		ins1 = zdt.toInstant();
		date1 = Date.from(ins1);
		System.out.println("LocalDateTime → Date  : " + date1);
		//
		//Date → Calendar(LocalDateTime → Date → Calendar)
		Calendar cal = Calendar.getInstance();
		cal.setTime(date1);
		System.out.println("Date → Calendar       : " + cal.getTime().toString());
	}
}

---取得結果--------------------
OffsetDateTime → Date : Fri Aug 28 18:45:39 GMT+09:00 2020
ZonedDateTime → Date  : Fri Aug 28 18:45:39 GMT+09:00 2020
LocalDateTime → Date  : Fri Aug 28 18:45:39 GMT+09:00 2020
Date → Calendar       : Fri Aug 28 18:45:39 GMT+09:00 2020

一度、DateにしてしまえばどんなDateAndTimeAPIもCalendarへの変換ができますね。

DateとCalendarの相互変換はこの章の次に詳しく紹介していますので、参考にしてください。

DateAndTimeAPIとDate・Calendarの相互変換は、Instant変換メソッドで、できるできないが少しややこしいですが、確認しながら変換をしてみてください。


関連記事:

日時取得(従来API)-java.util.Date, java.util.Calendar

日時取得(新API-Java8)





旧 API 同士の相互変換(Date 型と Calendar 型)

ここでは、Date型とCalendar型の相互変換のやり方を紹介します。


Calendar → Date

Calendar 変数名1 = Calendar.getInstance();
Date 変数名2 = 変数名1.getTime();

Calendarクラスはabstractクラス(抽象クラス)のため、new演算子でオブジェクトを作成できないので、getInstanceメソッドを使用しオブジェクトを作っています。

getTimeメソッドで変数名1のCalendarから設定された日時を表すDateオブジェクトを取得して、Date型の変数名2に設定をすることで変換ができます。


Date → Calendar

Date 変数名1 = new Date();
Calendar 変数名2 = Calendar.getInstance();
変数名2.setTime(変数名1);

setTimeメソッドは変数名1(Dateオブジェクト)をミリ秒形式の値で設定しています。


サンプルプログラム:Date と Calendar の相互変換

//相互変換サンプルプログラム
import java.util.Calendar;
import java.util.Date;

public class MutualConversion {

	public static void main(String[] args) throws Exception{
		//CalendarからDateに変換
		Calendar cal = Calendar.getInstance();
		Date date = cal.getTime();
		System.out.println("---取得結果--------------------");
		System.out.println("Calendar → Date = " + date);
		//
		//DateからCalendarに変換
		Date date2 = new Date();
		Calendar cal2 = Calendar.getInstance();
		cal2.setTime(date2);
		System.out.println("Date → Calendar = " + cal2.getTime().toString());
	}
}

---取得結果--------------------
Calendar → Date = Fri Aug 28 14:24:34 GMT+09:00 2020
Date → Calendar = Fri Aug 28 14:24:34 GMT+09:00 2020


関連記事:日時取得(従来API)-java.util.Date, java.util.Calendar



まとめ

Date・CalendarクラスとDateAndTimeAPI(新API)の相互変換、DateとCalendarの相互交換の方法は分かったでしょうか?

Java で作成されたシステムでは、現在でも従来の日付時刻クラスは広く使用されています。

新しい DateAndTimeAPI を使用する時に変換が必要になる場面が多々ありますが、そのためには少しコツが必要です。

新旧の日付時刻 API クラス相互変換のポイントを押さえておきましょう。


関連記事:

日付時刻のまとめ

日時取得(従来API)-java.util.Date, java.util.Calendar

日付時刻(従来のAPI) - 操作(計算、比較、フォーマット)

日時取得(新API-Java8)

日付時刻(新API‐Java8) - 日時比較・日時演算

日付時刻(新API‐Java8) - フォーマット

処理時間(経過時間)計測 ー UNIX時間について



【著者】

伊藤

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

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