Javaの日付と時刻クラス

公開日: 2026-07-30 20:20 更新日: 2026-07-30 20:20 1478文字 8 min read ... ページビュー

この記事では、Javaの日付と時刻に関連するAPIの進化を要約し、古いDate、Calendar、SimpleDateFormatクラスは依然として履歴コードのメンテナンスに使用できるが、可変性、スレッドセーフではない、エラーが発生しやすいなどの問題があることを指摘し、Java 8で導入されたjava.timeパッケージを新しいプロジェクトで使用することを推奨し、API設計はより明確で、型は不変で、スレッドセーフです。Local Date、Local DateTimeなどのクラスの使用に焦点を当て、ビジネスニーズに応じて適切な型を選択し、日付や文字列を使用しないことで、コードの可読性、セキュリティ、精度を向上させる必要があることを強調します。

Javaの日付と時刻クラス

Javaの一般的なdatetime APIは2つのカテゴリに分類できます。

  • 旧 API:DateCalendarSimpleDateFormat
  • Java 8の新 API LocalDateLocalDateTimeInstantDateTimeFormatterなど。

古いAPIは履歴コードを維持するときにまだ遭遇しますが、新しいプロジェクトでは通常java.timeパッケージが優先されます。

1.タイムスタンプとタイムゾーン

Unixタイムスタンプは通常、1970-01-01T00:00:00Zからの経過時間を示す。Dateは、ミリ秒精度を使用して、時点を保存します。

北京時間は通常UTC+8を使用する。タイムゾーンは、時刻の日付と時刻の表示方法に影響しますが、時刻自体は変更されません。

(2)Date

java.util.Dateはタイムライン上のある時点を表し、内部コア値はUnix 時代の開始からのミリ秒数である。単に年、月、日、時、分、秒を別々に保存するのではない。

Dateで直接日付を操作する方法の多くは時代遅れであり、日付計算にはCalendarまたはより推奨されるjava.time APIを使用する必要があります。

コンストラクター

Date now = new Date();

引数なしコンストラクタは、現在の時間を表すオブジェクトを作成します。

Date date = new Date(1_000_000L);

渡されるlongの値は、Unix 時代の開始から経過したミリ秒数を表します。

一般的なアプローチ

Date date = new Date();

long timestamp = date.getTime();
date.setTime(timestamp + 1_000L);
  • getTime():ミリ秒タイムスタンプを取得します。
  • setTime(long time)オブジェクトの表示が修正された時点。

Dateは可変オブジェクトであり、setTime()を呼び出すと元のオブジェクトが変更されます。

カテゴリー Calendar

Calendarは旧暦計算クラスであり、タイムゾーンやロケールに応じて年月日などのフィールドを処理することができる。

コンストラクタは通常直接呼び出されず、代わりにgetInstance()経由でインスタンスを取得します:

Calendar calendar = Calendar.getInstance();

日付フィールドの取得および変更

Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, 3);

int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH) + 1;
int day = calendar.get(Calendar.DAY_OF_MONTH);

System.out.println(year + "-" + month + "-" + day);

注意点:

  • Calendar.MONTH0から始まるため、月を表示する場合は通常1を追加します。
  • add()のパラメータは正または負であり、時間を増減させるために使用される。
  • Calendarも可変オブジェクトです。

Dateとの相互接続

Calendar calendar = Calendar.getInstance();
Date dateFromCalendar = calendar.getTime();

Date date = new Date(100_000_000L);
Calendar anotherCalendar = Calendar.getInstance();
anotherCalendar.setTime(date);
  • calendar.getTime()Calendarの現在の時刻をDateに変換します。
  • calendar.setTime(date)Dateを指定した時点をCalendarに使用させます。

カテゴリー SimpleDateFormat

SimpleDateFormatは、Dateと文字列間の書式設定と解析に使用されます。

一般的な書式記号は以下の通りです。

シンボル意味
yyyy4 年ぶり。【2026】
MM2 ヶ月間。0 1
dd2 日付。^25 頁。
HH24『 16 』
mm数分。『 30 』
ss秒ごとに『 45 』

書式記号では大文字と小文字が区別されます。たとえば、MMは月を表し、mmは分を表します。

Dateを文字列としてフォーマット

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

public class FormatDateDemo {

    public static void main(String[] args) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date now = new Date();

        String text = formatter.format(now);
        System.out.println(text);
    }
}

文字列をDateに解析

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

public class ParseDateDemo {

    public static void main(String[] args) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        formatter.setLenient(false);

        String text = "2026-01-25";

        try {
            Date date = formatter.parse(text);
            System.out.println(date);
        } catch (ParseException e) {
            System.out.println("日期格式不正确");
        }
    }
}

setLenient(false)は、緩い解析をオフにするために使用されます。たとえば、Strictモードでは、2026-02-30は自動的に翌月に調整するのではなく、失敗を解決します。

SimpleDateFormatはスレッドセーフではなく、同じインスタンスを複数のスレッドで共有オブジェクトとして使用しないでください。

5.古いAPIアプリケーション

指定日に15 日追加

20260122を15 日間増やし、中国語の日付形式でエクスポートします。

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

public class AddDaysLegacyDemo {

    public static void main(String[] args) {
        String text = "20260122";
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        formatter.setLenient(false);

        try {
            Date date = formatter.parse(text);

            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(Calendar.DATE, 15);

            formatter.applyPattern("yyyy年MM月dd日");
            System.out.println(formatter.format(calendar.getTime()));
        } catch (ParseException e) {
            System.out.println("日期格式不正确");
        }
    }
}

2つの時点におけるミリ秒差の計算

long differenceMillis = endDate.getTime() - startDate.getTime();

1 日のミリ秒数を直接割っても、固定時間の日数しか得られません。時間範囲が夏時間を超えて変化する場合、結果はカレンダーの日付差と異なる場合があります。したがって,日付間に何日ずれているかを計算する場合には,LocalDateChronoUnit.DAYSが適している.

Java 8 Date Time APIの概要

java.time APIの型設計はより明確であり、ほとんどのコアクラスは不変でスレッドセーフである。

LocalDate

LocalDateは、誕生日やコースの日付など、タイムゾーンのない日付を表します。

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class LocalDateDemo {

    public static void main(String[] args) {
        DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");

        LocalDate date = LocalDate.parse("20260122", inputFormatter);
        LocalDate result = date.plusDays(15);

        System.out.println(result.format(outputFormatter));
    }
}

日付差の計算

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;

public class DateDifferenceDemo {

    public static void main(String[] args) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");

        LocalDate startDate = LocalDate.parse("20260122", formatter);
        LocalDate endDate = LocalDate.parse("20260302", formatter);

        long days = ChronoUnit.DAYS.between(startDate, endDate);
        System.out.println(days);
    }
}

一般的なタイプ

タイプ適用可能なシーン
LocalDate日付のみ、タイムゾーンは不要です。
Time必要なのは秒だけ。
Time日付と時刻が必要ですが、タイムゾーンは含まれません
Instantタイムスタンプの記録に適したタイムライン上の時点
ZonedDateTime明確なタイムゾーンルールが必要な日時
Duration秒とナノ秒の長さを表す
od年、月、日に基づく日付差を表します。
DateTimeFormatter日時のフォーマットと解析

新しいコードは、常にDateまたは文字列で保存するのではなく、ビジネスの意味に基づいてタイプを選択する必要があります。

気に入ったならばコメントを残してくださいね~

... ページビュー
© 2026 跨越星轨的客 @Hoshiumi
Powered by theme astro-koharu · Inspired by Shoka