Command Palette

Search for a command to run...

ממיר חותמת זמן של יוניקס: תקופות, אזורי זמן והבאג של שנת 57123

ממיר חותמת זמן של יוניקס: תקופות, אזורי זמן והבאג של שנת 57123

T
Toolz Team
|Jul 3, 2026|14 קריאה דקות

חלק מאוסף כלים שונים

משתמש באחת מאפליקציות Laravel SaaS שלי שלח פעם אימייל כדי לומר שתאריך חידוש המנוי שלו נראה " קצת נדיב." דף החיוב אמר לו שהתוכנית שלו תתחדש ב-25 באפריל של השנה 57123.

הבאג לקח לי זמן מביך למצוא כי כל יצירה בודדת הייתה נכונה. החזית של React נשלחה Date.now()- מה שמחזיר אלפיות שניות- וה-Backend של PHP עשה זאת date('Y-m-d', $timestamp), שמצפה שניות seconds. הזנה 1740470400000 לתוך פונקציה מצפה 1740470400 ואתה נוחת בערך 55,000 שנים בעתיד אין יוצא מן הכלל, אין אזהרה, אין מבחן כושל רק לקוח ששואל בנימוס אם המנוי שלו באמת נמשך עד המוות החום של הציוויליזציה.

חותמות זמן נראות כמו הנושא המשעמם ביותר בתוכנה.They're למעשה אחד ממפעלי הבאגים האמינים ביותר שיש לנו: שניות מול אלפיות שניות, UTC לעומת מקומי, מעברי DST, הגלגול של 2038. ה ממיר חותמת זמן על Toolz.dev קיים כי נמאס לי לעשות new Date(x * 1000) בקונסולת דפדפן ארבעים פעם ביום המדריך הזה מכסה את מה שאני בודק עכשיו, לפי הסדר שאני בודק אותו.

TL;DR: חותמת זמן של Unix סופרת שניות מאז 1970-01-01T00:00:00 UTC. 10 ספרות = שניות, 13 ספרות = אלפיות שניות- ערבוב אותם מעמיד את התאריכים שלך 55,000 שנות חופש. אחסן UTC, המר רק לתצוגה, השתמש בשמות אזורי IANA כמו Asia/Dhaka במקום קיצורים. paste any timestamp into the ממיר חותמת זמן כדי לקבל ISO 8601, RFC 2822, טפסים מקומיים ו-UTC - הוא מריץ את צד הלקוח, אז חותמות זמן מחוץ JWTs ויומני ייצור לעולם לא עוזבים את הדפדפן שלך.


מהי חותמת זמן של יוניקס, בדיוק?

חותמת זמן של יוניקס (זמן עידן, זמן POSIX) היא מספר השניות שחלפו מאז 1 בינואר 1970, 00:00:00 UTC- ה-"Unix epoch." It' הוא מספר שלם בודד, אין לו אזור זמן (it's תמיד UTC בהגדרה), ולמעשה כל מערכת הפעלה, שפה ומסד נתונים מבינים זאת. המאפיין האחרון הוא הסיבה שהוא שרד חמישה עשורים: זה הפורמט החד פעמי שאף אחד לא מתווכח עליו.

למה 1970? אין סיבה עמוקה - זה היה תאריך עגול נוח ליד מתי יוניקס נבנתה במעבדות בל, ויוניקס מוקדם ספר זמן במספר שלם של 32 סיביות. הבחירה השרירותית התאבן לתקן אוניברסלי, שהוא מאוד יוניקס.

כמה נקודות התייחסות שכדאי לזהות במראה:

חותמת זמן תאריך UTC למה אתה'd תראה את זה
0 1970-01-01 00:00:00 התקופה. גם מה שאתה מקבל ממנו null/0 באגים - תאריך ב-1970 על המסך פירושו כמעט תמיד ערך לא מאותחל, לא מסע בזמן
946684800 2000-01-01 00:00:00 Y2K
1234567890 2009-02-13 23:31:30 מפתחים למעשה ערכו מסיבות עבור זה
1740470400 2025-02-25 08:00:00 חותמת זמן מודרנית רגילה בת 10 ספרות
2147483647 2038-01-19 03:14:07 המקסימום החתום של 32 סיביות - ראה Y2038 להלן

השורה הרביעית הזו היא הדוגמה האהובה עליי מסיבה עדינה: הרבה דפי הדרכה מופיעים 1740470400 as " 25 בפברואר 2025, 12:00:00." It's למעשה 08:00 UTC- מישהו המיר אותו באזור הזמן המקומי שלו פעם אחת והערך הלא נכון הודבק מאז. ודא חותמות זמן עם כלי, לא עם פוסט בבלוג. כולל זה.

שניות או אלפיות שניות - איך מספרים?

ספור את הספרות.לכל תאריך בעידן הנוכחי:

  • 10 ספרות (1740470400) - שניות. מוסכמות יוניקס, רוב ממשקי ה-API, PHP's time(), Python's time.time() (כציפה), Stripe's API.
  • 13 ספרות (1740470400000) - אלפיות שניות. JavaScript's Date.now(), Java's System.currentTimeMillis(), תאריכים של MongoDB.

זו ההבחנה המדויקת שיצרה את תאריך החידוש שלי לשנה-57123, אז I' יפרט את מצבי הכשל:

  • ms מתפרש כשניות → תאריכים ~55,000 שנים ב עתיד
  • שניות מתפרשות כ-ms → תאריכים ב ינואר 1970 (הכל קורס עד ~3 שבועות מהתקופה)

אם אתה רואה חתימה - תאריכים עתיקים או תאריכים אבסורדיים לעתיד הרחוק - אתה מכיר את הבאג לפני קריאת שורת קוד. ה ממיר חותמת זמן מזהה ספירת ספרות ומתייג את שתי הפרשנויות, מה שמסדר את " האם זה s או ms?" ארגומנט בשתי שניות.

אילו פורמטים של תאריכים אתה באמת צריך לדעת?

שלושה מכסים כמעט כל דבר שמפתח עובד נוגע בו.

ISO 8601- התקן הבינלאומי, ומה עליך לפלוט בממשקי API ויומנים:

2026-07-13T09:30:45Z          UTC ("Z" = Zulu)
2026-07-13T15:30:45+06:00     with timezone offset
2026-07-13T09:30:45.123Z      with milliseconds

תכונת הרוצח שאף אחד לא מזכיר: מחרוזות ISO 8601 מיין לקסיקוגרפית בסדר כרונולוגי. sort על קובץ יומן פשוט עובד. 02/25/2026-פורמטים בסגנון יכולים' אל תעשה את זה - וגרוע מכך, ארהב MM/DD ואירופאי DD/MM לא ניתן להבחין במשך שנים עשר ימים בכל חודש.

RFC 3339 (מפרט) - פרופיל פרוטוקול האינטרנט של ISO 8601. מעט יותר מחמיר; אם ה-API שלך פולט 2026-07-13T09:30:45Z אתה מספק את שניהם זהו הפורמט לסטנדרטיזציה על.

RFC 2822 (Sun, 13 Jul 2026 09:30:45 +0000) - דואר אלקטרוני וכותרות HTTP, הזנות RSS.אתה קורא את זה לעתים קרובות יותר ממה שאתה כותב את זה.

פורמטים של מסד נתונים הם בני דודים קרובים: MySQL DATETIME הוא 2026-07-13 09:30:45 (ISO עם רווח), PostgreSQL timestamptz מעבד 2026-07-13 09:30:45+00.

כיצד השפות שבהן אני משתמש מטפלות בחותמות זמן?

השלושה מהערימה שלי - והמוזרות בכל אחד מהם שעלתה לי באופן אישי זמן.

JavaScript (הגברת):

Math.floor(Date.now() / 1000)        // current Unix seconds — Date.now() is ms!
new Date(1740470400 * 1000)          // seconds → Date: multiply by 1000
date.toISOString()                   // "2025-02-25T08:00:00.000Z"
Date.parse('2026-07-13T09:30:45Z') / 1000   // ISO string → Unix seconds

קווירק: הכל אלפיות שניות, ו new Date(1740470400) בשקט נותן לך 21 בינואר 1970 במקום פברואר 2025 אין שגיאה אסימטריה זו היא באג חותמת הזמן הנפוץ ביותר בפיתוח אתרים.

PHP (השניות):

time();                                   // current Unix seconds
date('Y-m-d H:i:s', 1740470400);          // "2025-02-25 08:00:00" (server TZ!)
strtotime('2026-07-13 09:30:45');         // string → timestamp
(new DateTime('@1740470400'))
    ->setTimezone(new DateTimeZone('Asia/Dhaka'))
    ->format(DateTime::ATOM);             // "2025-02-25T14:00:00+06:00"

קווירק: date() פורמטים ב- server's אזור זמן ברירת מחדל, כך שאותו קוד מדפיס תאריכים שונים במחשב שלך ובייצור. כמו כן, new DateTime('@1740470400') מתעלם מכל אזור זמן שאתה מעביר לבנאי - ה @ הטופס הוא תמיד UTC; אתה חייב להתקשר setTimezone() לאחר. וורדפרס מוסיפה שכבה משלה: current_time('timestamp') מחזירה "local&quot מזויף; היסט חותמת זמן מזמן יוניקס אמיתי, שהוא מסוכן בדיוק כמו שהוא נשמע.

פייתון:

import time, datetime
int(time.time())                                      # current Unix seconds
datetime.datetime.fromtimestamp(1740470400,
    tz=datetime.timezone.utc)                         # → aware datetime
dt.isoformat()                                        # "2025-02-25T08:00:00+00:00"

קווירק: fromtimestamp() ללא tz= מחזירה תאריך-זמן נאיבי בזמן מקומי. Naive datetimes הם באג הזמן של Python: הם משווים ומחסירים בשמחה אחד נגד השני עד ליום שבו אחד מהם חצה גבול DST. תמיד לעבור tz=; להשתמש zoneinfo (stdlib מאז 3.9) עבור אזורים בעלי שם.

כיצד עליך לטפל באזורי זמן מבלי לאבד את דעתך?

ארבעה כללים, כולם למדו בדרך המעצבנת:

  1. אחסן UTC. תמיד. חותמות זמן של יוניקס או timestamptz במסד הנתונים.Timezone הופך לקונצרן תצוגה בלבד.
  2. המר בשכבת המצגת. המשתמש בדאקה רואה +06:00, המשתמש בברלין רואה +02:00, מסד הנתונים לא רואה אף אחד מהם.
  3. השתמש בשמות IANA, לא בקיצורים. Asia/Dhaka, America/New_York, Europe/Berlin. הקיצורים אינם חד משמעיים - CST פירושו שעון סטנדרטי במרכז ארהב, סין או שעון סטנדרטי קובה תלוי במי 's קריאה - וקיצורים don't לקודד כללי DST. שמות IANA כן.
  4. לעולם אל תגלגל ידנית לוגיקה DST. תאריכי DST שונים לפי מדינה, משתנים לפי חקיקה, ובמקומות מסוימים (אריזונה, בנגלדש, יפן) don' לא לצפות ב-DST בכלל. מסד הנתונים של IANA tz קיים כי זה באמת קשה; השתמש בספרייה שעוטפת אותו.

התוצאה של כלל 1: כאשר שתי מערכות לא מסכימות לגבי זמן אירוע, המר את שני הערכים לחותמות זמן של UTC Unix והשווה את המספרים השלמים. טיעונים לגבי " אבל זה אומר 3 PM כאן" להתמוסס באופן מיידי.

מהי בעיית Y2038, והאם צריך להיות אכפת לך?

מספר שלם חתום של 32 סיביות מגיע למקסימום ב 2,147,483,647. כחותמת זמן של Unix, that's 19 בינואר 2038, 03:14:07 UTC. שנייה לאחר מכן, הערך עוטף שלילי - עד 13 בדצמבר 1901.

נשמע רחוק; זה 't, משתי סיבות. ראשית, it's בערך 11.5 שנים בחוץ כשאני כותב את זה - הרבה בתוך תוחלת החיים של מערכות משובצות, בקרים תעשייתיים, והשירות האחד מדור קודם שאף אחד לא רוצה לגעת בו. שנית, עתיד תאריכים פגעו בקיר מוקדם: מערכת שמחשבת לוח משכנתא ל-15 שנה או פקיעת תוקף של תעודה ל-20 שנה חוצה את 2038 היום. MySQL's TIMESTAMP סוג העמודה הוא המלכודת הקלאסית - it's 32-bit-bounded ו-can't חנות תאריכים אחרי 2038-01-19, בעוד DATETIME באותו מאגר מידע זה בסדר.

You'בטוח ב-64 סיביות time_t (כל מערכת הפעלה מודרנית), JavaScript (float64 ms), Python (דיוק שרירותי) ו-PostgreSQL. You' נמצאים בסיכון במערכות משובצות של 32 סיביות, ישנות TIMESTAMP עמודות, וקוד C שקודד int32_t לזמן המבחן פשוט: push 2147483648 (אחד מעבר לגבול) דרך הצינור שלך ולראות מה יוצא. The ממיר חותמת זמן יפיק לך בשמחה ערכי בדיקה לאחר 2038.

היכן מופיעות חותמות זמן באיתור באגים אמיתי?

פקיעת JWT. אסימונים נושאים iat ו exp טוען כשניות יוניקס:

{ "sub": "user_8241", "iat": 1783915890, "exp": 1783919490 }

"מדוע משתמש זה מנותק?" נענה על ידי המרה exp. פענח את האסימון ב- מפענח JWT ולהמיר את התביעה - שניהם פועלים בצד הלקוח, מה שחשוב כי אסימון מודבק הוא אישור חי (ה מדריך פרטיות נתונים מכסה מדוע אני מסרב לשים אסימונים בכלים בצד השרת).

מתאם יומן. תקרית אחת, שלושה שירותים, שלושה פורמטים: יומני nginx [13/Jul/2026:09:30:45 +0000], האפליקציה מתעדת ISO 8601, עובד בתור רושם שניות עידן גולמיות המרת הכל לפורמט אחד היא שלב אפס של בניית ציר זמן.

שילוב API. פס שולח "created": 1740470400 (שניות). API בנוי JavaScript שולח 1740470400000 (ms). ממשקי API של Google שולחים מחרוזות RFC 3339. אם אתה צורך את שלושתם, ההמרה היא ' מדי פעם - זה 's קבוע. עצב את המטענים ב- פורמט JSON ולהמיר את השדות המעניינים.

שאילתות לטווח תאריכים. WHERE created_at >= 1752364800 AND created_at < 1752451200- האם זה היום הנכון? המר את שני הגבולות ובדוק, בutc, לפני הפעלת המחיקה. קשור: ה מחשבון הבדלי תאריך עבור &quot;כמה ימים בין שני אלה?&quot;, ה ממיר אזור זמן למתמטיקה של זמן מפגש, וה מנתח Cron עבור &quot;מתי לוח הזמנים הזה אכן יורה?&quot;.

שאלות נפוצות

מהי חותמת זמן של UNIX?

מספר השניות שחלפו מאז 1 בינואר 1970, 00:00:00 UTC (עידן יוניקס), מאוחסן כמספר שלם יחיד. It&#39;s אזור זמן בלתי תלוי בהגדרה - אותו רגע הוא אותו מספר בכל מקום על פני כדור הארץ - וזו הסיבה שהוא &#39; הוא פורמט ההחלפה הסטנדרטי על פני מערכות הפעלה, שפות ומסדי נתונים.

מדוע לחלק מחותמות הזמן יש 10 ספרות ואחרות 13?

10 ספרות הן שניות (מוסכמה סטנדרטית של Unix, PHP, רוב ממשקי ה-API); 13 ספרות הן אלפיות שניות (JavaScript&#39;s Date.now(), Java). חלקו ב-1,000 כדי לעבור מ-ms לשניות. מבלבל בין שני המשמרות מתוארך ~55,000 שנים לעתיד או חזרה לינואר 1970.

האם חותמות זמן של יוניקס יכולות לייצג תאריכים לפני 1970?

כן - ערכים שליליים נחשבים לאחור מהתקופה. -86400 הוא 31 בדצמבר 1969. חותמת זמן חתומה של 32 סיביות מגיעה עד 13 בדצמבר 1901. עם זאת, מערכות וממשקי API מסוימים דוחים חותמות זמן שליליות, אז בדוק לפני שאתה מסתמך עליהן.

מהי בעיית Y2038?

חותמות זמן חתומות של 32 סיביות עולות על גדותיהן ב-2,147,483,647 - 19 בינואר 2038, 03:14:07 UTC - עטיפה לדצמבר 1901. מערכות 64 סיביות מודרניות אינן מושפעות, אך התקנים משובצים של 32 סיביות, קוד C מדור קודם ו-MySQL TIMESTAMP עמודות נחשפות.תאריכי מחשוב מערכות לעתיד רחוק (משכנתאות, תעודות) פגעו בבאג שנים לפני ש-2038 מגיעה.

למה התאריך שלי מראה ינואר 1970?

חותמת זמן אפס או כמעט אפס הגיעה לקוד העיצוב שלך - בדרך כלל ערך לא מאותחל, ניתוח כושל שהחזיר 0, או שניות חלפו במקום שבו צפויות אלפיות שניות. תאריך 1970 על המסך הוא כמעט אף פעם לא נקודת נתונים; it&#39; הוא אפס לובש תחפושת.

האם עלי לאחסן חותמות זמן או מחרוזות של datetime במסד הנתונים שלי?

אחסן UTC בכל מקרה - הסוג חשוב פחות ממשמעת אזור הזמן. מספרים שלמים של יוניקס הם קומפקטיים, ממיינים באופן טריוויאלי ומתחמקים לחלוטין מניתוח; timestamptz/DATETIME עמודות ניתנות לקריאה אנושית בתוצאות שאילתות ותומכות בחשבון תאריכים ב-SQL. מה שאסור לך לעשות הוא לאחסן זמנים מקומיים ללא קיזוזים - אובדן נתונים של &#39; אתה מגלה רק במעבר DST הבא.

האם העידן מושפע משניות קפיצות?

מעשית, לא. זמן יוניקס מעמיד פנים ששניות קפיצות don&#39; לא קיים - כל יום הוא בדיוק 86,400 שניות, ומערכות בדרך כלל מורחות או דורכות את השעון כאשר מתרחשת שנייה קפיצה. עבור קוד יישום זה לא עניין; זה משנה רק בהקשרי תזמון מדעיים, שבהם נעשה שימוש בזמן TAI או GPS במקום זאת.

האם זה בטוח להדביק חותמות זמן של יומן ייצור לתוך ממיר מקוון?

חותמת זמן גולמית לבדה חושפת מעט, אבל חותמות זמן בדרך כלל נעות עם הקשר - מזהי משתמש, טענות אסימון, שורות יומן. ה ממיר חותמת זמן ב-Toolz.dev ממיר לחלוטין בדפדפן שלך ללא נתונים משודרים, כך שהדבקת ערכים ישירות מיומני ייצור או JWTs עושה &#39;t לחשוף שום דבר.

כיצד אוכל להמיר חותמת זמן של Unix לתאריך קריא?

הדבק את המספר בממיר וקרא את ה-UTC ואת התוצאות המקומיות, או עשה זאת בקוד: new Date(ts * 1000).toISOString() ב-javascript, datetime.fromtimestamp(ts, tz=timezone.utc) בפייתון, date -u -d @ts על לינוקס הדבר היחיד שצריך קודם כל הוא האם הערך שלך הוא תוך שניות או אלפיות שניות - כל השאר נובע מכך.

כיצד אוכל לקבל את חותמת הזמן הנוכחית של Unix?

date +%s במעטפת, Math.floor(Date.now() / 1000) ב-javascript, int(time.time()) בפייתון, SELECT EXTRACT(EPOCH FROM NOW()) ב-postgresQL. שימו לב ש-JavaScript הוא המוזר: Date.now() מחזירה אלפיות שניות, כך שהחלוקה אינה אופציונלית.

Frequently Asked Questions

The number of seconds elapsed since January 1, 1970, 00:00:00 UTC (the Unix epoch), stored as a single integer. It's timezone-independent by definition — the same instant is the same number everywhere on Earth — which is why it's the standard interchange format across operating systems, languages, and databases.

Comments

0 comments

0/2000 characters

No comments yet. Be the first to share your thoughts!