1前書き

このチュートリアルでは、

GregorianCalendar

クラスについて簡単に説明します。


2

グレゴリオ暦



GregorianCalendar

は、抽象クラス

java.util.Calendar

の具象実装です。当然のことながら、グレゴリオ暦


2.1. インスタンスを取得する

__GregorianCalendarのインスタンスを取得するには、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

、およびsecondを指定できます。

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. Java 8

の新しいメソッド

Java 8では、__GregorianCalendarに新しいメソッドが導入されました。


  • from()

    メソッドは、ZonedDateTimeオブジェクトからデフォルトロケールで

    GregorianCalendar

    のインスタンスを取得します。


  • getCalendarType()

    を使用すると、カレンダーインスタンスの種類を取得できます。

たとえば、これを使用して、アプリケーションロジックに進む前に特定の種類のカレンダーがあることを確認できます。

@Test
public void test__Calendar__Return__Type__Valid() {
    Calendar calendar = Calendar.getInstance();
    assert ("gregory".equals(calendar.getCalendarType()));
}


  • toZonedDateTime()

    を呼び出すと、カレンダーオブジェクトをタイムライン上のこの

    GregorianCalendarと同じポイントを表す

    ZonedDateTime__オブジェクトに変換できます。


2.3. 日付を変更する

カレンダーフィールドは、メソッド

add()



roll()

、および

set()

を使用して変更できます。


  • add()

    メソッドを使用すると、カレンダーの内部ルールセットに基づいて、指定した単位でカレンダーに時間を追加できます。

@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);
}


  • set()

    メソッドを使ってカレンダーフィールドを指定された値に直接設定することができます** ミリ秒単位のカレンダーの時間値は、次の

    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)



    は、の最小値を返します。

現在の時刻値を考慮して指定されたカレンダーフィールド

+[source、java、gutter:、true]

GregorianCalendar calendar = new GregorianCalendar(2018 , 5, 28);
assertTrue(1 == calendar.getActualMinimum(calendar.DAY__OF__MONTH));



  • getGreatestMinimum(int field)



    は最大の最小値を返します

与えられたカレンダーフィールドの場合:

+[source、java、gutter:、true]

GregorianCalendar calendar = new GregorianCalendar(2018 , 5, 28);
assertTrue(1 == calendar.getGreatestMinimum(calendar.DAY__OF__MONTH));



  • getLeastMaximum(int field)



    の最小の最大値を返す

指定されたカレンダフィールド

DAY

OF

MONTH

フィールドの場合、これは28です。これは、2月の日数が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()



    thisで表されるを返す


グレゴリオ暦

:

+[source、java、gutter:、true]

GregorianCalendar calendar = new GregorianCalendar(2018 , 5, 28);
assertTrue(2018 == calendar.getWeekYear());



  • getWeeksInWeekYear()



    は週の週数を返します

暦年の年:

+[source、java、gutter:、true]

GregorianCalendar calendar = new GregorianCalendar(2018 , 5, 28);
assertTrue(52 == calendar.getWeeksInWeekYear());



  • isLeapYear()



    年がうるう年の場合はtrueを返します。

+[source、java、gutter:、true]

GregorianCalendar calendar = new GregorianCalendar(2018 , 5, 28);
assertTrue(false == calendar.isLeapYear(calendar.YEAR));


3結論

この記事では、

GregorianCalendar

の特定の側面について説明しました。

いつものように、サンプルコードはhttps://github.com/eugenp/tutorials/tree/master/java-dates[over GitHub]から入手できます。