Javaにおいて日付や時刻を扱うプログラムを作成する際、特定の日の曜日を取得したいという場面は非常に多く存在します。

かつてはjava.util.Calendarクラスを使用するのが一般的でしたが、Java 8で導入された「Date-Time API」によって、その手法はより直感的で安全なものへと進化しました。

本記事では、現代のJava開発における標準であるjava.timeパッケージを用いた最新の曜日取得手法から、保守開発で必要となる従来のCalendarクラスの使い方まで、エンジニアが現場で即座に活用できる知識を網羅的に解説します。

Javaにおける日付処理の変遷と現状

Javaの歴史の中で、日付と時刻の処理は大きな転換点を迎えてきました。

初期のJavaではjava.util.Dateが、その後java.util.Calendarが登場しましたが、これらは「スレッドセーフではない」「月の指定が0から始まる」といった設計上の課題を抱えていました。

これらを解決するために登場したのが、Java 8以降のDate-Time API(JSR-310)です。

この新しいAPIでは、日付を扱うLocalDateや、曜日を表現するDayOfWeek列挙型が導入され、開発者はより簡潔でミスの少ないコードを書くことが可能になりました。

現代のJavaプロジェクトにおいて新規にコードを記述する場合、特別な理由がない限りはDate-Time APIを使用することが鉄則となっています。

LocalDateを使用した曜日の取得

現在のJavaにおいて、曜日を取得する最も標準的かつ推奨される方法は、java.time.LocalDateクラスを利用することです。

このクラスは時刻情報を持たない「日付」のみを扱うため、曜日の判定には最適です。

DayOfWeek列挙型の取得

LocalDateクラスには、その日付の曜日を返すgetDayOfWeek()メソッドが用意されています。

このメソッドの戻り値はDayOfWeekという列挙型(Enum)です。

Java
import java.time.LocalDate;
import java.time.DayOfWeek;

public class Main {
    public static void main(String[] args) {
        // 現在の日付を取得
        LocalDate today = LocalDate.now();
        
        // 曜日を取得(DayOfWeekオブジェクト)
        DayOfWeek dayOfWeek = today.getDayOfWeek();
        
        // 曜日の名前を英語で出力
        System.out.println("今日の曜日: " + dayOfWeek);
    }
}
実行結果
今日の曜日: MONDAY

このDayOfWeekオブジェクトを使用することで、曜日が「月曜日であるか」といった比較をタイプセーフに行うことができます。

曜日を日本語で取得する方法

システムのユーザーインターフェースに表示する場合、英語の「MONDAY」ではなく「月曜日」や「(月)」といった日本語形式で取得したいケースがほとんどです。

その場合は、getDisplayNameメソッドを使用します。

このメソッドには、表示スタイル(TextStyle)と地域(Locale)を指定します。

TextStyle.FULLを指定すれば「月曜日」、TextStyle.SHORTを指定すれば「月」といった形式で取得可能です。

Java
import java.time.LocalDate;
import java.time.DayOfWeek;
import java.time.format.TextStyle;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        LocalDate date = LocalDate.of(2025, 5, 12);
        DayOfWeek dow = date.getDayOfWeek();
        
        // 日本語のフルネーム(月曜日)
        String fullJp = dow.getDisplayName(TextStyle.FULL, Locale.JAPAN);
        
        // 日本語の短縮形(月)
        String shortJp = dow.getDisplayName(TextStyle.SHORT, Locale.JAPAN);
        
        System.out.println("フルネーム: " + fullJp);
        System.out.println("短縮形: " + shortJp);
    }
}
実行結果
フルネーム: 月曜日
短縮形: 月

このように、Localeを変更するだけで多言語対応も容易に行える点が、Date-Time APIの優れたメリットの一つです。

曜日を数値として扱う

プログラムのロジック内で「月曜日なら1、日曜日なら7」といった数値として曜日を扱いたい場合があります。

ISO-8601規格に基づき、JavaのDayOfWeekでは月曜日が1、日曜日が7として定義されています。

数値(1〜7)の取得

数値を抽出するには、getValue()メソッドを使用します。

Java
import java.time.LocalDate;

public class Main {
    public static void main(String[] args) {
        LocalDate date = LocalDate.of(2025, 12, 25);
        int dayValue = date.getDayOfWeek().getValue();
        
        System.out.println("2025年12月25日の曜日数値: " + dayValue);
        
        if (dayValue >= 6) {
            System.out.println("この日は週末です。");
        } else {
            System.out.println("この日は平日です。");
        }
    }
}
実行結果
2025年12月25日の曜日数値: 4
この日は平日です。

注意点として、後述するCalendarクラスとは数値の割り当てが異なるため、混同しないように気をつける必要があります。

モダンな開発では「月曜=1」のルールが定着しています。

DateTimeFormatterによる柔軟なフォーマット

日付全体を特定のフォーマット文字列に変換する際に、その中に曜日を含めたい場合はjava.time.format.DateTimeFormatterが非常に便利です。

フォーマットパターンによる取得

パターン文字列として「E」を使用すると曜日を出力できます。

  • E: 短縮された曜日(月)
  • EEEE: 完全な曜日(月曜日)
Java
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        LocalDate now = LocalDate.now();
        
        // フォーマットパターンの定義(日本語ロケール指定)
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd (E)", Locale.JAPAN);
        
        String formattedDate = now.format(formatter);
        System.out.println("フォーマット済み日付: " + formattedDate);
    }
}
実行結果
フォーマット済み日付: 2025/10/20 (月)

この手法は、ログ出力や画面表示用に「日付+曜日」の形式を一括で生成したい場合に、最もコードがスッキリします。

従来のCalendarクラスでの曜日取得

古いシステムの運用保守(レガシーシステム)に携わる場合、依然としてjava.util.Calendarクラスに遭遇することがあります。

新しいプロジェクトでの採用は避けるべきですが、既存コードの修正のために使い方は理解しておく必要があります。

Calendarクラスの基本コード

Calendarでは、get(Calendar.DAY_OF_WEEK)を使用して曜日の値を取得します。

Java
import java.util.Calendar;

public class Main {
    public static void main(String[] args) {
        Calendar cal = Calendar.getInstance();
        int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
        
        System.out.println("Calendarによる曜日数値: " + dayOfWeek);
        
        // 定数との比較
        if (dayOfWeek == Calendar.SUNDAY) {
            System.out.println("今日は日曜日です。");
        }
    }
}
実行結果
Calendarによる曜日数値: 2
今日は月曜日です。

Calendarクラスの重要な注意点

Calendarを使用する際に最も注意すべきは、日曜日の値が「1」から始まるという点です。

これはDate-Time API(月曜が1)とは根本的に異なる設計です。

曜日Calendarの定数Calendarの値LocalDate (getValue) の値
日曜日Calendar.SUNDAY17
月曜日Calendar.MONDAY21
火曜日Calendar.TUESDAY32
水曜日Calendar.WEDNESDAY43
木曜日Calendar.THURSDAY54
金曜日Calendar.FRIDAY65
土曜日Calendar.SATURDAY76

この違いを理解していないと、条件分岐で致命的なバグを引き起こす可能性があります。

既存のコードを読み書きする際は、どちらのAPIに基づいた数値処理なのかを必ず確認してください。

応用:曜日の計算と判定

実務では、単に曜日を表示するだけでなく、「次の日曜日の日付を求める」や「特定の日付が祝日ではない土日か判定する」といったロジックが求められます。

特定の曜日への調整

TemporalAdjustersクラスを使用すると、「次の金曜日」や「今月の第3月曜日」といった複雑な計算が一行で記述できます。

Java
import java.time.LocalDate;
import java.time.DayOfWeek;
import java.time.temporal.TemporalAdjusters;

public class Main {
    public static void main(String[] args) {
        LocalDate today = LocalDate.of(2025, 6, 1); // 日曜日
        
        // 次の金曜日を計算
        LocalDate nextFriday = today.with(TemporalAdjusters.next(DayOfWeek.FRIDAY));
        
        System.out.println("基準日: " + today);
        System.out.println("次の金曜日: " + nextFriday);
    }
}
実行結果
基準日: 2025-06-01
次の金曜日: 2025-06-06

週末(土日)かどうかの判定関数

実務でよく使われるユーティリティメソッドの例を紹介します。

Java
import java.time.LocalDate;
import java.time.DayOfWeek;

public class DateUtils {
    /**
     指定された日付が週末(土日)かどうかを判定します。
     */
    public static boolean isWeekend(LocalDate date) {
        DayOfWeek dow = date.getDayOfWeek();
        return dow == DayOfWeek.SATURDAY || dow == DayOfWeek.SUNDAY;
    }

    public static void main(String[] args) {
        LocalDate sampleDate = LocalDate.of(2025, 12, 20); // 土曜日
        if (isWeekend(sampleDate)) {
            System.out.println(sampleDate + " は休日(土日)です。");
        }
    }
}
実行結果
2025-12-20 は休日(土日)です。

このように、DayOfWeek列挙型を直接比較することで、マジックナンバー(数値の1や7など)を使わずに、可読性の高いコードを維持することが可能です。

まとめ

Javaで曜日を取得する方法は、時代とともに洗練されてきました。

現代のJava開発における要点は以下の通りです。

  • 基本は LocalDate と DayOfWeek を使用する。これが最も安全でモダンな手法です。
  • 日本語で表示したい場合は、getDisplayNameTextStyleLocale.JAPANを渡す。
  • 文字列として一括フォーマットしたい場合はDateTimeFormatterのパターン文字「E」を活用する。
  • 曜日を数値で扱う場合、LocalDateは月曜が1Calendarは日曜が1という違いに注意する。
  • 複雑な日付計算にはTemporalAdjustersを組み合わせる。

かつてのCalendarクラスが抱えていた「数値のズレ」や「スレッド安全性の欠如」といった問題は、Date-Time APIによって過去のものとなりました。

これからJavaを学ぶ方や、久々にJavaに触れるエンジニアの方は、この最新の作法を身に付けることで、堅牢でメンテナンス性の高いアプリケーションを構築できるようになるでしょう。