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)です。
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を指定すれば「月」といった形式で取得可能です。
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()メソッドを使用します。
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: 完全な曜日(月曜日)
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)を使用して曜日の値を取得します。
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.SUNDAY | 1 | 7 |
| 月曜日 | Calendar.MONDAY | 2 | 1 |
| 火曜日 | Calendar.TUESDAY | 3 | 2 |
| 水曜日 | Calendar.WEDNESDAY | 4 | 3 |
| 木曜日 | Calendar.THURSDAY | 5 | 4 |
| 金曜日 | Calendar.FRIDAY | 6 | 5 |
| 土曜日 | Calendar.SATURDAY | 7 | 6 |
この違いを理解していないと、条件分岐で致命的なバグを引き起こす可能性があります。
既存のコードを読み書きする際は、どちらのAPIに基づいた数値処理なのかを必ず確認してください。
応用:曜日の計算と判定
実務では、単に曜日を表示するだけでなく、「次の日曜日の日付を求める」や「特定の日付が祝日ではない土日か判定する」といったロジックが求められます。
特定の曜日への調整
TemporalAdjustersクラスを使用すると、「次の金曜日」や「今月の第3月曜日」といった複雑な計算が一行で記述できます。
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
週末(土日)かどうかの判定関数
実務でよく使われるユーティリティメソッドの例を紹介します。
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 を使用する。これが最も安全でモダンな手法です。
- 日本語で表示したい場合は、
getDisplayNameにTextStyleとLocale.JAPANを渡す。 - 文字列として一括フォーマットしたい場合は
DateTimeFormatterのパターン文字「E」を活用する。 - 曜日を数値で扱う場合、LocalDateは月曜が1、Calendarは日曜が1という違いに注意する。
- 複雑な日付計算には
TemporalAdjustersを組み合わせる。
かつてのCalendarクラスが抱えていた「数値のズレ」や「スレッド安全性の欠如」といった問題は、Date-Time APIによって過去のものとなりました。
これからJavaを学ぶ方や、久々にJavaに触れるエンジニアの方は、この最新の作法を身に付けることで、堅牢でメンテナンス性の高いアプリケーションを構築できるようになるでしょう。






