Menu

Date ב-JavaScript: new Date, עיצוב תאריכים והשוואה

איך האובייקט Date של JavaScript עובד באמת: יצירת תאריכים, עיצוב, חישובים, אזורי זמן והמוזרויות שמכשילות מפתחים.

בדף הזה יש עורכים שאפשר להריץ - לערוך, להריץ ולראות את הפלט מיד.

האובייקט Date הוא רגע בזמן

Date ב-JavaScript מייצג רגע יחיד: מבפנים זה פשוט מספר מילישניות מאז 1 בינואר 1970 UTC (ה"Unix epoch"). כל השאר, שנים, חודשים, ימים, אזורי זמן ועיצוב, הוא תצוגה שנבנית מעל המספר הזה.

now.getTime() הוא מספר המילישניות הגולמי. כל מה ש-Date עושה, השוואה, הוספת ימים, עיצוב, מסתכם בשינוי המספר הזה ובפירוש מחדש שלו.

שמרו את המודל הזה בראש. Date הוא לא "14 במרץ בפריז". זה רגע אוניברסלי ש_אפשר להציג_ כ-14 במרץ בפריז, או כ-13 במרץ בלוס אנג'לס, תלוי באזור הזמן שדרכו מסתכלים עליו.

יצירת תאריכים

יש ארבע דרכים עיקריות ליצור Date:

שני דברים שכדאי לשים לב אליהם:

  • ה-constructor שמקבל חלקים משתמש בחודשים שמתחילים מאפס. 2 הוא מרץ. ינואר הוא 0. זה מקור קבוע לבאגים של "טעות באחד". בכל שאר ה-API החודשים מתחילים מ-0 גם כן, אז לפחות זה עקבי עם עצמו.
  • new Date("2026-03-14") (בלי שעה) מפוענח כחצות UTC. new Date("2026-03-14T09:30") (בלי Z) מפוענח כזמן מקומי. חוסר הסימטריה הזה הוא מלכודת קלאסית.

כדי לקבל את "עכשיו" כמספר, העדיפו את Date.now(): הוא חוסך את יצירת האובייקט:

Date.now() הוא הכלי הנכון למדידת זמן שעבר, ל-timeouts ולכל מקרה שבו לא צריך חישובי לוח שנה.

קריאת החלקים של תאריך

כשיש לכם Date, שולפים ממנו רכיבים בעזרת getters. לכל אחד יש שתי גרסאות: זמן מקומי ו-UTC.

הגרסאות המקומיות תלויות במחשב שמריץ את הקוד. אם אתם שומרים או משווים תאריכים בין משתמשים ושרתים, בחרו UTC במפורש, אחרת תרדפו אחרי באגי רפאים. כלל אצבע: השתמשו ב-getters של UTC לכל מה שנכנס למסד נתונים או ללוג, וב-getters המקומיים לכל מה שעומד להיות מוצג לבן אדם.

אל תשתמשו ב-getYear(). זו מתודה ישנה שמחזירה year - 1900 וקיימת רק לצורכי תאימות. תמיד השתמשו ב-getFullYear().

עיצוב לבני אדם

הימנעו מ-date.toString() בכל דבר שחשוב לכם: הפלט שלו תלוי בהגדרות האזוריות ובמנוע. יש שני מעצבים שכדאי להכיר.

למחרוזת תקנית שמיועדת למכונה, השתמשו ב-toISOString():

זה הפורמט לשימוש בלוגים, בשמירה ב-JSON או בשליחה ברשת. הוא תמיד ב-UTC ותמיד חד משמעי.

למחרוזת שמוצגת לבני אדם, השתמשו ב-Intl.DateTimeFormat או במתודות toLocale*, שעוטפות אותו:

Intl.DateTimeFormat מטפל בשפות, באזורי זמן ובכל צירוף של שדות שתרצו. פנו אליו לפני שאתם כותבים עיצוב ידני כמו ${year}-${month}-${day}: בניית מחרוזות כזו היא בדיוק המקום שבו מסתתרים באגים של חודש אחד הצידה.

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

שני אובייקטי Date שמייצגים את אותו רגע אינם שווים לפי ===: === בודק זהות של אובייקטים, לא ערך. השוו את חותמות הזמן במקום:

לסידור לפי סדר, אופרטורי ההשוואה עובדים ישירות כי הם ממירים למספרים:

חיסור נותן את הפער במילישניות. חלקו ב-1000 * 60 * 60 * 24 כדי לקבל ימים. כתבו את הקבוע הזה במלואו בפעם הראשונה; אחרי זמן מה תזהו את 86_400_000 במבט אחד.

חשבון תאריכים

אין מתודה addDays. הדרך המקובלת היא להשתמש ב-setDate, setMonth וכדומה: הן מקבלות ערכים מחוץ לטווח ומגלגלות אותם נכון:

שני דברים שכדאי להדגיש:

  • new Date(date) מעתיק את התאריך. setDate משנה את האובייקט במקום, אז תמיד העתיקו קודם, אחרת תשנו את הערך של מי שקרא לפונקציה.
  • setDate(35) בחודש של 31 ימים עובר אוטומטית לחודש הבא. אותו דבר עם setMonth(14): הוא מקדם את השנה. זה הופך את החישובים להרבה פחות כואבים ממה שהם נראים.

לכל דבר מורכב, ימי עסקים, אירועים חוזרים, משכי זמן שמודעים לחודשים, השתמשו בספרייה (date-fns, Luxon, או ה-API העתידי Temporal). לבנות לבד חישובי לוח שנה מעבר ל"הוספת כמה ימים" זה בור ללא תחתית.

בדיקת מציאות: אזורי זמן

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

  • Date שומר רגע ב-UTC. אזור הזמן מוחל רק כשקוראים ממנו חלקים או מעצבים אותו.
  • אזור הזמן שבו משתמשים getHours(), getDate() וכדומה הוא אזור הזמן ה_מקומי_ של המחשב שמריץ את הקוד. שרתים ודפדפנים לעיתים קרובות לא מסכימים.
  • new Date("2026-03-14") (תאריך בלבד) מפוענח כ-UTC. new Date("2026-03-14T00:00") (עם שעה, בלי אזור) מפוענח כזמן מקומי. new Date(2026, 2, 14) (חלקים) הוא מקומי.

כשצריך אזור זמן מסוים לתצוגה, העבירו timeZone ל-Intl.DateTimeFormat:

אותו רגע, שתי תצוגות. אובייקט ה-Date עצמו לא השתנה.

דוגמה קטנה שעובדת

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

חותמות זמן נכנסות, מחרוזת קריאה יוצאת. זו הצורה של 90% מקוד התאריכים בעולם האמיתי: מחסרים שני רגעים, מחלקים ביחידה, מעגלים ומעצבים.

מה לקחת מכאן

  • Date הוא רגע ב-UTC. אזורי זמן נכנסים לתמונה כשקוראים או מעצבים אותו.
  • השתמשו ב-Date.now() לחותמות זמן, וב-new Date() לעבודה עם לוח שנה.
  • השתמשו ב-toISOString() לשמירה וללוגים, וב-Intl.DateTimeFormat למשתמשים.
  • השוו עם getTime() או </>. אף פעם לא ===.
  • חודשים מתחילים מ-0. היזהרו ממלכודת הפענוח של מחרוזת תאריך בלבד.
  • לחישובי תאריכים רציניים, השתמשו בספרייה.

הבא בתור: URL ו-query strings

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

שאלות נפוצות

איך מקבלים את התאריך הנוכחי ב-JavaScript?

קראו ל-new Date() בלי ארגומנטים. מתקבל אובייקט Date שמייצג את הרגע שבו ה-constructor רץ. אם צריך רק חותמת זמן מספרית (מילישניות מאז 1970), השתמשו ב-Date.now(): זה מהיר יותר ולא יוצר אובייקט שלם.

איך משווים שני תאריכים ב-JavaScript?

השוו את חותמות הזמן שלהם, לא את אובייקטי ה-Date עצמם. a.getTime() < b.getTime() עובד, וגם a < b עובד כי < ממיר תאריכים למספרים. אבל a === b לא עובד: === בודק זהות של אובייקטים, ולכן שני אובייקטי Date שמייצגים את אותו רגע אף פעם לא שווים באופן מחמיר.

איך מעצבים תאריך ב-JavaScript?

לכל דבר שמוצג למשתמש, השתמשו ב-Intl.DateTimeFormat או ב-date.toLocaleDateString(): הם מטפלים נכון בשפות ובאזורי זמן. לפלט שמיועד למכונה, date.toISOString() מחזיר מחרוזת תקנית כמו 2026-03-14T09:30:00.000Z. הימנעו מ-date.toString() לשמירה, כי הפורמט תלוי בהגדרות האזוריות.

למה התאריך שלי ב-JavaScript יוצא יום אחד לפני?

בדרך כלל זו בעיה של אזור זמן. new Date('2026-03-14') מפוענח כחצות UTC, אבל date.getDate() מחזיר את היום לפי אזור הזמן ה_מקומי_, שעשוי להיות היום הקודם. השתמשו ב-getUTCDate() כדי לקבל את היום לפי UTC, או צרו תאריכים עם new Date(year, month, day), שעובד בזמן מקומי מההתחלה.

איור של שפות התכנות ב-Coddy

ללמוד תכנות עם Coddy

להתחיל