【Java】LocalDateTimeクラスとCalendarクラス

Javaのjava.time.LocalDateTimeクラスとjava.util.Calendarクラスはどちらも日付と時刻を扱うクラスです。

本記事では、この両者の違いについて紹介します。

主な違いは、以下の通りです。

  • Calendarは、mutable(可変)なオブジェクト、LocalDateTimeは、immutable(不変)なオブジェクト
  • Calendarは、月は0始まり、LocalDateTimeは、1始まり
  • LocalDateTimeとCalendarで異なるメソッド
  • LocalDateTimeは、JavaSE8から使用可能

mutableとimmutable

mutable(可変)なオブジェクトは、値が途中で変更された場合、そのオブジェクトの値が変更されます。

immutable(不変)なオブジェクトは、値が途中で変更されても、そのオブジェクトの値は変更されません。

Calendarクラスは、mutable(可変)なオブジェクトで、

LocalDateTimeクラスは、immutable(不変)なオブジェクトです。

immutable(不変)なオブジェクトは、値が変更されたかどうか確かめる必要がないメリットがあります。

下のコードは、Calendarクラス、LocalDateTimeクラスそれぞれで2020年1月1日に設定したのち、2021年1月1日に変更して出力しています。

import java.time.LocalDateTime;
import java.util.Calendar;

public class Test {
    public static void main(String[] args) {
        Calendar cl = Calendar.getInstance();
        cl.set(2020,0,1,0,0,0);
        System.out.println(cl.getTime()); //Wed Jan 01 00:00:00 JST 2020
        cl.set(Calendar.YEAR,2021);
        System.out.println(cl.getTime()); //Fri Jan 01 00:00:00 JST 2021
        
        LocalDateTime ld = LocalDateTime.of(2020,1,1,0,0,0);
        System.out.println(ld); //2020-01-01T00:00
        ld.withYear(2021); 
        System.out.println(ld); //2020-01-01T00:00

    }
}

Calendarクラスでは、2021年に変更後、変数clを出力すると2021年に変更されていることがわかります。

対して、LocalDateTimeクラスでは、2021年に変更後、変数ldを出力すると2020年のままです。

これは、LocalDateTimeがimmutable(不変)なオブジェクトだからです。

immutable(不変)なオブジェクトで変更したい場合、新たにインスタンスを生成する必要があります。

Calendarクラスは、月が0始まり

LocalDateTimeクラスは、月が1始まりという違いがあります。

Calendar cl = Calendar.getInstance();
cl.set(2020,0,1,0,0,0); //2020年1月1日に設定

LocalDateTime ld = LocalDateTime.of(2020,1,1,0,0,0); //2020年1月1日に設定

LocalDateTimeクラスのほうが直感的に使いやすいです。

メソッド

現在時刻取得

Calendarクラスは、getInstanceメソッドで現在の日時を取得します。

LocalDateTimeクラスは、nowメソッドで現在の日時を取得します。

Calendar cl = Calendar.getInstance();

LocalDateTime ld = LocalDateTime.now();

時刻計算

Calendarクラスは、addメソッドで時刻を加算、減算します。

引数1つ目には、加算、減算する対象を指定します。

Calendar.YEAR
Calendar.MONTH
Calendar.DAY_OF_MONTH
Calendar.HOUR
Calendar.MINUTE
Calendar.SECOND

引数2つ目に、加算、減算する値を指定します。加算なら正、減算なら負の値です。

cl.add(Calendar.YEAR,1) //1年後の日時
cl.add(Calendar.HOUR,-5) //5時間前の日時

LocalDateTimeクラスは、年、月、日、時、分、秒を加算あるいは、減算する専用のメソッドが用意されています。

引数に加算、減算する値を指定します。

年を加算plusYears(long years)
月を加算plusMonths(long months)
日を加算plusDays(long days)
時を加算plusHours(long hours)
分を加算plusMinutes(long minutes)
秒を加算plusSeconds(long seconds)
年を減算minusYears(long years)
月を減算minusMonths(long months)
日を減算minusDays(long days)
時を減算minusHours(long hours)
分を減算minusMinutes(long minutes)
秒を減算minusSeconds(long seconds)

ld.plusYears(1) //1年後の日時
ld.minusHours(5) //5時間前の日時

フォーマット

Calendarクラスは、SimpleDateFormatクラスを使ってフォーマットを指定します。

LocalDateTimeクラスは、DateTimeFormatterクラスを使ってフォーマットを指定します。

import java.time.LocalDateTime;
import java.util.Calendar;
import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;

public class Test {
    public static void main(String[] args) {
        Calendar cl = Calendar.getInstance();
        cl.set(2020,0,1,0,0,0);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(sdf.format(cl.getTime())); //2020-01-01 00:00:00
        
        LocalDateTime ld = LocalDateTime.of(2020,1,1,0,0,0);
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        System.out.println(ld.format(dtf)); //2020-01-01 00:00:00
    }
}

JavaSE8

LocalDateTimeクラスは、JavaSE8から登場したクラスであるため、8より古いバージョンは利用できない。

コマンドでjava --versionで確認を