Gids voor java.util.GregorianCalendar

1. Inleiding

In deze tutorial gaan we een snelle blik werpen op de Gregoriaanse kalender klasse.

2. Gregoriaanse kalender

Gregoriaanse kalender is een concrete implementatie van de abstracte klasse java.util.Calendar. Het is niet verrassend dat de Gregoriaanse kalender de meest gebruikte burgerlijke kalender ter wereld is.

2.1. Een instantie ophalen

Er zijn twee opties beschikbaar om een ​​exemplaar van Gregoriaanse kalender:Calendar.getInstance () en met behulp van een van de constructeurs.

Met behulp van de statische fabrieksmethode Calendar.getInstance () is geen aanbevolen aanpak, omdat het een subjectieve instantie naar de standaardlandinstelling retourneert.

Het kan een Boeddhistische kalender voor Thai of JapaneseImperialCalendar voor Japan. Als u niet weet welk type exemplaar wordt geretourneerd, kan dit leiden tot een ClassCastException:

@Test (verwacht = ClassCastException.class) public void test_Class_Cast_Exception () {TimeZone tz = TimeZone.getTimeZone ("GMT + 9: 00"); Locale loc = nieuwe Locale ("ja", "JP", "JP"); Kalenderkalender = Calendar.getInstance (loc); GregorianCalendar gc = (GregorianCalendar) kalender; }

Met behulp van een van de zeven overbelaste constructors kunnen we de Kalender object ofwel met de standaard datum en tijd, afhankelijk van de landinstelling van ons besturingssysteem, of we kunnen een combinatie van datum, tijd, landinstelling en tijdzone specificeren.

Laten we de verschillende constructeurs begrijpen waarmee a Gregoriaanse kalender object kan worden geïnstantieerd.

De standaardconstructor initialiseert de kalender met de huidige datum en tijd in de tijdzone en landinstelling van het besturingssysteem:

nieuwe GregorianCalendar ();

We kunnen de jaar, maand, dayOfMonth, hourOfDay, minuut, en ten tweede voor de standaardtijdzone met de standaardlandinstelling:

nieuwe Gregoriaanse kalender (2018, 6, 27, 16, 16, 47);

Merk op dat we niet hoeven te specificeren hourOfDay, minuut en tweede aangezien er andere constructors zijn zonder deze parameters.

We kunnen de tijdzone doorgeven als parameter om een ​​kalender in deze tijdzone te maken met de standaardlandinstelling:

nieuwe GregorianCalendar (TimeZone.getTimeZone ("GMT + 5: 30"));

We kunnen de landinstelling doorgeven als parameter om een ​​kalender in deze landinstelling te maken met de standaardtijdzone:

new GregorianCalendar (new Locale ("en", "IN"));

Ten slotte kunnen we zowel de tijdzone als de locale als parameters doorgeven:

nieuwe GregorianCalendar (TimeZone.getTimeZone ("GMT + 5: 30"), nieuwe Locale ("en", "IN"));

2.2. Nieuwe methoden met Java 8

Met Java 8 zijn nieuwe methoden geïntroduceerd in Gregoriaanse kalender.

De van() methode krijgt een instantie van Gregoriaanse kalender met de standaardlandinstelling van een ZonedDateTime-object.

Gebruik makend van getCalendarType () we kunnen het type kalenderinstantie krijgen. De beschikbare kalendertypen zijn ‘Gregorius ',‘ Boeddhistisch' en 'Japans'.

We kunnen dit bijvoorbeeld gebruiken om ervoor te zorgen dat we een kalender van een bepaald type hebben voordat we verder gaan met onze applicatielogica:

@Test openbare ongeldig test_Calendar_Return_Type_Valid () {Calendar calendar = Calendar.getInstance (); assert ("gregory" .equals (calendar.getCalendarType ())); }

Roeping toZonedDateTime () we kunnen het kalenderobject omzetten in een ZonedDateTime voorwerp dat vertegenwoordigt hetzelfde punt op de tijdlijn als dit Gregoriaanse kalender.

2.3. Datums wijzigen

De kalendervelden kunnen worden gewijzigd met behulp van de methoden toevoegen(), rollen() en set ().

De toevoegen() methode stelt ons in staat om tijd aan de kalender toe te voegen in een gespecificeerde eenheid gebaseerd op de interne regelset van de kalender:

@Test openbare ongeldige test_whenAddOneDay_thenMonthIsChanged () {int finalDay1 = 1; int finalMonthJul = 6; GregorianCalendar calendarExpected = nieuwe 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); }

We kunnen ook de toevoegen() methode om tijd af te trekken van het kalenderobject:

@Test openbare ongeldige test_whenSubtractOneDay_thenMonthIsChanged () {int finalDay31 = 31; int finalMonthMay = 4; GregorianCalendar calendarExpected = nieuwe GregorianCalendar (2018, 5, 1); calendarExpected.add (Calendar.DATE, -1); assertEquals (calendarExpected.get (Calendar.DATE), finalDay31); assertEquals (calendarExpected.get (Calendar.MONTH), finalMonthMay); }

Uitvoering van het toevoegen() methode forceert een onmiddellijke herberekening van de milliseconden van de kalender en alle velden.

Merk op dat het gebruik van toevoegen() kan ook de hogere kalendervelden wijzigen (in dit geval MAAND).

De rollen() methode voegt een getekend bedrag toe aan het opgegeven kalenderveld zonder de grotere velden te wijzigen. Een groter veld vertegenwoordigt een grotere tijdseenheid. Bijvoorbeeld, DAG VAN DE MAAND is groter dan UUR.

Laten we eens kijken naar een voorbeeld van hoe u maanden kunt oprollen.

In dit geval, JAAR zijnde een groter veld zal niet worden opgehoogd:

@Test openbare ongeldige test_whenRollUpOneMonth_thenYearIsUnchanged () {int rolledUpMonthJuly = 7, orginalYear2018 = 2018; GregorianCalendar calendarExpected = nieuwe GregorianCalendar (2018, 6, 28); calendarExpected.roll (Calendar.MONTH, 1); assertEquals (calendarExpected.get (Calendar.MONTH), rolledUpMonthJuly); assertEquals (calendarExpected.get (Calendar.YEAR), orginalYear2018); }

Evenzo kunnen we maanden terugdraaien:

@Test openbare ongeldige test_whenRollDownOneMonth_thenYearIsUnchanged () {int rolledDownMonthJune = 5, orginalYear2018 = 2018; GregorianCalendar calendarExpected = nieuwe GregorianCalendar (2018, 6, 28); calendarExpected.roll (Calendar.MONTH, -1); assertEquals (calendarExpected.get (Calendar.MONTH), rolledDownMonthJune); assertEquals (calendarExpected.get (Calendar.YEAR), orginalYear2018); }

We kunnen een kalenderveld direct instellen op een opgegeven waarde met behulp van de set () methode. De tijdwaarde van de kalender in milliseconden wordt pas opnieuw berekend bij de volgende aanroep van krijgen(), krijg tijd(), toevoegen() of rollen() is gemaakt.

Dus meerdere oproepen naar set () activeer geen onnodige berekeningen.

Laten we een voorbeeld bekijken waarbij het maandveld wordt ingesteld op 3 (d.w.z. april):

@Test openbare ongeldige test_setMonth () {GregorianCalendarExample calendarDemo = nieuwe GregorianCalendarExample (); GregorianCalendar calendarActual = nieuwe GregorianCalendar (2018, 6, 28); GregorianCalendar calendarExpected = nieuwe GregorianCalendar (2018, 6, 28); calendarExpected.set (Calendar.MONTH, 3); Datum verwachteDate = calendarExpected.getTime (); assertEquals (verwachteDate, calendarDemo.setMonth (calendarActual, 3)); }

2.4. Werken met XMLGregorianCalendar

JAXB maakt het mogelijk om Java-klassen toe te wijzen aan XML-representaties. De javax.xml.datatype.XMLGregorianCalendar type kan helpen bij het in kaart brengen van de basistypen XSD-schema's, zoals xsd: datum, xsd: tijd en xsd: dateTime.

Laten we een voorbeeld bekijken om van te converteren Gregoriaanse kalender typ in het XMLGregorianCalendar type:

@Test public void test_toXMLGregorianCalendar () gooit Uitzondering {GregorianCalendarExample calendarDemo = nieuwe GregorianCalendarExample (); DatatypeFactory datatypeFactory = DatatypeFactory.newInstance (); GregorianCalendar calendarActual = nieuwe GregorianCalendar (2018, 6, 28); GregorianCalendar calendarExpected = nieuwe GregorianCalendar (2018, 6, 28); XMLGregorianCalendar verwachtXMLGregorianCalendar = datatypeFactory .newXMLGregorianCalendar (calendarExpected); assertEquals (verwachteXMLGregorianCalendar, alendarDemo.toXMLGregorianCalendar (calendarActual)); }

Nadat het kalenderobject is vertaald in XML-indeling, kan het worden gebruikt in alle gevallen waarin een datum moet worden geserialiseerd, zoals berichtenuitwisseling of webservice-oproepen.

Laten we een voorbeeld bekijken van hoe u kunt converteren van XMLGregorianCalendar typ terug in Gregoriaanse kalender:

@Test public void test_toDate () gooit DatatypeConfigurationException {GregorianCalendar calendarActual = nieuwe GregorianCalendar (2018, 6, 28); DatatypeFactory datatypeFactory = DatatypeFactory.newInstance (); XMLGregorianCalendar verwachtXMLGregorianCalendar = datatypeFactory .newXMLGregorianCalendar (calendarActual); verwachteXMLGregorianCalendar.toGregorianCalendar (). getTime (); assertEquals (calendarActual.getTime (), verwachtXMLGregorianCalendar.toGregorianCalendar (). getTime ()); }

2.5. Datums vergelijken

We kunnen de Kalender klassen' vergelijk met() methode om datums te vergelijken. Het resultaat is positief als de basisdatum in de toekomst ligt en negatief als de basisgegevens in het verleden liggen van de datum die we vergelijken met:

@Test public void test_Compare_Date_FirstDate_Greater_SecondDate () {GregorianCalendar firstDate = nieuwe GregorianCalendar (2018, 6, 28); GregorianCalendar secondDate = nieuwe GregorianCalendar (2018, 5, 28); assertTrue (1 == firstDate.compareTo (secondDate)); } @Test public void test_Compare_Date_FirstDate_Smaller_SecondDate () {GregorianCalendar firstDate = nieuwe GregorianCalendar (2018, 5, 28); GregorianCalendar secondDate = nieuwe GregorianCalendar (2018, 6, 28); assertTrue (-1 == firstDate.compareTo (secondDate)); } @Test public void test_Compare_Date_Both_Dates_Equal () {GregorianCalendar firstDate = nieuwe GregorianCalendar (2018, 6, 28); GregorianCalendar secondDate = nieuwe GregorianCalendar (2018, 6, 28); assertTrue (0 == firstDate.compareTo (secondDate)); }

2.6. Datums opmaken

We kunnen converteren Gregoriaanse kalender naar een specifiek formaat door een combinatie te gebruiken van ZonedDateTime en DateTimeFormatter om de gewenste output te krijgen:

@Test public void test_dateFormatdMMMuuuu () {String verwachteDate = nieuwe GregorianCalendar (2018, 6, 28) .toZonedDateTime () .format (DateTimeFormatter.ofPattern ("d MMM uuuu")); assertEquals ("28 juli 2018", verwachte datum); }

2.7. Informatie opvragen over de kalender

Gregoriaanse kalender biedt verschillende ophaalmethoden die kunnen worden gebruikt om verschillende kalenderattributen op te halen. Laten we eens kijken naar de verschillende opties die we hebben:

  • getActualMaximum (int veld) geeft de maximale waarde voor het opgegeven kalenderveld terug, rekening houdend met de huidige tijdwaarden. In het volgende voorbeeld wordt waarde 30 geretourneerd voor de DAG VAN DE MAAND veld omdat juni 30 dagen heeft:
    GregorianCalendar-kalender = nieuwe GregorianCalendar (2018, 5, 28); assertTrue (30 == calendar.getActualMaximum (calendar.DAY_OF_MONTH));
  • getActualMinimum (int veld) geeft de minimumwaarde terug voor het opgegeven kalenderveld, rekening houdend met de huidige tijdwaarden:
    GregorianCalendar-kalender = nieuwe GregorianCalendar (2018, 5, 28); assertTrue (1 == calendar.getActualMinimum (calendar.DAY_OF_MONTH));
  • getGreatestMinimum (int veld) geeft de hoogste minimumwaarde terug voor het opgegeven kalenderveld:
    GregorianCalendar-kalender = nieuwe GregorianCalendar (2018, 5, 28); assertTrue (1 == calendar.getGreatestMinimum (calendar.DAY_OF_MONTH));
  • getLeastMaximum (int veld) Retourneert de laagste maximumwaarde voor het opgegeven kalenderveld. Voor de DAG VAN DE MAAND veld is dit 28, omdat februari slechts 28 dagen kan hebben:
    GregorianCalendar-kalender = nieuwe GregorianCalendar (2018, 5, 28); assertTrue (28 == calendar.getLeastMaximum (calendar.DAY_OF_MONTH));
  • getMaximum (int veld) geeft de maximale waarde terug voor het opgegeven kalenderveld:
    GregorianCalendar-kalender = nieuwe GregorianCalendar (2018, 5, 28); assertTrue (31 == calendar.getMaximum (calendar.DAY_OF_MONTH));
  • getMinimum (int veld) geeft de minimumwaarde terug voor het opgegeven kalenderveld:
    GregorianCalendar-kalender = nieuwe GregorianCalendar (2018, 5, 28); assertTrue (1 == calendar.getMinimum (calendar.DAY_OF_MONTH));
  • getWeekYear () geeft het jaar van de week terug dat hierdoor wordt vertegenwoordigd Gregoriaanse kalender:
    GregorianCalendar-kalender = nieuwe GregorianCalendar (2018, 5, 28); assertTrue (2018 == calendar.getWeekYear ());
  • getWeeksInWeekYear () geeft het aantal weken in het weekjaar voor het kalenderjaar terug:
    GregorianCalendar-kalender = nieuwe GregorianCalendar (2018, 5, 28); assertTrue (52 == calendar.getWeeksInWeekYear ());
  • isLeapYear () geeft true terug als het jaar een schrikkeljaar is:
    GregorianCalendar-kalender = nieuwe GregorianCalendar (2018, 5, 28); assertTrue (false == calendar.isLeapYear (calendar.YEAR));

3. Conclusie

In dit artikel hebben we bepaalde aspecten van Gregoriaanse kalender.

Zoals altijd is de voorbeeldcode beschikbaar op GitHub.