היי! היום נתחיל לעבוד עם סוג נתונים חדש שעוד לא נתקלנו בו, כלומר תאריכים.
אני לא חושב שאני צריך להסביר מה זה דייט. :) באופן עקרוני, נוכל לאחסן את התאריך והשעה הנוכחיים במחרוזת Java רגילה.
זה לא אומר שאי אפשר להשתמש בשיטות האלה בכלל. אם תנסה להריץ קוד באמצעות מתודות שהוצאו משימוש ב-IDE, סביר להניח שזה יעבוד. לדוגמה, שקול את
רוב
תאריך הוא רק כמה מספרים שמציינים מרווח זמן מסוים. לוח שנה הוא מערכת שלמה שמאפשרת לך לעשות הרבה דברים עם תאריכים. :) זה בולט לעין אם אתה מנסה להציג את

public class Main {
public static void main(String[] args) {
String date = "June 11, 2018";
System.out.println(date);
}
}
אבל לגישה זו יש חסרונות רבים. הכיתה String
נועדה לעבוד עם טקסט, והשיטות שלה מתאימות למשימה זו. אם אנחנו צריכים לתמרן תאריך בדרך כלשהי (להוסיף שעתיים, למשל), String
זה לא עובד כל כך טוב. או אם נרצה להציג את התאריך והשעה הנוכחיים כאשר התוכנית מורכבת. String
גם כאן לא עוזר: עד שתכתוב את הקוד ותפעיל אותו, השעה תשתנה והקונסולה תציג את המידע השגוי. זו הסיבה שיוצרי Java סיפקו מספר שיעורים לעבודה עם תאריכים ושעה. הראשון שבהם הואjava.util.Date
שיעור תאריך
ציינו את השם המלא שלו, כי חבילת Java אחרת כוללת אתjava.sql.Date
המחלקה. אל תערבב ביניהם! הדבר הראשון שאתה צריך לדעת על זה הוא שהוא מאחסן את התאריך כמספר האלפיות השניות שחלפו מאז 1 בינואר 1970. למערכת הזמן הזו יש אפילו שם משלה: " Unix-time " גישה מעניינת למדי, לא אתה מסכים? :) הדבר השני שכדאי לזכור הוא זה: אם אתה יוצר אובייקט Date
באמצעות בנאי ברירת המחדל, התוצאה מייצגת את התאריך והשעה הנוכחיים ברגע שבו האובייקט נוצר . זוכרים שאמרנו שדייט המיוצג בתור String
יתקשה במשימה כזו? הכיתה Date
מטפלת בזה בקלות.
public class Main {
public static void main(String[] args) {
Date date = new Date();
System.out.println(date);
}
}
הפעל את הקוד הזה מספר פעמים, ותראה את הזמן משתנה שוב ושוב. :) זה אפשרי מכיוון שהזמן מאוחסן באלפיות שניות: מדובר ביחידות זמן קטנות במיוחד, כך שהתוצאות מדויקות ביותר. המחלקה Date
בנאי נוסף: אתה יכול להעביר את המספר המדויק של אלפיות השנייה מאז 00:00 ב-1 בינואר 1970 לתאריך הנדרש, ואובייקט תאריך מתאים ייווצר:
public class Main {
public static void main(String[] args) {
Date date = new Date(1212121212121L);
System.out.println(date);
}
}
פלט קונסולה: שישי 30 במאי 04:20:12 GMT 2008 נקבל את ה-30 במאי 2008. "שי" מציין את היום בשבוע (שישי, דוה), ו-GMT הוא אזור הזמן (שעון גריניץ'). אלפיות השנייה מועברות כ- long
s, מכיוון שמספר האלפיות השניות אינו מתאים בדרך כלל ל- int
. אז, אילו פעולות עם תאריכים אולי נצטרך לבצע? ובכן, הברור ביותר, כמובן, הוא השוואה . כדי לקבוע אם דייט אחד בא לפני או אחרי אחר. זה יכול להיעשות בכמה דרכים. לדוגמה, אתה יכול לקרוא לשיטה Date.getTime()
, שמחזירה את מספר האלפיות השניות שחלפו מאז חצות ב-1 בינואר 1970. פשוט קרא לה על שני אובייקטים של Date והשווה את התוצאות:
public class Main {
public static void main(String[] args) {
Date date1 = new Date();
Date date2 = new Date();
System.out.println((date1.getTime() > date2.getTime())?
"date1 is later than date2" : "date1 is earlier than date2");
}
}
פלט: date1 מוקדם מ-date2 אבל ישנה גם דרך נוחה יותר, כלומר באמצעות שיטות מיוחדות המסופקות על ידי המחלקה Date: before()
, after()
ו equals()
. כולם מחזירים ערך בוליאני. השיטה before()
בודקת אם התאריך שלנו מוקדם מהתאריך שעבר כארגומנט:
public class Main {
public static void main(String[] args) throws InterruptedException {
Date date1 = new Date();
Thread.sleep(2000);// Suspend the program for 2 seconds
Date date2 = new Date();
System.out.println(date1.before(date2));
}
}
פלט מסוף: נכון באופן דומה, after()
השיטה בודקת אם התאריך שלנו מאוחר מהתאריך שעבר כארגומנט:
public class Main {
public static void main(String[] args) throws InterruptedException {
Date date1 = new Date();
Thread.sleep(2000);// Suspend the program for 2 seconds
Date date2 = new Date();
System.out.println(date1.after(date2));
}
}
פלט מסוף: false בדוגמאות שלנו, אנו "משכיבים את התוכנית למצב שינה" למשך 2 שניות, כך ששני התאריכים מובטחים שונים. במחשבים מהירים, הזמן בין היצירה של date1
לבין date2
יכול להיות פחות מאלפית שנייה אחת, מה שגורם גם before()
וגם after()
להחזיר false. אבל במקרה זה, equals()
השיטה תחזור אמיתית! אחרי הכל, הוא משווה את מספר האלפיות השניות מאז 00:00 ב-1 בינואר 1970 עבור כל תאריך. האובייקטים נחשבים שווים רק אם הם תואמים לאלפית השנייה :
public static void main(String[] args) {
Date date1 = new Date();
Date date2 = new Date();
System.out.println(date1.getTime());
System.out.println(date2.getTime());
System.out.println(date1.equals(date2));
}
הנה עוד דבר שאתה צריך לשים לב אליו. אם תפתח את התיעוד של Date
המחלקה באתר אורקל
, תראה שרבים מהשיטות והבנאים שלה סומנו כ- Deprecated (כלומר לא מומלץ לשימוש). הנה מה שיש ליוצרים של Java לומר על חלקים של מחלקות שהוצאו משימוש:
"רכיב תוכנית עם הערות @Deprecated הוא משהו למתכנתים לא מומלץ להשתמש, בדרך כלל בגלל שהוא מסוכן, או בגלל שיש אלטרנטיבה טובה יותר." |
Date.getHours()
השיטה שהוצאה משימוש, המחזירה את מספר השעות המשויכות לאובייקט Date
.
public static void main(String[] args) {
Date date1 = new Date();
System.out.println(date1.getHours());
}
אם תתחיל את הקוד בשעה 14:21 (14:21), הוא יציג את המספר 14. כפי שאתה יכול לראות, השיטה שהוצאה משימוש מחוצה, אך היא עדיין עובדת. שיטות אלו אינן מוסרות כדי לא לשבור את הגוף העצום של הקוד הקיים שמשתמש בהן. במילים אחרות, שיטות אלו אינן "שבורות" ולא "מוסרות". הם פשוט לא מומלצים לשימוש מכיוון שקיימת חלופה נוחה יותר. אגב, התיעוד מזכיר באופן ספציפי את החלופה הזו:

Date
השיטות של המחלקה הועברו למחלקה המשופרת והמורחבת Calendar
. נכיר את השיעור הבא. :)
שיעור לוח שנה
JDK 1.1 הציג מחלקה חדשה:Calendar
. זה הפך את העבודה עם תאריכים ב-Java לקלה יותר מבעבר. היישום היחיד של הכיתה Calendar
איתו נעבוד הוא GregorianCalendar
הכיתה. הוא מיישם את הלוח הגרגוריאני, שנצפה על ידי רוב מדינות העולם. היתרון העיקרי שלו הוא שהוא יכול לעבוד עם תאריכים בפורמט נוח יותר. לדוגמה, זה יכול:
- הוסף חודש או יום לתאריך הנוכחי
- בדקו האם השנה היא שנה מעוברת;
- החזר רכיבים בודדים של התאריך (לדוגמה, חלץ את מספר החודש מתאריך שלם)
- הוא מכיל גם מערכת קבועים מאוד נוחה (שרבים מהם נראה בהמשך).
Calendar
שלה : ניתן לציין תאריך לפני העידן הנפוץ (לפני ישו) או בעידן הנפוץ (AD - Anno Domini). בואו נסתכל על כל זה עם דוגמאות. בואו ניצור אובייקט עם התאריך של 25 בינואר 2017: calendar
public static void main(String[] args) {
Calendar calendar = new GregorianCalendar(2017, 0 , 25);
}
בכיתה Calendar
(כמו גם Date
בכיתה לצורך העניין), חודשים מתחילים מאפס , אז אנחנו מעבירים את המספר 0 כארגומנט השני. כשעובדים עם Calendar
הכיתה, חשוב להבין שזה בדיוק זה, לוח שנה , לא תאריך בודד. 
Calendar
האובייקט: פלט: java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=false,lenient=true,zone=sun.util.calendar.ZoneInfo[id= "אירופה/לונדון",offset=0,dstSavings=0,useDaylight=false,transitions=79,lastRule=null],firstDayOfWeek=2,minimalDaysInFirstWeek=1,ERA=?,YEAR=2017,MONTH=0,WEEK_OF_YEAR=? ,WEEK_OF_MONTH=?,DAY_OF_MONTH=25,DAY_OF_YEAR=?,DAY_OF_WEEK=?,DAY_OF_WEEK_IN_MONTH=?,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND_OFFSET=0,MILLISECOND_OFFSET=? =?] ראה כמה מידע אתה מקבל! ללוח שנה יש חבורה של מאפיינים שאין לתאריך רגיל, וכולם מוצגים (כך toString()
עובדת השיטה בכיתה Calendar
). אם אתה רק צריך לקבל תאריך פשוט מהלוח שנה, כלומר אובייקט Date
, השתמש Calendar.getTime()
בשיטה (השם לא הכי הגיוני, אבל מה אתה יכול לעשות?):
public static void main(String[] args) {
Calendar calendar = new GregorianCalendar(2017, 0 , 25);
Date date = calendar.getTime();
System.out.println(date);
}
פלט: Wed Jan 25 00:00:00 GMT 2017 עכשיו לקחנו את לוח השנה ו"צמצמנו אותו" לתאריך רגיל. בוא נלך רחוק יותר. בנוסף לקביעת החודשים לפי מספרם, תוכל להשתמש בערכי השדות הקבועיםCalendar
של המחלקה . קבועים אלו הם שדות סטטיים של המחלקה עם ערך מוגדר מראש שלא ניתן לשנות. זוהי למעשה אפשרות טובה אפילו יותר, מכיוון שהשימוש בהם משפר את קריאות הקוד שלך. Calendar
public static void main(String[] args) {
GregorianCalendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
}
Calendar.JANUARY הוא אחד הקבועים המייצגים את חודשי השנה. באמצעות הקבועים הנקובים הללו, אף אחד לא ישכח, למשל, שהמספר 3 פירושו אפריל, ולא החודש השלישי, שאנו אוהבים לקרוא לו מרץ. פשוט כתוב Calendar.APRIL , וסיימת. :) ניתן לציין בנפרד את כל שדות היומן (מספר, חודש, דקות, שניות וכו') באמצעות השיטהset()
. שיטה זו נוחה מאוד, מכיוון שלמחלקהCalendar
יש קבוע לכל שדה, והקוד המתקבל קל מאוד לקריאה. בדוגמה האחרונה יצרנו תאריך, אך לא קבענו לו זמן. בוא נקבע את השעה 19:42:12
public static void main(String[] args) {
Calendar calendar = new GregorianCalendar();
calendar.set(Calendar.YEAR, 2017);
calendar.set(Calendar.MONTH, 0);
calendar.set(Calendar.DAY_OF_MONTH, 25);
calendar.set(Calendar.HOUR_OF_DAY, 19);
calendar.set(Calendar.MINUTE, 42);
calendar.set(Calendar.SECOND, 12);
System.out.println(calendar.getTime());
}
פלט: Wed Jan 25 19:42:12 GMT 2017 אנו קוראים לשיטה set()
, מעבירים קבוע (בהתאם לשדה שאנו רוצים לשנות) ואת הערך החדש עבור השדה. מסתבר ששיטה זו set()
היא מעין "סופר-מגדיר" שיודע להגדיר את הערך לא רק לשדה אחד, אלא להרבה שדות. :) Calendar
המחלקה משתמשת בשיטה add()
כדי להוסיף ולהחסיר ערכים. אתה מעביר בשדה שאתה רוצה לשנות, ומספר (בדיוק כמה אתה רוצה להוסיף/להחסיר מהערך הנוכחי). לדוגמה, בוא נקבל תאריך שהוא חודשיים לפני התאריך שיצרנו:
public static void main(String[] args) {
Calendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
calendar.set(Calendar.HOUR, 19);
calendar.set(Calendar.MINUTE, 42);
calendar.set(Calendar.SECOND, 12);
calendar.add(Calendar.MONTH, -2); // To subtract, pass a negative number
System.out.println(calendar.getTime());
}
פלט: ו' 25 בנובמבר 19:42:12 GMT 2016 טוב מאוד! קיבלנו את התאריך לפני חודשיים. זה לא רק גרם לשינוי החודש: גם השנה השתנתה מ-2017 ל-2016. כמובן, בהמרת תאריכים, השנה הנוכחית מחושבת אוטומטית ללא צורך במעקב ידני. אבל אם מסיבה כלשהי אתה צריך להשבית התנהגות זו, אתה יכול לעשות זאת. השיטה roll()
יכולה להוסיף ולהחסיר ערכים מבלי להשפיע על הערכים הנותרים . לדוגמה, כך:
public static void main(String[] args) {
Calendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
calendar.set(Calendar.HOUR, 10);
calendar.set(Calendar.MINUTE, 42);
calendar.set(Calendar.SECOND, 12);
calendar.roll(Calendar.MONTH, -2);
System.out.println(calendar.getTime());
}
עשינו בדיוק את אותו הדבר כמו בדוגמה הקודמת: לקחנו חודשיים מהתאריך הנוכחי. אבל עכשיו הקוד עושה משהו שונה: החודש השתנה מינואר לנובמבר, אבל השנה נשארת ללא שינוי - 2017! פלט: שבת 25 בנובמבר 10:42:12 GMT 2017 מתקדם. כפי שאמרנו לעיל, אנו יכולים לקבל את כל Calendar
השדות בנפרד. אנו עושים זאת בשיטה get()
:
public static void main(String[] args) {
GregorianCalendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
calendar.set(Calendar.HOUR, 10);
calendar.set(Calendar.MINUTE, 42);
calendar.set(Calendar.SECOND, 12);
System.out.println("Year: " + calendar.get(Calendar.YEAR));
System.out.println("Month: " + calendar.get(Calendar.MONTH));
System.out.println("Week in the month: " + calendar.get(Calendar.WEEK_OF_MONTH));// Week in this month?
System.out.println("Day: " + calendar.get(Calendar.DAY_OF_MONTH));
System.out.println("Hours: " + calendar.get(Calendar.HOUR));
System.out.println("Minutes: " + calendar.get(Calendar.MINUTE));
System.out.println("Seconds: " + calendar.get(Calendar.SECOND));
System.out.println("Milliseconds: " + calendar.get(Calendar.MILLISECOND));
}
פלט: שנה: 2017 חודש: 0 שבוע בחודש: 5 יום: 25 שעות: 10 דקות: 42 שניות: 12 אלפיות שניות: 0 אז, בנוסף ל"סופר Calendar
-מגדיר" של הכיתה, יש גם "סופר-גטר" ". :) כמובן, היבט מעניין נוסף של השיעור הזה הוא עבודה עם תקופות. כדי ליצור תאריך "לפני הספירה", תצטרך להשתמש בשדה Calendar.ERA. לדוגמה, בואו ניצור תאריך לקרב קנאי, שבו חניבעל הביס את הצבא הרומי. זה קרה ב-2 באוגוסט 216 לפני הספירה:
public static void main(String[] args) {
GregorianCalendar cannae = new GregorianCalendar(216, Calendar.AUGUST, 2);
cannae.set(Calendar.ERA, GregorianCalendar.BC);
DateFormat df = new SimpleDateFormat("MMM dd, yyy GG");
System.out.println(df.format(cannae.getTime()));
}
כאן השתמשנו SimpleDateFormat
בכיתה כדי להדפיס את התאריך בפורמט שקל לנו יותר להבין (האותיות "GG" מציינות שאנחנו רוצים שהעידן יוצג). פלט: 02 באוגוסט, 216 לפני הספירה. לכיתה Calendar
יש עוד הרבה שיטות וקבועים. ניתן לקרוא עליהם בתיעוד
. אם אינך אוהב את פורמט התאריך הזה שבת 25 נובמבר 10:42:12 GMT 2017 , תוכל להשתמש בו SimpleDateFormat
כדי להפוך אותו בקלות למה שאתה רוצה שיהיה.
public static void main(String[] args) {
SimpleDateFormat dateFormat = new SimpleDateFormat("EEEE, MMMM d, yyyy");
Calendar calendar = new GregorianCalendar(2017, Calendar.JANUARY , 25);
calendar.set(Calendar.HOUR, 10);
calendar.set(Calendar.MINUTE, 42);
calendar.set(Calendar.SECOND, 12);
calendar.roll(Calendar.MONTH, -2);
System.out.println(dateFormat.format(calendar.getTime()));
}
פלט: שבת, 25 בנובמבר, 2017 זה הרבה יותר טוב, לא? :)
GO TO FULL VERSION