Java Calendar クラス
Calendar クラスは、Java で日付と時刻を処理するための抽象クラスであり、それはjava.utilパッケージ内にあります。このクラスは、年、月、日、時、分などの日付と時刻のフィールドを操作するための一連のメソッドを提供し、日付の計算と比較を実行できます。
なぜ Calendar クラスが必要なのか?
Java では、Date クラスも日付と時刻を表すことができますが、次のような制限があります:
- ほとんどのメソッドが非推奨(deprecated)になっている
- 国際化に対応していない
- 日付計算機能が限られている
Calendar クラスはこれらの問題を解決し、より強力で柔軟な日時操作機能を提供します。
Calendar クラスの基本的な使い方
Calendar インスタンスの取得
Calendar は抽象クラスなので、直接インスタンス化することはできません。Calendar インスタンスを取得する標準的な方法は次のとおりです:
例
このメソッドは、デフォルトのタイムゾーンとロケールに基づいて Calendar インスタンス(通常は GregorianCalendar)を返します。
日時を設定する
私たちは使用できますset()メソッドを使用して Calendar オブジェクトの各フィールドを設定します:
例
calendar.set(2023, Calendar.NOVEMBER, 15);
// 年月日時分秒を設定
calendar.set(2023, Calendar.NOVEMBER, 15, 14, 30, 0);
注意:月は 0 から始まります。0 は 1 月、11 は 12 月を表します。混乱を避けるために、Calendar クラスで定義されている定数(Calendar.JANUARY、Calendar.FEBRUARY など)を使用することをお勧めします。
日時の情報を取得する
使用get()メソッドを使用して Calendar オブジェクトの各フィールドを取得できます:
例
int month = calendar.get(Calendar.MONTH); // 月を取得(0-11)
int day = calendar.get(Calendar.DAY_OF_MONTH);// 日を取得
int hour = calendar.get(Calendar.HOUR_OF_DAY);// 時を取得(24時間制)
int minute = calendar.get(Calendar.MINUTE); // 分を取得
int second = calendar.get(Calendar.SECOND); // 秒を取得
Calendar クラスのよく使われるメソッド
日付計算
Calendar クラスは便利な日付計算メソッドを提供します:
例
calendar.add(Calendar.DAY_OF_MONTH, 10);
// 現在の月から3ヶ月を引く
calendar.add(Calendar.MONTH, -3);
日付の比較
私たちは使用できますcompareTo()メソッドを使用して 2 つの Calendar オブジェクトを比較します:
例
Calendar cal2 = Calendar.getInstance();
cal2.add(Calendar.DAY_OF_MONTH, 1);
int result = cal1.compareTo(cal2);
// result < 0 は cal1 が cal2 より前であることを示す
// result == 0 は cal1 が cal2 と等しいことを示す
// result > 0 は cal1 が cal2 より後であることを示す
タイムスタンプの取得
使用できますgetTimeInMillis()メソッドを使用して Calendar オブジェクトが表すタイムスタンプ(ミリ秒数)を取得します:
例
次を使用することもできますgetTime()メソッドを使用してそれを Date オブジェクトに変換します:
例
Calendar クラスの高度な使い方
タイムゾーンを設定する
Calendar オブジェクトに特定のタイムゾーンを設定できます:
例
calendar.setTimeZone(timeZone);
カレンダーフィールドの操作
Calendar クラスは提供しますroll()メソッドは、他のフィールドに影響を与えずに特定のフィールドをロールすることができます:
例
calendar.roll(Calendar.MONTH, true); // または calendar.roll(Calendar.MONTH, 1);
週の最初の日を取得する
地域によって週の最初の日の定義は異なります(日曜日の場合もあれば、月曜日の場合もあります):
例
総合例
例
import java.util.GregorianCalendar;
import java.text.SimpleDateFormat;
public class CalendarDemo {
public static void main(String[] args) {
// 1. Calendar インスタンスを取得(デフォルトでは現在の日時を使用)
Calendar calendar = Calendar.getInstance();
// 2. 各フィールドの値を取得
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH) + 1; // 月は0から始まるため、1を加える必要があります
int day = calendar.get(Calendar.DAY_OF_MONTH);
int hour = calendar.get(Calendar.HOUR_OF_DAY); // 24時間制
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
System.out.printf("現在時刻: %d年%d月%d日 %d:%d:%d%n",
year, month, day, hour, minute, second);
// 3. 特定の日時を設定
calendar.set(2023, Calendar.MAY, 15, 10, 30, 0); // 2023年5月15日10:30:00
// 4. SimpleDateFormat を使用してフォーマット出力
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("設定後の時刻: " + sdf.format(calendar.getTime()));
// 5. 日付演算
calendar.add(Calendar.DAY_OF_MONTH, 5); // 5日を加える
calendar.add(Calendar.HOUR, -3); // 3時間を引く
System.out.println("演算後の時刻: " + sdf.format(calendar.getTime()));
// 6. 日付を比較
Calendar anotherCalendar = new GregorianCalendar(2023, Calendar.JUNE, 1);
System.out.println("比較結果: " +
(calendar.before(anotherCalendar) ? "より前" : "より後"));
// 7. 週の何日目かを取得(日曜日=1、土曜日=7)
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
System.out.println("曜日" + getChineseWeekday(dayOfWeek));
}
private static String getChineseWeekday(int dayOfWeek) {
String[] weekdays = {"", "日", "月", "火", "水", "木", "金", "土"};
return weekdays[dayOfWeek];
}
}
出力結果:
当前时间: 2023年5月15日 14:25:36 设置后的时间: 2023-05-15 10:30:00 运算后的时间: 2023-05-20 07:30:00 比较结果: 之前 星期二
Calendar クラスの注意点
月は0から始まる:Calendar クラスでは月は0から始まります(0=1月、11=12月)。これはエラーを引き起こしやすいです。
可変性:Calendar オブジェクトは可変です。1つの Calendar オブジェクトを変更すると、それを参照するすべての場所に影響します。
スレッドセーフ:Calendar クラスはスレッドセーフではありません。マルチスレッド環境では追加の同期が必要です。
パフォーマンス:Calendar インスタンスを頻繁に作成するとパフォーマンスに影響します。インスタンスを再利用することを検討できます。
タイムゾーンの問題:デフォルトではシステムのタイムゾーンが使用されます。タイムゾーンをまたぐアプリケーションでは特に注意が必要です。
Java 8 での代替案
Java 8 以降、新しい日時 API(java.timeパッケージ)が導入され、より現代的で使いやすい日時処理方法が提供されています。Java 8 以降を使用する場合は、新しい API を優先的に使用することをお勧めします:
例
LocalDate date = LocalDate.now();
LocalDateTime dateTime = LocalDateTime.now();
ZonedDateTime zonedDateTime = ZonedDateTime.now();
新しい API は Calendar クラスの多くの問題を解決しました。より良いスレッドセーフ性、より直感的な API 設計、より強力な機能が含まれます。
Java Calendar クラスのよく使われるメソッド
以下は java.util.Calendar クラスのよく使われるメソッドです:
基本メソッド
| メソッド | 説明 | 例 |
|---|---|---|
static Calendar getInstance() |
デフォルトのタイムゾーンとロケールの Calendar インスタンスを取得する | Calendar cal = Calendar.getInstance() |
static Calendar getInstance(TimeZone zone) |
指定されたタイムゾーンの Calendar インスタンスを取得する | Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+8")) |
static Calendar getInstance(Locale locale) |
指定されたロケールの Calendar インスタンスを取得する | Calendar cal = Calendar.getInstance(Locale.CHINA) |
static Calendar getInstance(TimeZone zone, Locale locale) |
指定されたタイムゾーンとロケールの Calendar インスタンスを取得する | Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+8"), Locale.CHINA) |
フィールド定数(よく使われる)
| フィールド | 説明 | 値の範囲 |
|---|---|---|
Calendar.YEAR |
年フィールド | - |
Calendar.MONTH |
月フィールド | 0-11 (0は1月を表す) |
Calendar.DATE 或 Calendar.DAY_OF_MONTH |
月の日数 | 1-31 |
Calendar.DAY_OF_WEEK |
曜日 | 1-7 (1は日曜日を表す) |
Calendar.HOUR |
12時間制の時間 | 0-11 |
Calendar.HOUR_OF_DAY |
24時間制の時間 | 0-23 |
Calendar.MINUTE |
分 | 0-59 |
Calendar.SECOND |
秒 | 0-59 |
Calendar.MILLISECOND |
ミリ秒 | 0-999 |
Calendar.AM_PM |
午前または午後 | 0 (AM) または 1 (PM) |
日時操作メソッド
| メソッド | 説明 | 例 |
|---|---|---|
int get(int field) |
指定されたフィールドの値を取得 | int year = cal.get(Calendar.YEAR) |
void set(int field, int value) |
指定されたフィールドの値を設定 | cal.set(Calendar.MONTH, 5)(6月に設定) |
void set(int year, int month, int date) |
年、月、日を設定 | cal.set(2023, 5, 15)(2023年6月15日) |
void set(int year, int month, int date, int hourOfDay, int minute) |
年、月、日、時、分を設定 | cal.set(2023, 5, 15, 14, 30) |
void set(int year, int month, int date, int hourOfDay, int minute, int second) |
年、月、日、時、分、秒を設定 | cal.set(2023, 5, 15, 14, 30, 45) |
void add(int field, int amount) |
指定された時間量を加算または減算 | cal.add(Calendar.DATE, 5)(5日加算) |
void roll(int field, int amount) |
より大きなフィールドを変更せずに時間量を加算または減算 | cal.roll(Calendar.DATE, 5)(日フィールドのみ変更) |
時間比較メソッド
| メソッド | 説明 | 例 |
|---|---|---|
boolean after(Object when) |
このCalendarが指定された時間の後かどうかを判断 | cal1.after(cal2) |
boolean before(Object when) |
このCalendarが指定された時間の前かどうかを判断 | cal1.before(cal2) |
int compareTo(Calendar anotherCalendar) |
2つのCalendarオブジェクトの時間的な順序を比較 | cal1.compareTo(cal2) |
その他の便利なメソッド
| メソッド | 説明 | 例 |
|---|---|---|
long getTimeInMillis() |
このCalendarの時間値(ミリ秒)を返す | long millis = cal.getTimeInMillis() |
void setTimeInMillis(long millis) |
指定されたミリ秒の時間値でCalendarを設定 | cal.setTimeInMillis(1626345600000L) |
Date getTime() |
このCalendarの時間値を表すDateオブジェクトを返す | Date date = cal.getTime() |
void setTime(Date date) |
指定されたDateを使用してCalendarの時間を設定 | cal.setTime(new Date()) |
void clear() |
すべてのフィールド値をクリア | cal.clear() |
void clear(int field) |
指定されたフィールドの値をクリア | cal.clear(Calendar.HOUR) |
boolean isSet(int field) |
指定されたフィールドに値が設定されているかどうかを判断 | if(cal.isSet(Calendar.YEAR)) |