java.util.GregorianCalendarへのガイド
1. 前書き
このチュートリアルでは、GregorianCalendarクラスを簡単に見ていきます。
2. GregorianCalendar
GregorianCalendarは、抽象クラスjava.util.Calendarの具体的な実装です。 当然のことながら、グレゴリオ暦is the most widely used civil calendar in the world.
2.1. インスタンスの取得
GregorianCalendar:Calendar.getInstance()のインスタンスを取得し、コンストラクターの1つを使用するために使用できる2つのオプションがあります。
静的ファクトリメソッドCalendar.getInstance() を使用すると、デフォルトロケールの主観的なインスタンスが返されるため、推奨されるアプローチではありません。
タイ語の場合はBuddhistCalendar、日本語の場合はJapaneseImperialCalendarが返される場合があります。 返されるインスタンスのタイプがわからない場合、ClassCastException:が発生する可能性があります
@Test(expected = ClassCastException.class)
public void test_Class_Cast_Exception() {
TimeZone tz = TimeZone.getTimeZone("GMT+9:00");
Locale loc = new Locale("ja", "JP", "JP");
Calendar calendar = Calendar.getInstance(loc);
GregorianCalendar gc = (GregorianCalendar) calendar;
}
7つのオーバーロードされたコンストラクターの1つを使用して、オペレーティングシステムのロケールに応じてデフォルトの日付と時刻でCalendarオブジェクトを初期化するか、日付、時刻、ロケール、およびタイムゾーンの組み合わせを指定できます。
GregorianCalendarオブジェクトをインスタンス化できるさまざまなコンストラクターを理解しましょう。
デフォルトのコンストラクターは、オペレーティングシステムのタイムゾーンとロケールの現在の日付と時刻でカレンダーを初期化します。
new GregorianCalendar();
year, month, dayOfMonth, hourOfDay, minuteを指定し、デフォルトのロケールでデフォルトのタイムゾーンに秒を指定できます。
new GregorianCalendar(2018, 6, 27, 16, 16, 47);
これらのパラメーターのない他のコンストラクターがあるため、hourOfDay, minuteとsecondを指定する必要がないことに注意してください。
タイムゾーンをパラメーターとして渡して、既定のロケールでこのタイムゾーンにカレンダーを作成できます。
new GregorianCalendar(TimeZone.getTimeZone("GMT+5:30"));
ロケールをパラメーターとして渡して、デフォルトのタイムゾーンでこのロケールでカレンダーを作成できます。
new GregorianCalendar(new Locale("en", "IN"));
最後に、タイムゾーンとロケールの両方をパラメーターとして渡すことができます。
new GregorianCalendar(TimeZone.getTimeZone("GMT+5:30"), new Locale("en", "IN"));
2.2. Java8の新しいメソッド
Java 8では、GregorianCalendar.に新しいメソッドが導入されました
from()メソッドは、ZonedDateTimeオブジェクトからデフォルトロケールのGregorianCalendarのインスタンスを取得します。
Using getCalendarType() we can get the type of the calendar instance.使用可能なカレンダータイプは、「gregory」、「buddhist」、および「Japanese」です。
たとえば、これを使用して、アプリケーションロジックに進む前に特定の種類のカレンダーがあることを確認できます。
@Test
public void test_Calendar_Return_Type_Valid() {
Calendar calendar = Calendar.getInstance();
assert ("gregory".equals(calendar.getCalendarType()));
}
このGregorianCalendar.と同じタイムライン上のポイントを表すCalling toZonedDateTime() we can convert the calendar object into a ZonedDateTime object
2.3. 日付の変更
カレンダーフィールドは、メソッドadd()、roll()、およびset()を使用して変更できます。
カレンダーの内部ルールセットに基づくThe add() method allows us to add time to the calendar in a specified unit:
@Test
public void test_whenAddOneDay_thenMonthIsChanged() {
int finalDay1 = 1;
int finalMonthJul = 6;
GregorianCalendar calendarExpected = new GregorianCalendar(2018, 5, 30);
calendarExpected.add(Calendar.DATE, 1);
System.out.println(calendarExpected.getTime());
assertEquals(calendarExpected.get(Calendar.DATE), finalDay1);
assertEquals(calendarExpected.get(Calendar.MONTH), finalMonthJul);
}
add()メソッドを使用して、カレンダーオブジェクトから時間を減算することもできます。
@Test
public void test_whenSubtractOneDay_thenMonthIsChanged() {
int finalDay31 = 31;
int finalMonthMay = 4;
GregorianCalendar calendarExpected = new GregorianCalendar(2018, 5, 1);
calendarExpected.add(Calendar.DATE, -1);
assertEquals(calendarExpected.get(Calendar.DATE), finalDay31);
assertEquals(calendarExpected.get(Calendar.MONTH), finalMonthMay);
}
add()メソッドを実行すると、カレンダーのミリ秒とすべてのフィールドが即座に再計算されます。
add()を使用すると、上位のカレンダーフィールド(この場合はMONTH)も変更される可能性があることに注意してください。
roll()メソッドは、大きなフィールドを変更せずに、指定されたカレンダーフィールドに署名された金額を追加します。 フィールドが大きいほど、時間の単位が大きくなります。 たとえば、DAY_OF_MONTHはHOUR.よりも大きい
月をロールアップする方法の例を見てみましょう。
この場合、より大きなフィールドであるYEARはインクリメントされません。
@Test
public void test_whenRollUpOneMonth_thenYearIsUnchanged() {
int rolledUpMonthJuly = 7, orginalYear2018 = 2018;
GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28);
calendarExpected.roll(Calendar.MONTH, 1);
assertEquals(calendarExpected.get(Calendar.MONTH), rolledUpMonthJuly);
assertEquals(calendarExpected.get(Calendar.YEAR), orginalYear2018);
}
同様に、月をロールダウンできます。
@Test
public void test_whenRollDownOneMonth_thenYearIsUnchanged() {
int rolledDownMonthJune = 5, orginalYear2018 = 2018;
GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28);
calendarExpected.roll(Calendar.MONTH, -1);
assertEquals(calendarExpected.get(Calendar.MONTH), rolledDownMonthJune);
assertEquals(calendarExpected.get(Calendar.YEAR), orginalYear2018);
}
We can directly set a calendar field to a specified value using the set() method.ミリ秒単位のカレンダーの時間値は、get()、getTime()、add()、またはroll()への次の呼び出しが行われるまで再計算されません。
したがって、set()を複数回呼び出しても、不要な計算はトリガーされません。
月フィールドを3に設定する例を見てみましょう(つまり、 4月):
@Test
public void test_setMonth() {
GregorianCalendarExample calendarDemo = new GregorianCalendarExample();
GregorianCalendar calendarActual = new GregorianCalendar(2018, 6, 28);
GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28);
calendarExpected.set(Calendar.MONTH, 3);
Date expectedDate = calendarExpected.getTime();
assertEquals(expectedDate, calendarDemo.setMonth(calendarActual, 3));
}
2.4. XMLGregorianCalendarの操作
JAXBでは、JavaクラスをXML表現にマッピングできます。 javax.xml.datatype.XMLGregorianCalendarタイプは、xsd:date、xsd:time、xsd:dateTimeなどの基本的なXSDスキーマタイプのマッピングに役立ちます。
GregorianCalendarタイプからXMLGregorianCalendarタイプに変換する例を見てみましょう。
@Test
public void test_toXMLGregorianCalendar() throws Exception {
GregorianCalendarExample calendarDemo = new GregorianCalendarExample();
DatatypeFactory datatypeFactory = DatatypeFactory.newInstance();
GregorianCalendar calendarActual = new GregorianCalendar(2018, 6, 28);
GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28);
XMLGregorianCalendar expectedXMLGregorianCalendar = datatypeFactory
.newXMLGregorianCalendar(calendarExpected);
assertEquals(
expectedXMLGregorianCalendar,
alendarDemo.toXMLGregorianCalendar(calendarActual));
}
カレンダーオブジェクトがXML形式に変換されると、メッセージングやWebサービス呼び出しなど、日付のシリアル化が必要なユースケースで使用できます。
XMLGregorianCalendarタイプからGregorianCalendarに戻す方法の例を見てみましょう。
@Test
public void test_toDate() throws DatatypeConfigurationException {
GregorianCalendar calendarActual = new GregorianCalendar(2018, 6, 28);
DatatypeFactory datatypeFactory = DatatypeFactory.newInstance();
XMLGregorianCalendar expectedXMLGregorianCalendar = datatypeFactory
.newXMLGregorianCalendar(calendarActual);
expectedXMLGregorianCalendar.toGregorianCalendar().getTime();
assertEquals(
calendarActual.getTime(),
expectedXMLGregorianCalendar.toGregorianCalendar().getTime() );
}
2.5. 日付の比較
CalendarクラスのcompareTo()メソッドを使用して、日付を比較できます。 結果は、基準日が将来の場合は正になり、基準データが過去の日付にある場合は負になります。
@Test
public void test_Compare_Date_FirstDate_Greater_SecondDate() {
GregorianCalendar firstDate = new GregorianCalendar(2018, 6, 28);
GregorianCalendar secondDate = new GregorianCalendar(2018, 5, 28);
assertTrue(1 == firstDate.compareTo(secondDate));
}
@Test
public void test_Compare_Date_FirstDate_Smaller_SecondDate() {
GregorianCalendar firstDate = new GregorianCalendar(2018, 5, 28);
GregorianCalendar secondDate = new GregorianCalendar(2018, 6, 28);
assertTrue(-1 == firstDate.compareTo(secondDate));
}
@Test
public void test_Compare_Date_Both_Dates_Equal() {
GregorianCalendar firstDate = new GregorianCalendar(2018, 6, 28);
GregorianCalendar secondDate = new GregorianCalendar(2018, 6, 28);
assertTrue(0 == firstDate.compareTo(secondDate));
}
2.6. 日付のフォーマット
ZonedDateTimeとDateTimeFormatterの組み合わせを使用して、GregorianCalendarを特定の形式に変換し、目的の出力を取得できます。
@Test
public void test_dateFormatdMMMuuuu() {
String expectedDate = new GregorianCalendar(2018, 6, 28).toZonedDateTime()
.format(DateTimeFormatter.ofPattern("d MMM uuuu"));
assertEquals("28 Jul 2018", expectedDate);
}
2.7. カレンダーに関する情報の取得
GregorianCalendarは、さまざまなカレンダー属性をフェッチするために使用できるいくつかのgetメソッドを提供します。 さまざまなオプションを見てみましょう。
-
getActualMaximum(int field) –は、現在の時刻値を考慮して、指定されたカレンダーフィールドの最大値を返します。 次の例では、6月が30日であるため、DAY_OF_MONTHフィールドに値30が返されます。
GregorianCalendar calendar = new GregorianCalendar(2018 , 5, 28); assertTrue(30 == calendar.getActualMaximum(calendar.DAY_OF_MONTH));
-
getActualMinimum(int field) –は、現在の時刻値を考慮して、指定されたカレンダーフィールドの最小値を返します。
GregorianCalendar calendar = new GregorianCalendar(2018 , 5, 28); assertTrue(1 == calendar.getActualMinimum(calendar.DAY_OF_MONTH));
-
getGreatestMinimum(int field) –は、指定されたカレンダーフィールドの最大最小値を返します。
GregorianCalendar calendar = new GregorianCalendar(2018 , 5, 28); assertTrue(1 == calendar.getGreatestMinimum(calendar.DAY_OF_MONTH));
-
getLeastMaximum(int field) –指定されたカレンダーフィールドの最小最大値を返します。 2月の日数は28日しかないため、DAY_OF_MONTHフィールドの場合は28です。
GregorianCalendar calendar = new GregorianCalendar(2018 , 5, 28); assertTrue(28 == calendar.getLeastMaximum(calendar.DAY_OF_MONTH));
-
getMaximum(int field) –は、指定されたカレンダーフィールドの最大値を返します。
GregorianCalendar calendar = new GregorianCalendar(2018 , 5, 28); assertTrue(31 == calendar.getMaximum(calendar.DAY_OF_MONTH));
-
getMinimum(int field) –は、指定されたカレンダーフィールドの最小値を返します。
GregorianCalendar calendar = new GregorianCalendar(2018 , 5, 28); assertTrue(1 == calendar.getMinimum(calendar.DAY_OF_MONTH));
-
getWeekYear() –は、次のGregorianCalendarで表されるyear of the week を返します。
GregorianCalendar calendar = new GregorianCalendar(2018 , 5, 28); assertTrue(2018 == calendar.getWeekYear());
-
getWeeksInWeekYear() –は、暦年の週年の週数を返します。
GregorianCalendar calendar = new GregorianCalendar(2018 , 5, 28); assertTrue(52 == calendar.getWeeksInWeekYear());
-
年がうるう年の場合、isLeapYear() –はtrueを返します。
GregorianCalendar calendar = new GregorianCalendar(2018 , 5, 28); assertTrue(false == calendar.isLeapYear(calendar.YEAR));
3. 結論
この記事では、GregorianCalendarの特定の側面について説明しました。
いつものように、サンプルコードはover on GitHubで利用できます。