האובייקט 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), שעובד בזמן מקומי מההתחלה.