מעבר ל- API החדש של Java 8 Date Time API

1. סקירה כללית

במדריך זה תלמד כיצד לשדרג את הקוד שלך כדי למנף את ה- Date Time API החדש שהוצג ב- Java 8.

2. ממשק API חדש במבט חטוף

העבודה עם תאריכים בג'אווה הייתה בעבר קשה. ספריית התאריכים הישנה שסופקה על ידי JDK כללה רק שלוש כיתות: java.util.Date, java.util.Calendar ו java.util.Timezone.

אלה התאימו רק למשימות הבסיסיות ביותר. לכל דבר מורכב אפילו מרחוק, המפתחים נאלצו להשתמש בספריות צד שלישי או לכתוב טונות של קוד מותאם אישית.

Java 8 הציגה ממשק API חדש של Date Time (java.util.time. *) שמבוסס באופן רופף על ספריית Java הפופולרית בשם JodaTime. ה- API החדש הזה פשט בצורה דרמטית עיבוד תאריכים ושעות ותיקן חסרונות רבים בספריית התאריכים הישנה.

1.1. בהירות API

יתרון ראשון של ה- API החדש הוא בְּהִירוּת - ה- API מאוד ברור, תמציתי וקל להבנה. אין בו הרבה סתירות שנמצאות בספריה הישנה כמו למשל מספור השדות (בחודשי לוח השנה הם מבוססי אפס, אך ימי השבוע הם מבוססי אחד).

1.2. גמישות API

יתרון נוסף הוא גמישות - עבודה עם מספר ייצוגים של זמן. ספריית התאריכים הישנה כללה רק שיעור ייצוג חד פעמי - java.util.Date, שלמרות שמו, הוא למעשה חותמת זמן. הוא מאחסן רק את מספר האלפיות השנייה שחלפו מאז תקופת יוניקס.

ל- API החדש יש הרבה ייצוגי זמן שונים, שכל אחד מהם מתאים למקרי שימוש שונים:

  • רֶגַע - מייצג נקודת זמן (חותמת זמן)
  • LocalDate - מייצג תאריך (שנה, חודש, יום)
  • LocalDateTime - כמו LocalDate, אך כולל זמן בדיוק ננו-שנייה
  • OffsetDateTime - כמו LocalDateTime, אך עם קיזוז אזור הזמן
  • זמן מקומי - זמן בדיוק ננו-שנייה וללא מידע על תאריך
  • ZonedDateTime - כמו OffsetDateTime, אך כולל מזהה אזור זמן
  • OffsetLocalTime - כמו זמן מקומי, אך עם קיזוז אזור הזמן
  • חודש יום - חודש ויום, ללא שנה או זמן
  • שנת חודש - חודש ושנה, ללא יום ושעה
  • מֶשֶׁך - משך הזמן המיוצג בשניות, דקות ושעות. יש דיוק ננו שנייה
  • פרק זמן - משך הזמן המיוצג בימים, חודשים ושנים

1.3. אי-משתנות ובטיחות חוטים

יתרון נוסף הוא שכל ייצוגי הזמן ב- Java 8 Date Time API הם בלתי ניתן לשינוי ובכך בטוח לחוטים.

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

שיעורים ישנים כגון java.util.Date לא היו בטוחים בחוטים ויכולים להציג באגים מקבילים מאוד עדינים.

1.4. שרשרת שיטה

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

ZonedDateTime nextFriday = LocalDateTime.now () .plusHours (1) .with (TemporalAdjusters.next (DayOfWeek.FRIDAY)) .atZone (ZoneId.of ("PST")); 

2. דוגמאות

הדוגמאות שלהלן ידגימו כיצד לבצע משימות נפוצות עם ממשק API ישן וחדש.

מקבל זמן עדכני

// תאריך ישן עכשיו = תאריך חדש (); // חדש ZonedDateTime עכשיו = ZonedDateTime.now (); 

ייצוג זמן ספציפי

// תאריך לידה יום הולדת = לוח שנה גרגוריאני חדש (1990, לוח שנה. 15 בדצמבר) .getTime (); // New LocalDate birthDay = LocalDate.of (1990, חודש. 15 בדצמבר); 

חילוץ שדות ספציפיים

// חודש אינטל ישן = לוח שנה גרגוריאני חדש (). קבל (Calendar.MONTH); // חודש חודש חדש = LocalDateTime.now (). GetMonth (); 

זמן חיבור וחיסור

// לוח שנה גרגוריאני-קלנדרי ישן = לוח שנה גרגוריאני-לוח שנה חדש (); calendar.add (Calendar.HOUR_OF_DAY, -5); תאריך fiveHoursBefore = calendar.getTime (); // LocalDateTime חדש FiveHoursBefore = LocalDateTime.now (). מינוס שעות (5); 

שינוי שדות ספציפיים

// לוח שנה גרגוריאני-קלנדרי ישן = לוח שנה גרגוריאני-לוח שנה חדש (); calendar.set (Calendar.MONTH, Calendar.JUNE); תאריך inJune = calendar.getTime (); // LocalDateTime חדש inJune = LocalDateTime.now (). WithMonth (Month.JUNE.getValue ()); 

קוצץ

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

// לוח שנה ישן עכשיו = Calendar.getInstance (); now.set (Calendar.MINUTE, 0); now.set (לוח שנה. שני, 0); now.set (Calendar.MILLISECOND, 0); תאריך קטוע = now.getTime (); // חדש LocalTime קטום = LocalTime.now (). TruncatedTo (ChronoUnit.HOURS); 

המרת אזור זמן

// לוח שנה גרגוריאני-קלנדרי ישן = לוח שנה גרגוריאני-לוח שנה חדש (); calendar.setTimeZone (TimeZone.getTimeZone ("CET")); תאריך centralEastern = calendar.getTime (); // חדש ZonedDateTime centralEastern = LocalDateTime.now (). AtZone (ZoneId.of ("CET")); 

קבלת טווח זמן בין שתי נקודות זמן

// לוח שנה גרגוריאני-לוח שנה ישן = לוח שנה גרגוריאני-לוח שנה חדש (); תאריך עכשיו = תאריך חדש (); calendar.add (Calendar.HOUR, 1); תאריך hourLater = calendar.getTime (); עבר זמן רב = hourLater.getTime () - now.getTime (); // LocalDateTime חדש עכשיו = LocalDateTime.now (); LocalDateTime hourLater = LocalDateTime.now (). PlusHours (1); טווח משך = Duration.between (now, hourLater); 

עיצוב זמן וניתוח

DateTimeFormatter הוא תחליף ל- SimpleDateFormat הישן שהוא בטיחות חוט ומספק פונקציונליות נוספת.

// ישן SimpleDateFormat dateFormat = חדש SimpleDateFormat ("yyyy-MM-dd"); תאריך עכשיו = תאריך חדש (); מחרוזת formattedDate = dateFormat.format (עכשיו); תאריך parsedDate = dateFormat.parse (formattedDate); // LocalDate חדש עכשיו = LocalDate.now (); מעצב DateTimeFormatter = DateTimeFormatter.ofPattern ("yyyy-MM-dd"); מחרוזת formattedDate = now.format (מעצב); LocalDate parsedDate = LocalDate.parse (formattedDate, formatter); 

מספר הימים בחודש

// לוח שנה לוח שנה ישן = לוח שנה גרגוריאני חדש (1990, לוח שנה. פברואר, 20); int daysInMonth = calendar.getActualMaximum (לוח שנה. DAY_OF_MONTH); // int int daysInMonth = YearMonth.of (1990, 2) .lengthOfMonth ();

3. אינטראקציה עם קוד מורשת

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

בג'אווה 8 הורחבו שיעורי ספריית התאריכים הישנים בשיטות להמיר אותם לאובייקטים תואמים מממשק ה- API החדש של Date.

שיעורים חדשים מספקים פונקציות דומות.

InstantFromCalendar מיידי = GregorianCalendar.getInstance (). ToInstant (); ZonedDateTime zonedDateTimeFromCalendar = לוח שנה גרגוריאני חדש (). ToZonedDateTime (); תאריך dateFromInstant = Date.from (Instant.now ()); GregorianCalendar calendarFromZonedDateTime = GregorianCalendar.from (ZonedDateTime.now ()); InstantFromDate מיידי = תאריך חדש (). ToInstant (); ZoneId zoneIdFromTimeZone = TimeZone.getTimeZone ("PST"). ToZoneId (); 

4. מסקנה

במאמר זה חקרנו את ה- Date Time API החדש הזמין בג'אווה 8. בדקנו את היתרונות שלו בהשוואה ל- API שהוצא משימוש והצבענו על הבדלים בעזרת מספר דוגמאות.

שים לב שבקושי גירדנו את היכולות של ה- Date Time API החדש. הקפד לקרוא את התיעוד הרשמי כדי לגלות מגוון רחב של כלים המוצעים על ידי ה- API החדש.

ניתן למצוא דוגמאות לקודים בפרויקט GitHub.