מדריך java.util.GregorianCalendar

1. הקדמה

במדריך זה אנו נסתכל במהירות על ה- לוח השנה הגרגוריאני מעמד.

2. לוח השנה הגרגוריאני

לוח השנה הגרגוריאני הוא יישום קונקרטי של המעמד המופשט java.util.Calendar. באופן לא מפתיע, לוח השנה הגרגוריאני הוא לוח השנה האזרחי הנפוץ ביותר בעולם.

2.1. קבלת מקרה

ישנן שתי אפשרויות זמינות לקבל מופע של לוח השנה הגרגוריאני:Calendar.getInstance () ושימוש באחד הבונים.

בשיטת המפעל הסטטי Calendar.getInstance () אינה גישה מומלצת מכיוון שהיא תחזיר מופע סובייקטיבי לאזור ברירת המחדל.

זה עשוי להחזיר א בודהיסטי לוח השנה לתאילנדית או יפניתקישורי לוח שנה ליפן. אי ידיעת סוג המופע המוחזר עשויה להוביל ל- ClassCastException:

@Test (צפוי = ClassCastException.class) test_Class_Cast_Exception () בטל פומבי () {TimeZone tz = TimeZone.getTimeZone ("GMT + 9: 00"); Locale loc = Locale חדש ("ja", "JP", "JP"); לוח שנה לוח שנה = Calendar.getInstance (loc); GregorianCalendar gc = (GregorianCalendar) לוח שנה; }

באמצעות אחד משבע הבנאים העמוסים אנו יכולים לאתחל את לוּחַ שָׁנָה התנגד לתאריך ולשעה המוגדרים כברירת מחדל בהתאם למיקום מערכת ההפעלה שלנו או שנוכל לציין שילוב של תאריך, שעה, אזור ואזור זמן.

בואו נבין את הבונים השונים לפיהם א לוח השנה הגרגוריאני ניתן לייצר אובייקט.

קונסטרוקטור ברירת המחדל יאותחל את לוח השנה עם התאריך והשעה הנוכחיים באזור הזמן והמקום של מערכת ההפעלה:

גרגוריאני יומן חדש ();

אנחנו יכולים לציין את year, month, dayOfMonth, hourOfDay, דקה, והשנייה עבור אזור הזמן המוגדר כברירת מחדל עם אזור ברירת המחדל:

גרגוריאני לוח שנה חדש (2018, 6, 27, 16, 16, 47);

שים לב שאנחנו לא צריכים לציין hourOfDay, דקה ו שְׁנִיָה כמו שישנם בונים אחרים ללא פרמטרים אלה.

אנו יכולים להעביר את אזור הזמן כפרמטר ליצירת לוח שנה באזור זמן זה עם אזור ברירת המחדל:

גרגוריאני לוח שנה חדש (TimeZone.getTimeZone ("GMT + 5: 30"));

אנו יכולים להעביר את המקום כפרמטר ליצירת לוח שנה באזור זה עם אזור הזמן המוגדר כברירת מחדל:

לוח שנה גרגוריאני חדש (אזור חדש ("en", "IN"));

לבסוף נוכל להעביר את אזור הזמן ואת המקום כפרמטרים:

GregorianCalendar חדש (TimeZone.getTimeZone ("GMT + 5: 30"), אזור חדש ("en", "IN"));

2.2. שיטות חדשות עם Java 8

עם Java 8 הוצגו שיטות חדשות לוח השנה הגרגוריאני.

ה מ() השיטה מקבלת מופע של לוח השנה הגרגוריאני עם אזור ברירת המחדל מאובייקט ZonedDateTime.

באמצעות getCalendarType () אנו יכולים לקבל את סוג המופע בלוח השנה. סוגי לוח השנה הזמינים הם 'גרגורי', 'בודהיסטי' ו'יפני '.

אנחנו יכולים להשתמש בזה, למשל, כדי לוודא שיש לנו לוח שנה מסוג מסוים לפני שנמשיך עם לוגיקת היישום שלנו:

@Test ציבורי בטל test_Calendar_Return_Type_Valid () {לוח שנה לוח שנה = Calendar.getInstance (); assert ("gregory" .equals (calendar.getCalendarType ())); }

יִעוּד toZonedDateTime () אנו יכולים להמיר את אובייקט לוח השנה ל- ZonedDateTime לְהִתְנַגֵד המייצג את אותה נקודה בציר הזמן כמו זה לוח השנה הגרגוריאני.

2.3. שינוי תאריכים

ניתן לשנות את שדות היומן בשיטות לְהוֹסִיף(), גָלִיל() ו מַעֲרֶכֶת().

ה לְהוֹסִיף() השיטה מאפשרת לנו להוסיף זמן ליומן ביחידה מסוימת בהתבסס על מערך הכללים הפנימי של לוח השנה:

@Test ציבורי בטל test_whenAddOneDay_thenMonthIsChanged () {int finalDay1 = 1; int finalMonthJul = 6; לוח שנה של גרגוריאן-קלנדרינגExpected = גרגוריאני-לוח שנה חדש (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); }

אנחנו יכולים גם להשתמש ב- לְהוֹסִיף() שיטה להפחית את הזמן מאובייקט לוח השנה:

@Test פומבי מבטל test_whenSubtractOneDay_thenMonthIsChanged () {int finalDay31 = 31; int finalMonthMay = 4; GregorianCalendar לוח שנהExpected = גרגוריאני לוח שנה חדש (2018, 5, 1); calendarExpected.add (Calendar.DATE, -1); assertEquals (calendarExpected.get (Calendar.DATE), finalDay31); assertEquals (calendarExpected.get (Calendar.MONTH), finalMonthMay); }

ביצוע של לְהוֹסִיף() השיטה מאלצת חישוב מיידי מחדש של אלפיות השנייה של לוח השנה ושל כל השדות.

שים לב כי השימוש ב לְהוֹסִיף() עשוי גם לשנות את שדות היומן הגבוהים יותר (MONTH במקרה זה).

ה גָלִיל() השיטה מוסיפה סכום חתום לשדה היומן שצוין מבלי לשנות את השדות הגדולים יותר. שדה גדול יותר מייצג יחידת זמן גדולה יותר. לדוגמה, יום בחודש גדול מ- שָׁעָה.

בואו נראה דוגמה לאופן הפעלת חודשים.

במקרה הזה, שָׁנָה היותך שדה גדול יותר לא יגדל:

@Test פומבי מבטל test_whenRollUpOneMonth_thenYearIsUnchanged () {int rolledUpMonthJuly = 7, orginalYear2018 = 2018; לוח שנה של גרגוריאן-קלנדארהצפוי = לוח שנה של גרגוריאן חדש (2018, 6, 28); calendarExpected.roll (Calendar.MONTH, 1); assertEquals (calendarExpected.get (Calendar.MONTH), rolledUpMonthJuly); assertEquals (calendarExpected.get (Calendar.YEAR), orginalYear2018); }

באופן דומה, אנו יכולים להפיל חודשים:

@Test הציבור בטל test_whenRollDownOneMonth_thenYearIsUnchanged () {int rolledDownMonthJune = 5, orginalYear2018 = 2018; לוח השנה של גרגוריאן-קלנדרינגExpected = גרגוריאני-לוח שנה חדש (2018, 6, 28); calendarExpected.roll (Calendar.MONTH, -1); assertEquals (calendarExpected.get (Calendar.MONTH), rolledDownMonthJune); assertEquals (calendarExpected.get (Calendar.YEAR), orginalYear2018); }

אנו יכולים להגדיר ישירות שדה לוח שנה לערך מוגדר באמצעות ה- מַעֲרֶכֶת() שיטה. ערך הזמן של לוח השנה באלפיות השנייה לא יחושב מחדש עד לשיחה הבאה לקבל(), getTime (), לְהוֹסִיף() אוֹ גָלִיל() עשוי.

לפיכך, מספר שיחות אל מַעֲרֶכֶת() אל תפעיל חישובים מיותרים.

בואו נראה דוגמה שתגדיר את שדה החודש ל -3 (כלומר אפריל):

@Test ציבורי בטל test_setMonth () {GregorianCalendarExample calendarDemo = גרגוריאניCalendarExample חדש (); GregorianCalendar לוח שנה Actual = גרגוריאני לוח שנה חדש (2018, 6, 28); לוח שנה של גרגוריאן-קלנדארהצפוי = לוח שנה של גרגוריאן חדש (2018, 6, 28); calendarExpected.set (Calendar.MONTH, 3); תאריך expectDate = calendarExpected.getTime (); assertEquals (expectDate, calendarDemo.setMonth (calendarActual, 3)); }

2.4. עובד עם XMLGregorianCalendar

JAXB מאפשר מיפוי שיעורי Java לייצוגי XML. ה javax.xml.datatype.XMLGregorianCalendar סוג יכול לעזור במיפוי סוגי סכמות XSD בסיסיים כגון xsd: תאריך, xsd: זמן ו xsd: dateTime.

בואו נסתכל על דוגמה להמרה ממנה לוח השנה הגרגוריאני הקלד לתוך ה- XMLGregorianCalendar סוּג:

@Test הריק ציבורי test_toXMLGregorianCalendar () זורק חריג {GregorianCalendarExample calendarDemo = GregorianCalendarExample חדש (); DatatypeFactory datatypeFactory = DatatypeFactory.newInstance (); GregorianCalendar לוח שנה Actual = גרגוריאני לוח שנה חדש (2018, 6, 28); לוח שנה של גרגוריאן-קלנדארהצפוי = לוח שנה של גרגוריאן חדש (2018, 6, 28); XMLGregorianCalendar צפוי XMLGregorianCalendar = datatypeFactory .newXMLGregorianCalendar (calendarExpected); assertEquals (צפוי XMLGregorianCalendar, alendarDemo.toXMLGregorianCalendar (calendarActual)); }

לאחר שתורגם אובייקט היומן לפורמט XML, ניתן להשתמש בו בכל מקרי שימוש שדורשים סדרת תאריך, כמו הודעות או שיחות שירות אינטרנט.

בואו נראה דוגמה כיצד להמיר מ XMLGregorianCalendar הקלד בחזרה לוח השנה הגרגוריאני:

@Test הריק ציבורי test_toDate () זורק את DatatypeConfigurationException {GregorianCalendar calendarActual = גרגוריאני חדש Calender (2018, 6, 28); DatatypeFactory datatypeFactory = DatatypeFactory.newInstance (); XMLGregorianCalendar צפוי XMLGregorianCalendar = datatypeFactory .newXMLGregorianCalendar (calendarActual); expectXMLGregorianCalendar.toGregorianCalendar (). getTime (); assertEquals (calendarActual.getTime (), צפוי XMLGregorianCalendar.toGregorianCalendar (). getTime ()); }

2.5. השוואת תאריכים

אנחנו יכולים להשתמש ב- לוּחַ שָׁנָה שיעורים ' בהשוואה ל() שיטה להשוואת תאריכים. התוצאה תהיה חיובית אם תאריך הבסיס יהיה בעתיד ושלילי אם נתוני הבסיס היו בעבר התאריך שאנו משווים אותו ל:

@ מבחן הריק הציבורי test_Compare_Date_FirstDate_Greater_SecondDate () {GregorianCalendar firstDate = גרגוריאני חדש Kalender (2018, 6, 28); GregorianCalendar secondDate = חדש GregorianCalendar (2018, 5, 28); assertTrue (1 == firstDate.compareTo (secondDate)); } @Test ציבורי בטל test_Compare_Date_FirstDate_Smaller_SecondDate () {GregorianCalendar firstDate = גרגוריאני חדש Kalender (2018, 5, 28); GregorianCalendar secondDate = GregorianCalendar חדש (2018, 6, 28); assertTrue (-1 == firstDate.compareTo (secondDate)); } @Test ציבורי בטל test_Compare_Date_Both_Dates_Equal () {GregorianCalendar firstDate = GregorianCalendar חדש (2018, 6, 28); GregorianCalendar secondDate = GregorianCalendar חדש (2018, 6, 28); assertTrue (0 == firstDate.compareTo (secondDate)); }

2.6. עיצוב תאריכים

אנחנו יכולים להתגייר לוח השנה הגרגוריאני לתבנית ספציפית באמצעות שילוב של ZonedDateTime ו DateTimeFormatter כדי להשיג את התפוקה הרצויה:

@Test ציבורי בטל test_dateFormatdMMMuuuu () {מחרוזת expectDate = גרגוריאני חדש Kalender (2018, 6, 28) .toZonedDateTime (). פורמט (DateTimeFormatter.ofPattern ("d MMM uuuu)); assertEquals ("28 ביולי 2018", expectDate); }

2.7. קבלת מידע על לוח השנה

לוח השנה הגרגוריאני מספק כמה שיטות לקבל בהן ניתן להשיג מאפייני לוח שנה שונים. בואו נסתכל על האפשרויות השונות שיש לנו:

  • getActualMaximum (שדה int) מחזיר את הערך המקסימלי עבור שדה היומן שצוין תוך התחשבות בערכי הזמן הנוכחיים. הדוגמה הבאה תחזיר ערך 30 עבור ה- יום בחודש שדה כי ביוני יש 30 יום:
    לוח השנה של גרגוריאן קלנדה = לוח השנה הגרגוריאני חדש (2018, 5, 28); assertTrue (30 == calendar.getActualMaximum (לוח שנה. DAY_OF_MONTH));
  • getActualMinimum (שדה int) מחזיר את הערך המינימלי עבור שדה היומן שצוין תוך התחשבות בערכי הזמן הנוכחיים:
    לוח השנה של גרגוריאן קלנדה = לוח השנה הגרגוריאני חדש (2018, 5, 28); assertTrue (1 == calendar.getActualMinimum (לוח שנה. DAY_OF_MONTH));
  • getGreatestMinimum (שדה int) מחזירה את הערך המינימלי הגבוה ביותר עבור שדה היומן הנתון:
    לוח השנה של גרגוריאן קלנדה = לוח השנה הגרגוריאני חדש (2018, 5, 28); assertTrue (1 == calendar.getGreatestMinimum (לוח שנה. DAY_OF_MONTH));
  • getLeastMaximum (שדה int) מחזירה את הערך המקסימלי הנמוך ביותר עבור שדה היומן הנתון. בשביל ה יום בחודש שדה זה 28, מכיוון שלפברואר עשויים להיות רק 28 יום:
    לוח השנה של גרגוריאן קלנדה = לוח השנה הגרגוריאני חדש (2018, 5, 28); assertTrue (28 == calendar.getLeastMaximum (לוח שנה. DAY_OF_MONTH));
  • getMaximum (שדה int) מחזירה את הערך המקסימלי עבור שדה היומן הנתון:
    לוח השנה של גרגוריאן קלנדה = לוח השנה הגרגוריאני חדש (2018, 5, 28); assertTrue (31 == calendar.getMaximum (לוח שנה. DAY_OF_MONTH));
  • getMinimum (שדה int) מחזיר את הערך המינימלי עבור שדה היומן הנתון:
    לוח השנה של גרגוריאן קלנדה = לוח השנה הגרגוריאני חדש (2018, 5, 28); assertTrue (1 == calendar.getMinimum (לוח שנה. DAY_OF_MONTH));
  • getWeekYear () מחזירה את שנת השבוע המיוצגת על ידי זה לוח השנה הגרגוריאני:
    לוח השנה של גרגוריאן קלנדה = לוח השנה הגרגוריאני חדש (2018, 5, 28); assertTrue (2018 == calendar.getWeekYear ());
  • getWeeksInWeekYear () מחזירה את מספר השבועות בשנה בשבוע לשנה הקלנדרית:
    לוח השנה של גרגוריאן קלנדה = לוח השנה הגרגוריאני חדש (2018, 5, 28); assertTrue (52 == calendar.getWeeksInWeekYear ());
  • isLeapYear () מחזיר נכון אם השנה היא שנה מעוברת:
    לוח השנה של גרגוריאן קלנדה = לוח השנה הגרגוריאני חדש (2018, 5, 28); assertTrue (false == calendar.isLeapYear (calendar.YEAR));

3. מסקנה

במאמר זה בחנו היבטים מסוימים של לוח השנה הגרגוריאני.

כמו תמיד, קוד הדוגמה זמין ב- GitHub.