זמן יוניקס

קידוד זמן כמספר

זמן יוניקס מיוצג על ידי מספר שלם שגדל ב-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 על ידי . באותו האופן ניתן גם לחשב זמנים מלפני הראשית: בתאריך 04/10/1957 בשעה 00:00:00, בדיוק 4472 ימים לפני הראשית, מיוצגת נקודת הזמן על ידי המספר השלילי .
בתוך כל יום, זמן יוניקס מחושב כסכום של זמן יוניקס בחצות (UTC 00:00:00Z) ומספר השניות שחלפו מאז חצות. כך לדוגמה, בזמן 2004-09-16T17:55:43.54Z, שהוא 64543.54 שניות אחרי חצות יום 16/09/2004, זמן יוניקס יהיה . גם בתאריכים שלפני הראשית זמן יוניקס גדל במהלך כל יום ובכך הופך למספר שלילי קטן יותר ככל שמתקדמים קדימה בזמן.

ייצוג המספר

ניתן לייצג זמן יוניקס בכל דרך בה ניתן לייצג מספר. ביישומים מסוימים המספר מיוצג על ידי מחרוזת המורכבת מספרות עשרוניות. בישומים רבים אחרים מיוצג המספר בבסיס בינארי.
טיפוס הנתונים 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 השנייה".
באותו מדריך צוין גם כי "המשתמש הכרונולוגי ישים לב שסכום של  של 1 חלקי 60 השנייה הוא רק כשנתיים וחצי". בגלל זמן מוגבל זה, ראשית זמן יוניקס הוגדרה מחדש מספר פעמים עד שהוחלט שזמן יוניקס יתקדם בקצב של 1 הרץ, קצב שנהוג עד היום. תדירות זו הביאה לאורך מקסימלי של כ-136 שנים, כשיותר מחציו מייצג זמן בעבר.
כשאוסף התקנים POSIX נכתב, עלתה השאלה איך להגדיר במדויק את time_t מבחינת דקות מעוברות. הוועדה שקלה האם זמן יוניקס צריך להישאר ייצוג ליניארי של הזמן שחלף מאז הראשית, במחיר סיבוכיות בהמרה לזמן אזרחי, או להפוך את זמן יוניקס לייצוג של הזמן האזרחי על חשבון חוסר עקיבות בטיפול בדקות מעוברות. הוועדה החליטה להעדיף את שיקול הפשטות על שיקול הייצוג הליניארי של הזמן, וקבעה שזמן יוניקס יהיה ייצוג של הזמן האוניברסלי המתואם. לרוע המזל, ההגדרה הזו של זמן יוניקס כל כך פשוטה שאפילו לא הסבירה כיצד יש לנהוג במצב של שנה מעוברת ותגרום לכך שהשנה 2100 תחשב, בטעות, כשנה מעוברת.
מהדורת 2001 של תקן POSIX תקנה את בעיית השנים המעוברות וזמן יוניקס אבל השאירה את זמן יוניקס להיות מוגדר כקידוד של UTC על פני ייצוג ליניארי של הזמן. בנוסף, מאז אמצע שנות ה-90, הדיוק של שעונים במחשבים גדל באופן מתמיד ורובם הוגדרו לשימוש בזמן יוניקס המבוסס על הזמן האוניברסלי המתואם.