Vodič za java.util.GregorianCalendar

1. Uvod

U ovom ćemo uputstvu na brzinu zaviriti u Gregorijanski kalendar razred.

2. Gregorijanski kalendar

Gregorijanski kalendar je konkretna provedba apstraktne klase java.util.Kalendar. Nije iznenađujuće da je Gregorijanski kalendar najčešće korišten građanski kalendar na svijetu.

2.1. Dobivanje instance

Dostupne su dvije mogućnosti za dobivanje instance Gregorijanski kalendar:Calendar.getInstance () i koristeći jedan od konstruktora.

Korištenjem statičke tvorničke metode Calendar.getInstance () nije preporučeni pristup jer će vratiti instancu subjektivnu na zadani jezik.

Moglo bi se vratiti a Budistički kalendar za tajlandske ili JapaneseImperialCalendar za Japan. Nepoznavanje vrste instance koja se vraća može dovesti do a ClassCastException:

@Test (očekuje se = ClassCastException.class) public void test_Class_Cast_Exception () {TimeZone tz = TimeZone.getTimeZone ("GMT + 9: 00"); Locale loc = novi Locale ("ja", "JP", "JP"); Kalendar kalendara = Calendar.getInstance (loc); GregorianCalendar gc = (GregorianCalendar) kalendar; }

Korištenjem jednog od sedam preopterećenih konstruktora možemo inicijalizirati Kalendar objekt sa zadanim datumom i vremenom, ovisno o lokalitetu našeg operativnog sustava ili možemo odrediti kombinaciju datuma, vremena, lokalizacije i vremenske zone.

Razumijemo različite konstruktore pomoću kojih a Gregorijanski kalendar objekt može biti instanciran.

Zadani konstruktor inicijalizirat će kalendar s trenutnim datumom i vremenom u vremenskoj zoni i lokalnom okruženju operativnog sustava:

novi GregorianCalendar ();

Možemo odrediti godina, mjesec, danMjesec, satDan, minuta, i drugo za zadanu vremensku zonu sa zadanim lokalitetom:

novi GregorianCalendar (2018, 6, 27, 16, 16, 47);

Imajte na umu da ne moramo precizirati hourOfDay, minute i drugi kao što postoje i drugi konstruktori bez ovih parametara.

Vremensku zonu možemo proslijediti kao parametar za stvaranje kalendara u ovoj vremenskoj zoni sa zadanim lokalitetom:

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

Lokalni jezik možemo proslijediti kao parametar za stvaranje kalendara u ovom lokalitetu sa zadanom vremenskom zonom:

novi GregorianCalendar (novi jezik ("en", "IN"));

Napokon, vremensku zonu i lokalizaciju možemo proslijediti kao parametre:

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

2.2. Nove metode s Javom 8

S Javom 8 uvedene su nove metode Gregorijanski kalendar.

The iz() metoda dobiva primjerak Gregorijanski kalendar sa zadanim lokalitetom iz objekta ZonedDateTime.

Koristeći getCalendarType () možemo dobiti vrstu instance kalendara. Dostupne vrste kalendara su "gregory", "budistički" i "japanski".

Ovo možemo koristiti, na primjer, kako bismo bili sigurni da imamo kalendar određenog tipa prije nego što nastavimo s našom logikom aplikacije:

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

Pozivanje toZonedDateTime () kalendarski objekt možemo pretvoriti u ZonedDateTime objekt koja predstavlja istu točku na vremenskoj liniji kao i ova Gregorijanski kalendar.

2.3. Izmjena datuma

Polja kalendara mogu se mijenjati pomoću metoda dodati(), svitak() i postavi ().

The dodati() metoda omogućuje nam dodavanje vremena u kalendar u određenoj jedinici na temelju unutarnjeg skupa pravila kalendara:

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

Također možemo koristiti dodati() metoda oduzimanja vremena od objekta kalendara:

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

Izvršenje dodati() metoda prisiljava na trenutno ponovno izračunavanje milisekundi kalendara i svih polja.

Imajte na umu da pomoću dodati() također može promijeniti viša polja kalendara (u ovom slučaju MJESEC).

The svitak() metoda dodaje potpisani iznos u navedeno polje kalendara bez mijenjanja većih polja. Veće polje predstavlja veću jedinicu vremena. Na primjer, DAY_OF_MONTH je veći od SAT.

Pogledajmo primjer kako smotati mjesece.

U ovom slučaju, GODINA budući da je veće polje neće se povećavati:

@Test public void test_whenRollUpOneMonth_thenYearIsUnchanged () {int rolledUpMonthJuly = 7, orginalYear2018 = 2018; GregorianCalendar calendarExpected = novi GregorianCalendar (2018, 6, 28); calendarExpected.roll (Kalendar.MJESEC, 1); assertEquals (calendarExpected.get (Calendar.MONTH), rolledUpMonthJuly); assertEquals (calendarExpected.get (Calendar.YEAR), orginalYear2018); }

Slično tome, možemo se spuštati prema mjesecima:

@Test public void test_whenRollDownOneMonth_thenYearIsUnchanged () {int rolledDownMonthJune = 5, orginalYear2018 = 2018; GregorianCalendar calendarExpected = novi GregorianCalendar (2018, 6, 28); calendarExpected.roll (Kalendar.MJESEC, -1); assertEquals (calendarExpected.get (Calendar.MONTH), rolledDownMonthJune); assertEquals (calendarExpected.get (Calendar.YEAR), orginalYear2018); }

Pomoću alata možemo izravno postaviti polje kalendara na zadanu vrijednost postavi () metoda. Vrijednost vremena kalendara u milisekundama neće se preračunati do sljedećeg poziva na dobiti(), getTime (), dodati() ili svitak() je izrađena.

Dakle, višestruki pozivi na postavi () nemojte pokretati nepotrebna izračunavanja.

Pogledajmo primjer koji će polje za mjesec postaviti na 3 (tj. Travanj):

@Test public void test_setMonth () {GregorianCalendarExample calendarDemo = novi GregorianCalendarExample (); GregorianCalendar calendarActual = novi GregorianCalendar (2018, 6, 28); GregorianCalendar calendarExpected = novi GregorianCalendar (2018, 6, 28); calendarExpected.set (Calendar.MONTH, 3); Datum očekujeDatum = kalendarExpected.getTime (); assertEquals (očekuje seDate, calendarDemo.setMonth (calendarActual, 3)); }

2.4. Raditi sa XMLGregorianCalendar

JAXB omogućuje mapiranje Java klasa u XML reprezentacije. The javax.xml.datatype.XMLGregorianCalendar type može pomoći u mapiranju osnovnih tipova XSD shema kao što su xsd: datum, xsd: vrijeme i xsd: dateTime.

Pogledajmo primjer za pretvorbu Gregorijanski kalendar upišite u XMLGregorianCalendar tip:

@Test public void test_toXMLGregorianCalendar () baca iznimku {GregorianCalendarExample calendarDemo = novi GregorianCalendarExample (); DatatypeFactory datatypeFactory = DatatypeFactory.newInstance (); GregorianCalendar calendarActual = novi GregorianCalendar (2018, 6, 28); GregorianCalendar calendarExpected = novi GregorianCalendar (2018, 6, 28); Očekuje se XMLGregorianCalendarXMLGregorianCalendar = datatypeFactory .newXMLGregorianCalendar (calendarEx očekuje); assertEquals (očekivaniXMLGregorianCalendar, alendarDemo.toXMLGregorianCalendar (calendarActual)); }

Nakon što je objekt kalendara preveden u XML format, može se koristiti u svim slučajevima korištenja koji zahtijevaju serializaciju datuma, poput razmjene poruka ili poziva web usluga.

Pogledajmo primjer kako pretvoriti iz XMLGregorianCalendar tip natrag u Gregorijanski kalendar:

@Test public void test_toDate () baca DatatypeConfigurationException {GregorianCalendar calendarActual = new GregorianCalendar (2018, 6, 28); DatatypeFactory datatypeFactory = DatatypeFactory.newInstance (); Očekuje se XMLGregorianCalendarXMLGregorianCalendar = datatypeFactory .newXMLGregorianCalendar (calendarActual); očekujeXMLGregorianCalendar.toGregorianCalendar (). getTime (); assertEquals (calendarActual.getTime (), očekivaniXMLGregorianCalendar.toGregorianCalendar (). getTime ()); }

2.5. Usporedba datuma

Možemo koristiti Kalendar satovi ' compareTo () metoda za usporedbu datuma. Rezultat će biti pozitivan ako je bazni datum u budućnosti i negativan ako su osnovni podaci u prošlosti datuma s kojim ga uspoređujemo:

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

2.6. Oblikovanje datuma

Možemo se pretvoriti Gregorijanski kalendar u određeni format upotrebom kombinacije ZonedDateTime i DateTimeFormatter da biste dobili željeni izlaz:

@Test public void test_dateFormatdMMMuuuu () {String očekujeDate = novi GregorianCalendar (2018, 6, 28) .toZonedDateTime () .format (DateTimeFormatter.ofPattern ("d MMM uuuu")); assertEquals ("28. srpnja 2018.", očekuje seDatum); }

2.7. Dobivanje informacija o kalendaru

Gregorijanski kalendar pruža nekoliko metoda dobivanja koje se mogu koristiti za dohvaćanje različitih atributa kalendara. Pogledajmo različite mogućnosti koje imamo:

  • getActualMaximum (int polje) vraća maksimalnu vrijednost za navedeno polje kalendara uzimajući u obzir trenutne vrijednosti vremena. Sljedeći će primjer vratiti vrijednost 30 za DAY_OF_MONTH polje jer lipanj ima 30 dana:
    Kalendar GregorianCalendar = novi GregorianCalendar (2018, 5, 28); assertTrue (30 == calendar.getActualMaximum (calendar.DAY_OF_MONTH));
  • getActualMinimum (int polje) vraća minimalnu vrijednost za navedeno polje kalendara uzimajući u obzir trenutne vrijednosti vremena:
    Kalendar GregorianCalendar = novi GregorianCalendar (2018, 5, 28); assertTrue (1 == calendar.getActualMinimum (calendar.DAY_OF_MONTH));
  • getGreatestMinimum (int polje) vraća najvišu minimalnu vrijednost za dano polje kalendara:
    Kalendar GregorianCalendar = novi GregorianCalendar (2018, 5, 28); assertTrue (1 == calendar.getGreatestMinimum (calendar.DAY_OF_MONTH));
  • getLeastMaximum (int polje) Vraća najnižu maksimalnu vrijednost za dano polje kalendara. Za DAY_OF_MONTH polje je ovo 28, jer veljača može imati samo 28 dana:
    Kalendar GregorianCalendar = novi GregorianCalendar (2018, 5, 28); assertTrue (28 == calendar.getLeastMaximum (calendar.DAY_OF_MONTH));
  • getMaximum (int polje) vraća maksimalnu vrijednost za dano polje kalendara:
    Kalendar GregorianCalendar = novi GregorianCalendar (2018, 5, 28); assertTrue (31 == kalendar.getMaximum (kalendar.DAY_OF_MONTH));
  • getMinimum (int polje) vraća minimalnu vrijednost za dato polje kalendara:
    Kalendar GregorianCalendar = novi GregorianCalendar (2018, 5, 28); assertTrue (1 == calendar.getMinimum (calendar.DAY_OF_MONTH));
  • getWeekYear () vraća godinu u tjednu koju predstavlja ovo Gregorijanski kalendar:
    Kalendar GregorianCalendar = novi GregorianCalendar (2018, 5, 28); assertTrue (2018 == calendar.getWeekYear ());
  • getWeeksInWeekYear () vraća broj tjedana u tjednoj godini za kalendarsku godinu:
    Kalendar GregorianCalendar = novi GregorianCalendar (2018, 5, 28); assertTrue (52 == calendar.getWeeksInWeekYear ());
  • isLeapYear () vraća true ako je godina prijestupna:
    Kalendar GregorianCalendar = novi GregorianCalendar (2018, 5, 28); assertTrue (false == calendar.isLeapYear (calendar.YEAR));

3. Zaključak

U ovom smo članku istražili određene aspekte Gregorijanski kalendar.

Kao i uvijek, uzorak koda dostupan je na GitHubu.