זמן יוניקס

זמן יוניקס חצה את 1,000,000,000 השניות ביום ראשון, ה-9 בספטמבר 2001 בשעה 01:46:40 לפי הזמן האוניברסלי המתואם.
זמן יוניקס (באנגלית: Unix time) היא שיטה לתיאור נקודה בזמן המוגדרת על ידי מספר השניות שחלפו מאז יום חמישי, 1 בינואר 1970, בשעה 00:00:00 לפי הזמן האוניברסלי המתואם (UTC), מבלי לספור דקות מעוברות. שיטה זו נפוצה בעיקר בקרב מערכות הפעלה -דמויות יוניקס, מערכות הפעלה אחרות, וקבצים. כיוון ששיטה זו לא כוללת דקות מעוברות, זו אינה תצוגה ליניארית של הזמן או ייצוג אמיתי של הזמן האוניברסלי המתואם. ניתן לבדוק את זמן יוניקס במערכות Unix על ידי הקלדת <code><syntaxhighlight lang="text" inline>date +%s</syntaxhighlight></code><code></code> בשורת הפקודה.

{| class="wikitable selfreference" style="text-align: center; margin: auto auto 10px;"
| לדוגמה: (ISO 8601:Z)
זמן יוניקס ברגע בו דף זה הוכן להצגה לאחרונה. (רענון)
|}

== הגדרה ==
=== קידוד זמן כמספר ===
זמן יוניקס מיוצג על ידי מספר שלם שגדל ב-1 בכל שנייה שחולפת ללא חישובים לצורך קביעת שנים, חודשים, ימים, שעות ודקות כפי שעושים בני האדם. הזמן במערכות Unix מודרניות מבוסס על UTC, שסופר שניות לפי מערכת היחידות הבינלאומית ופורש את הזמן לימים כמעט תמיד באורך 86400 שניות. בחודשים מסוימים, בהם יש דקה מעוברת, אורך היממה הוא 86401 שניות. שנייה נוספת זו שומרת על הסנכרון בין סיבוב כדור הארץ לזמן האוניברסלי המתואם.

=== ראשית זמן יוניקס ===
ראשית זמן יוניקס נקבע לשעה 00:00:00 ביום ה-1 בינואר 1970 (לפי הזמן האוניברסלי המתואם - כלומר שעון אנגליה). ישנה בעייתיות בהגדרה זו שכן הזמן האוניברסלי המתואם לא היה קיים במתכונתו הנוכחית עד שנת 1972 - הדיון בבעיה זו מפורט בהמשך. לפי תקן ISO 8601 שעוסק בתבניות של תאריכים, ראשית זמן יוניקס הוא 1970-01-01T00:00:00Z.

זמן יוניקס בראשית הוגדר כאפס, ומאז גדל ב-86400 שניות בדיוק בכל יום מאז הראשית. כך למשל, בתאריך 16/09/2004, 12677 ימים מאז הראשית, ייוצג הזמן בשעה 00:00:00 על ידי <math>12677 \times 86400 = 1095292800</math>. באותו האופן ניתן גם לחשב זמנים מלפני הראשית: בתאריך 04/10/1957 בשעה 00:00:00, בדיוק 4472 ימים לפני הראשית, מיוצגת נקודת הזמן על ידי המספר השלילי <math>-4472 \times 86400 = -386380800</math>.

בתוך כל יום, זמן יוניקס מחושב כסכום של זמן יוניקס בחצות (UTC 00:00:00Z) ומספר השניות שחלפו מאז חצות. כך לדוגמה, בזמן 2004-09-16T17:55:43.54Z, שהוא 64543.54 שניות אחרי חצות יום 16/09/2004, זמן יוניקס יהיה <math>1095292800 + 64543.54 = 1095357343.54</math>. גם בתאריכים שלפני הראשית זמן יוניקס גדל במהלך כל יום ובכך הופך למספר שלילי קטן יותר ככל שמתקדמים קדימה בזמן.

== טיפול בדקה מעוברת ==
ביום רגיל נוספות לייצוג זמן יוניקס 86400 שניות באופן רציף. כך לדוגמה יראה זמן יוניקס בסוף היום המתואר בדוגמאות לעיל:
{| class="wikitable" style="text-align: center; margin-bottom: 10px;"
|+ זמן יוניקס בחצות יום 17 בספטמבר 2004

! הזמן האטומי הבינלאומי (TAI)
בין 16 ל-17 בספטמבר 2004
!הזמן האוניברסלי המתואם (UTC)
בין 16 ל-17 בספטמבר 2004
!זמן יוניקס
|-
|2004-09-17T00:00:30.75
| 2004-09-16T23:59:58.75
| style="text-align:right;" |1 095 379 198.75
|-
| 2004-09-17T00:00:31.00
| 2004-09-16T23:59:59.00
| style="text-align:right;" |1 095 379 199.00
|-
| 2004-09-17T00:00:31.25
| 2004-09-16T23:59:59.25
| style="text-align:right;" |1 095 379 199.25
|-
| 2004-09-17T00:00:31.50
| 2004-09-16T23:59:59.50
| style="text-align:right;" |1 095 379 199.50
|-
! 2004-09-17T00:00:31.75
! 2004-09-16T23:59:59.75
! style="text-align:right;" |1 095 379 199.75
|-
! 2004-09-17T00:00:32.00
! 2004-09-17T00:00:00.00
! style="text-align:right;" |1 095 379 200.00
|-
| 2004-09-17T00:00:32.25
| 2004-09-17T00:00:00.25
| style="text-align:right;" |1 095 379 200.25
|-
| 2004-09-17T00:00:32.50
| 2004-09-17T00:00:00.50
| style="text-align:right;" |1 095 379 200.50
|-
| 2004-09-17T00:00:32.75
| 2004-09-17T00:00:00.75
| style="text-align:right;" |1 095 379 200.75
|-
| 2004-09-17T00:00:33.00
| 2004-09-17T00:00:01.00
| style="text-align:right;" |1 095 379 201.00
|-
| 2004-09-17T00:00:33.25
| 2004-09-17T00:00:01.25
| style="text-align:right;" |1 095 379 201.25
|}
ביום בו מתרחשת דקה מעוברת, כך שבאותו היום אין בדיוק 86400 שניות, תיווצר נקודת אי רציפות בזמן יוניקס. בהגדרתו, גדל זמן יוניקס בכל יום ב-86400 שניות בדיוק ללא קשר לאורך היממה בפועל. לכן, ביום כזה, שמגיע בממוצע בכל שנה וחצי, זמן יוניקס ממשיך לגדול גם במהלך השנייה שנוספה (כך שלמעשה באותו יום נספרו 86401 שניות), ואז חוזר אחורה שנייה אחת בדיוק ברגע המעבר בין הימים. בכך מוחזר מספר השניות באותו היום להיות 86400 ויש התעלמות מהדקה המעוברת.

לדוגמה, כך נראה זמן יוניקס במעבר בין 31 בדצמבר 1998 ל-1 בינואר 1999, יום בו חלה דקה מעוברת:
{| class="wikitable" style="text-align: center; margin-bottom: 10px;"
|+זמן יוניקס ביום 1 בינואר 1999 בו נוספה דקה מעוברת
!הזמן האטומי הבינלאומי (TAI)
ב-1 בינואר 1999
!הזמן האוניברסלי המתואם (UTC)
בין 31 בדצמבר 1998 ל-1 בינואר 1999 
!זמן יוניקס
|-
|1999-01-01T00:00:29.75
| 1998-12-31T23:59:58.75
| style="text-align:right;" |915 148 798.75
|-
| 1999-01-01T00:00:30.00
| 1998-12-31T23:59:59.00
| style="text-align:right;" |915 148 799.00
|-
| 1999-01-01T00:00:30.25
| 1998-12-31T23:59:59.25
| style="text-align:right;" |915 148 799.25
|-
| 1999-01-01T00:00:30.50
| 1998-12-31T23:59:59.50
| style="text-align:right;" |915 148 799.50
|-
! 1999-01-01T00:00:30.75
! 1998-12-31T23:59:59.75
! style="text-align:right;" |915 148 799.75
|-
! 1999-01-01T00:00:31.00
! 1998-12-31T23:59:60.00
! style="text-align:right;" |915 148 800.00
|-
| 1999-01-01T00:00:31.25
| 1998-12-31T23:59:60.25
| style="text-align:right;" |915 148 800.25
|-
| 1999-01-01T00:00:31.50
| 1998-12-31T23:59:60.50
| style="text-align:right;" |915 148 800.50
|-
! 1999-01-01T00:00:31.75
! 1998-12-31T23:59:60.75
! style="text-align:right;" |915 148 800.75
|-
! 1999-01-01T00:00:32.00
! 1999-01-01T00:00:00.00
! style="text-align:right;" |915 148 800.00
|-
| 1999-01-01T00:00:32.25
| 1999-01-01T00:00:00.25
| style="text-align:right;" |915 148 800.25
|-
| 1999-01-01T00:00:32.50
| 1999-01-01T00:00:00.50
| style="text-align:right;" |915 148 800.50
|-
| 1999-01-01T00:00:32.75
| 1999-01-01T00:00:00.75
| style="text-align:right;" |915 148 800.75
|-
| 1999-01-01T00:00:33.00
| 1999-01-01T00:00:01.00
| style="text-align:right;" |915 148 801.00
|-
| 1999-01-01T00:00:33.25
| 1999-01-01T00:00:01.25
| style="text-align:right;" |915 148 801.25
|}
ניתן לשים לב שביום בו מתרחשת דקה מעוברת, ערכי זמן יוניקס חוזרים על עצמם במשך שנייה. הערך 915148800.50 הוא דו-ערכי שכן יכול להתייחס לשני זמנים שונים: חצי שנייה לפני חצות או חצי שנייה לאחר חצות, לפי UTC.

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

ניתן להמיר זמן יוניקס בחזרה ל-UTC בקלות על ידי פעולת חילוק וחשבון מודולרי. חילוק המספר (ללא שארית) עם 86400 יניב את מספר הימים מאז ראשית זמן יוניקס, וחישוב המספר מודולו 86400 (חישוב השארית) יניב את מספר השניות שחלפו מאז חצות אותו היום. המרה בשיטה זו של זמן יוניקס דו-ערכי תניב תמיד את הזמן שמיד לאחר חצות. לעולם לא נקבל את זמן הדקה המעוברת שלפני חצות.
== ייצוג המספר ==
ניתן לייצג זמן יוניקס בכל דרך בה ניתן לייצג מספר. ביישומים מסוימים המספר מיוצג על ידי מחרוזת המורכבת מספרות עשרוניות. בישומים רבים אחרים מיוצג המספר בבסיס בינארי.

טיפוס הנתונים time_t במערכות Unix המציין נקודה בזמן, הוא מספר שלם, לרוב באורך 32 סיביות, המייצג את מספר השניות שחלפו מאז ראשית זמן יוניקס כפי שמפורט לעיל. כיוון שגודלו 32 סיביות הוא מכסה משך של 136 שנים בסך הכל. ניתן לייצג באמצעותו נקודות זמן מיום שישי, 13 בדצמבר 1901 ועד יום שלישי, 19 בינואר 2038. שנייה אחת אחרי השעה 03:14:07 ביום זה הייצוג הבינארי של המספר יגלוש (overflow) - ראה באג 2038.

בחלק ממערכות ההפעלה החדשות יותר, time_t הורחב למספר שלם באורך 64 סיביות. הרחבה זו מגדילה את מספר השנים שניתן לייצג באמצעותו לכ-293 מיליארד, לכל כיוון - קדימה או אחורה.

במקור הייתה מחלוקת בשאלה האם טיפוס הנתונים צריך להיות מספר מסומן או לא (כלומר- מספר שלם או טבעי). שימוש במספר טבעי היה אמנם דוחה את באג 2038 בעוד 68 שנים אך היה מבטל את האפשרות לייצג נקודות זמן לפני ראשית זמן יוניקס - שנת 1970. מסיבות אלו הוחלט לייצג את זמן יוניקס באמצעות מספר שלם (מסומן).

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

=== ייצוג מבוסס הזמן האוניברסלי המתואם (UTC) ===
הזמן האוניברסלי המתואם הנוכחי, המכיל דקות מעוברות, תקף רק לאחר 1 בינואר 1972. עד שהוגדר באופן זה, מאז 1 בינואר 1961, הייתה בשימוש צורה קודמת של UTC שבה לא רק שהופיעו דקות מעוברות בנקודות אקראיות, אלא גם השנייה לפי הזמן האוניברסלי המתואם הייתה מעט יותר ארוכה מהשנייה לפי מערכת היחידות הבינלאומית. במהלך שנים אלו אורך השנייה שונה לסירוגין כדי להתאים לקצב סיבוב כדור הארץ. לפני 1961 לא היה זמן אוניברסלי מתואם כלל, ועד 1958 מעקב אחרי זמן בשעונים אטומים לא היה נפוץ כלל.

ההגדרה המדויקת של זמן יוניקס כקידוד של UTC אינה שנויה במחלוקת רק בשימוש בצורה החדשה של UTC. עצם העובדה שראשית זמן יוניקס התרחשה לפני תחילת השימוש ב-UTC לא השפיעה על השימוש בזמן יוניקס: הזמן בין 1 בינואר 1970 (ראשית זמן יוניקס) לבין 1 בינואר 1972 (תחילת השימוש ב-UTC) לא נתון במחלוקת ומספר הימים שחלפו הוא הדבר היחיד שחשוב לצורך חישוב זמן יוניקס.

משמעות ערכי זמן יוניקס שקטנים מ-63072000 (כלומר: לפני 1 בינואר 1972) לא מוגדרת היטב. נקודות זמן אלו מייצגות רק קירוב לא מוחלט של זמן גריניץ'. עובדה זו שולית כיוון שבמרבית המחשבים באותה תקופה כלל לא היה שעון שידע לספק חותם זמן משמעותי ביחידות קטנות משנייה. מכאן שזמן יוניקס היא אינה שיטה מיטבית לייצוג נקודות זמן טרם 1972 הדורש דיוק של חלקיקי שנייה.

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

== שורת הפקודה ==
במערכת הפעלה דמוית יוניקס, הפקודה date תציג את הזמן הנוכחי.

== היסטוריה ==
הגרסאות הראשונות של זמן יוניקס היו מספר באורך 32 סיביות שגדל בקצב של 60 הרץ, שהיה הקצב של שעון המערכת שבחומרה של מחשבי היוניקס הראשונים. גם מועד ראשית זמן יוניקס היה שונה מהיום. במהדורה הראשונה של "המדריך למתכנת ב-Unix" מתאריך ה-3 בנובמבר 1971 הוגדר זמן יוניקס כ"זמן מאז ה-1 בינואר 1971, בשעה 00:00:00, אשר נמדד ביחידות של 1 חלקי 60 השנייה".

באותו מדריך צוין גם כי "המשתמש הכרונולוגי ישים לב שסכום של <math>2^{32}</math> של 1 חלקי 60 השנייה הוא רק כשנתיים וחצי". בגלל זמן מוגבל זה, ראשית זמן יוניקס הוגדרה מחדש מספר פעמים עד שהוחלט שזמן יוניקס יתקדם בקצב של 1 הרץ, קצב שנהוג עד היום. תדירות זו הביאה לאורך מקסימלי של כ-136 שנים, כשחציו מסמן זמן שלילי.

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

מהדורת 2001 של תקן POSIX תקנה את בעיית השנים המעוברות וזמן יוניקס אבל השאירה את זמן יוניקס להיות מוגדר כקידוד של UTC על פני ייצוג ליניארי של הזמן. בנוסף, מאז אמצע שנות ה-90, הדיוק של שעונים במחשבים גדל באופן מתמיד ורובם הוגדרו לשימוש בזמן יוניקס המבוסס על הזמן האוניברסלי המתואם.

== לוחות שנה אחרים ==
{| border="1" class="wikitable" style="margin-bottom: 10px;"
|+ראשית זמן יוניקס בלוחות שנה אחרים
!לוח שנה
!תאריך
|-
!הלוח העברי
|כ"ג בטבת תש"ל
|-
!הלוח המוסלמי
|22 בחודש שוואל 1389
|-
!הלוח היוליאני
|19 בדצמבר 1968
|-
!הלוח הפרסי
|11 בחודש דיי 1348
|-
!לוח השנה של המאיה
|12.17.16.7.5
|-
!לוח השנה הסיני
|24 בחודש יי-צ'ו 4667
|}

== נקודות ציון בזמן יוניקס ==
מעריצי יוניקס מקיימים "מסיבות time_t" כדי לציין ערכים מיוחדים של זמן יוניקס. ככל שהתגבר השימוש בזמן יוניקס כך גם מנהג חגיגת נקודות זמן מיוחדות נהיה נפוץ יותר. לרוב נחגגות נקודות זמן המיוצגות על ידי מספרים עשרוניים עגולים, אך יש החוגגים גם מספרים בינאריים עגולים, כמו המספר <math>2^{30}</math> שנחגג בשעה 13:37:04 ביום שבת ה-10 בינואר 2004.
* ביום ראשון, ה-9 בספטמבר 2001, בשעה 01:46:40 (UTC) נחגג בילניום (זמן יוניקס היה 1,000,000,000). המילה "בילניום" היא הלחם בסיסים של המילים "ביליון" (מיליארד) ומילניום. תוכנות מסוימות ששמרו חותמת זמן בייצוג של מחרוזת נתקלו בבעיות מיון, כיוון שלאחר יום זה נקודות זמן שהתחילו ב-"1" סודרו בטעות לפני נקודות זמן שהתחילו ב-"9". תקלות כאלו היו לרוב קוסמטיות ותוקנו במהרה ברגע שהתקלה הפכה גלויה. 
* ב-13 בפברואר 2009, בשעה 23:31:30 (UTC) הייצוג העשרוני של זמן יוניקס היה 1,234,567,890 שניות. בחלק ממדינות העולם (מדינות מערביות לאירופה לפי קו התאריך הבינלאומי) נקודת זמן זו התרחשה ביום שישי ה-13 לפי הלוח הגרגוריאני. גוגל ציינו את יום זה באמצעות שרבוט גוגל מיוחד.
* יום רביעי, ה-26 בינואר 2011, היה היום ה-15,000 לזמן יוניקס. נקודה זו נחגגה בבלומינגטון (אינדיאנה).
* ביום שלישי, ה-13 במאי 2014, בשעה 16:53:20 (UTC) חצה זמן יוניקס את המספר 1,400,000,000. אירוע זה נחגג ברשת. 
* ביום שלישי, ה-19 בינואר 2038, בשעה 03:14:08, זמן יוניקס המאוחסן בטיפוס נתונים באורך 32 סיביות יפסיק לתפקד, כיוון שהייצוג הבינארי של זמן יוניקס יגלוש (overflow) - ראה באג 2038. עד אותו היום, יהיה צורך להחליף תוכנות שנכתבו עבור מערכות עם 32 סיביות כדי לתמוך בחותמות זמן ארוכות. אם לא יוחלפו, שנייה לאחר השעה 03:14:08, השעה בשעון תראה 20:45:52 ביום ה-13 בדצמבר 1901 (UTC).
* ביום ראשון, ה-7 בפברואר 2106, בשעה 06:28:15 זמן יוניקס יהיה FFFFFFFF לפי הבסיס ההקסדצימלי (4,294,967,295 שניות מאז הראשית). במערכות ששומרות את זמן יוניקס כמספר לא מסומן באורך 32 סיביות, זה יהיה המספר המקסימלי האפשרי. שנייה לאחר מכן יראה השעון את השעה 00:00:00 ביום ה-1 בינואר 1970, ראשית זמן יוניקס.
* ביום ראשון, ה-4 בדצמבר בשנת 292,277,026,596 בשעה 15:30:08 גרסת 64 סיביות של זמן יוניקס תפסיק לעבוד והייצוג שלה יגלוש, שכן זה המספר הגדול ביותר שניתן לייצג כמספר מסומן באורך 64 סיביות.

== ראו גם ==
* באג 2038
* time (פקודה)
* חותם זמן
* גלישה נומרית
* 2,147,483,647

== קישורים חיצוניים ==
* [http://turningpoint.selfip.org/utime.php כלי לחישוב זמן יוניקס, ולצפייה בזמן יוניקס הנוכחי] 
* [https://web.archive.org/web/20170522031114/http://www.numberphile.com/videos/unix_time.html End of Time (Unix) - Numberphile], באתר Youtube (אנגלית)
* [https://www.youtube.com/watch?v=brZEd-8bt68 Year 2038 Problem aka the Unix Millennium Bug - Next Y2K], באתר Youtube (אנגלית)
* [http://lost.co.nz/main/programming/epoch.html Using POSIX Epoch Timestamps] 
== הערות שוליים ==

קטגוריה:יוניקס
קטגוריה:ייצוג זמן