FlowingDev

Epoch टाइम, समझाया गया: वो घड़ी जो सिर्फ आगे बढ़ती है

जानें कि Unix टाइम (या Epoch टाइम) क्या है: यह 1 जनवरी, 1970 से बीते हुए सेकंड्स की संख्या है, जिसका इस्तेमाल कंप्यूटर universally समय का ट्रैक रखने के लिए करते हैं।

टूल आज़माएँ: युग परिवर्तक

एक वाक्य में

Epoch टाइम कंप्यूटर का समय को ट्रैक करने का एक तरीका है, जिसमें समय को एक सिंगल, हमेशा बढ़ने वाले नंबर के रूप में देखा जाता है: यह 1 जनवरी, 1970 की आधी रात UTC से गुज़रे कुल सेकंड्स की संख्या है।

यह कौन सी समस्या हल करता है

इंसानों और समय का रिश्ता बड़ा कॉम्प्लिकेटेड है। हमारे पास timezones, daylight saving, और MM/DD/YYYY बनाम DD/MM/YYYY जैसे फ़ॉर्मैट हैं। हम लिखते हैं "8 अक्टूबर, 2024 को दोपहर 3:00 बजे," लेकिन इसका मतलब टोक्यो में कुछ और होता है और टोरंटो में कुछ और। यह सब कन्फ्यूज़न का रायता फैला देता है।

दूसरी ओर, कंप्यूटर को कन्फ्यूज़न से सख़्त नफ़रत है। उन्हें किसी भी क्षण को दर्शाने के लिए एक सिंगल, यूनिवर्सल, और गणितीय रूप से सरल तरीके की आवश्यकता होती है। "8 अक्टूबर" के साथ गणित करने की कोशिश करना एक बुरे सपने जैसा है। लेकिन एक सादे से नंबर के साथ गणित करना? कंप्यूटर तो बने ही इसी काम के लिए हैं।

यही वो समस्या है जिसे हल करने के लिए Unix टाइम (जिसे Epoch टाइम या POSIX टाइम भी कहते हैं) बनाया गया था। 1970 के दशक में Unix ऑपरेटिंग सिस्टम के शुरुआती दिनों में, इसके बनाने वालों को एक सीधे-सादे टाइमकीपिंग सिस्टम की ज़रूरत थी। उन्होंने एक मनमाना शुरुआती पॉइंट—एक "epoch"—चुना और बस... गिनना शुरू कर दिया।

चुना गया epoch था 00:00:00 UTC, 1 जनवरी, 1970। यही क्यों? यह एक अच्छा, राउंड नंबर था, और उस समय की टेक्नोलॉजी के हिसाब से काफी नया था।

उस पल के बाद से, हर गुज़रता सेकंड एक यूनिवर्सल काउंटर को बढ़ा देता है। तो, कंप्यूटर को "टोरंटो में (जो EDT है) 8 अक्टूबर, 2024 को दोपहर 3:00 बजे" को parse करने के बजाय, वह बस 1728409200 नंबर स्टोर कर सकता है। यह नंबर पृथ्वी पर हर जगह, एक साथ, उसी सटीक पल को दर्शाता है। कोई टाइमज़ोन नहीं, कोई फ़ॉर्मैट नहीं, कोई "AM है या PM?" वाला चक्कर नहीं। बस एक नंबर। प्रॉब्लम सॉल्व्ड।

यह अंदर से कैसे काम करता है

दिल से कहें तो, यह कॉन्सेप्ट बहुत ही सरल है। लेकिन जैसा कि टेक की दुनिया में होता है, असली कहानी तो डिटेल्स में छिपी है।

Epoch और यूनिट

पूरा सिस्टम दो आइडिया पर बना है:

  1. शुरुआती पॉइंट (Epoch): यह 1970-01-01T00:00:00Z पर फिक्स है। यहाँ Z का मतलब है Zulu, जो UTC (Coordinated Universal Time) के लिए एक मिलिट्री और एविएशन शब्द है। Epoch टाइम की दुनिया में, यह पल बस 0 है।
  2. माप की इकाई: स्टैंडर्ड, ऑफिशियल यूनिट है सेकंड।

तो, टाइमस्टैम्प 1 का मतलब है 1970-01-01T00:00:01Z। अगले दिन की शुरुआत, 1970-01-02T00:00:00Z, का टाइमस्टैम्प 86400 है (क्योंकि एक दिन में 60 सेकंड * 60 मिनट * 24 घंटे = 86,400 सेकंड होते हैं)।

// भविष्य में बहुत दूर की तारीख
const humanDate = new Date('2035-10-26T10:00:00Z');

// सेकंड में इसका संबंधित Epoch टाइमस्टैम्प
const epochTimestamp = 2071754400;

जब आपका कंप्यूटर आपको यह टाइमस्टैम्प लोकल टाइम के रूप में दिखाता है, तो वह पर्दे के पीछे एक कन्वर्ज़न कर रहा होता है। यह यूनिवर्सल UTC टाइमस्टैम्प लेता है और आपके सिस्टम के टाइमज़ोन ऑफ़सेट को लागू करके इसे ऐसे दिखाता है जो आपके लिए मायने रखता हो। हालाँकि, असली नंबर प्योर और यूनिवर्सल बना रहता है।

वेरिएशन्स: Milliseconds, Microseconds, Nanoseconds

कभी-कभी, आपको उन चीज़ों को मापने की ज़रूरत होती है जो एक सेकंड से भी तेज़ होती हैं। इसके लिए, सिस्टम Epoch टाइमस्टैम्प के अधिक सटीक वर्ज़न का उपयोग करते हैं। सिद्धांत वही है, लेकिन यूनिट बदल जाती है।

यूनिट उदाहरण मान (एक ही पल के लिए) आमतौर पर डिजिट्स की संख्या आम इस्तेमाल
सेकंड्स 1728409200 10 POSIX स्टैंडर्ड; APIs, डेटाबेस।
मिलीसेकंड्स 1728409200123 13 JavaScript (Date.now()), मॉडर्न APIs।
माइक्रोसेकंड्स 1728409200123456 16 हाई-परफॉरमेंस सिस्टम, कुछ डेटाबेस।
नैनोसेकंड्स 1728409200123456789 19 साइंटिफिक कंप्यूटिंग, Go लैंग्वेज।

टाइमस्टैम्प के साथ काम करते समय यह बग्स का नंबर वन सोर्स है। अगर कोई सिस्टम आपको 13-डिजिट का नंबर देता है और आप उसे सेकंड मान लेते हैं, तो आप हज़ारों साल भविष्य की तारीख कैलकुलेट करने की कोशिश कर रहे हैं। हमेशा डॉक्स (documentation) देखें या डिजिट्स की संख्या पर ध्यान दें ताकि पता चल सके कि आप किससे डील कर रहे हैं।

"ईयर 2038 प्रॉब्लम"

यहाँ कंप्यूटर की दुनिया की एक क्लासिक कहानी है। कई शुरुआती सिस्टम्स ने, कीमती मेमोरी बचाने के लिए, Epoch टाइमस्टैम्प को 32-बिट साइन्ड इंटीजर (32-bit signed integer) के रूप में स्टोर किया।

एक "बिट" 1 या 0 होता है। "32-बिट" का मतलब है कि आपके पास 1 और 0 के लिए 32 स्लॉट हैं। "साइन्ड" का मतलब है कि उन बिट्स में से एक का उपयोग यह बताने के लिए किया जाता है कि नंबर पॉजिटिव है या नेगेटिव। इससे नंबर के लिए 31 बिट बचते हैं, जिसकी अधिकतम वैल्यू 2^31 - 1, या 2,147,483,647 हो सकती है।

क्या होगा जब 1970 से सेकंड्स की संख्या इस सीमा तक पहुँच जाएगी? यह मंगलवार, 19 जनवरी, 2038 को 03:14:07 UTC पर होगा। अगले ही सेकंड, इंटीजर ओवरफ्लो हो जाएगा। जैसे किसी कार का ओडोमीटर 999999 से घूमकर 000000 पर आ जाता है, वैसे ही 32-बिट टाइमस्टैम्प घूमकर अपनी सबसे नेगेटिव वैल्यू (-2,147,483,648) पर पहुँच जाएगा। यह दिसंबर 1901 की एक तारीख से मेल खाता है।

किसी भी 32-बिट सिस्टम के लिए जिसे पैच नहीं किया गया है, यह समय का पूरा रायता फैला देगा। पुरानी कारों, औद्योगिक उपकरणों, या नेटवर्क राउटर्स में लगे एम्बेडेड सिस्टम के बारे में सोचें।

इलाज? 64-बिट इंटीजर का उपयोग करें। एक 64-बिट इंटीजर इतना बड़ा नंबर स्टोर कर सकता है कि यह लगभग 292 अरब वर्षों तक ओवरफ्लो नहीं होगा। तब तक, सूरज बहुत पहले फैलकर पृथ्वी को निगल चुका होगा, तो हम इसे शायद एक परमानेंट सॉल्यूशन कह सकते हैं। अधिकांश मॉडर्न ऑपरेटिंग सिस्टम और लैंग्वेजेज पहले ही यह बदलाव कर चुकी हैं।

लीप सेकंड्स: कबाब में हड्डी

पृथ्वी का घूमना पूरी तरह से नियमित नहीं है; यह थोड़ी धीमी हो रही है। हमारी एटॉमिक घड़ियों (जो सुपर रेगुलर हैं) को सौर दिन के साथ सिंक में रखने के लिए, अंतर्राष्ट्रीय संस्थाएं कभी-कभी कैलेंडर में एक "लीप सेकंड" जोड़ देती हैं। इसका मतलब है कि एक मिनट में 61 सेकंड हो सकते हैं (जैसे, 23:59:60)।

तो Epoch टाइम इसे कैसे हैंडल करता है? यह नहीं करता है।

आधिकारिक तौर पर, POSIX स्टैंडर्ड लीप सेकंड को अनदेखा करता है। यह मानता है कि हर दिन में ठीक 86,400 सेकंड होते हैं। जब एक लीप सेकंड होता है, तो सिस्टम इसे कुछ तरीकों से संभालते हैं, लेकिन एक आम तरीका यह है कि पिछले सेकंड को प्रभावी रूप से दोहराया जाता है। 23:59:59 का टाइमस्टैम्प दो बार आ सकता है। यह सेकंड्स की निरंतर, अटूट गिनती बनाए रखता है, लेकिन इसका मतलब है कि एक Unix टाइमस्टैम्प हमेशा वास्तविक दुनिया के UTC से पूरी तरह मेल नहीं खाता है। 99.9% एप्लीकेशन के लिए, यह कोई मुद्दा नहीं है। हाई-फ्रीक्वेंसी ट्रेडिंग या साइंटिफिक माप के लिए, यह एक बहुत बड़ा सिरदर्द है।

असल दुनिया की कहानियाँ

समय में यात्रा करने वाले Cache का मामला

एक डेव टीम कैशिंग सिस्टम पर आधारित एक नया फीचर लॉन्च कर रही थी। परफॉरमेंस सुधारने के लिए, वे डेटा को एक घंटे के लिए कैश करते थे। लॉजिक सिंपल था: expiration_time = current_time() + 3600। उन्होंने अपने सर्वर फ्लीट में कोड डिप्लॉय कर दिया।

अचानक, अजीबोगरीब बग्स की बाढ़ आ गई। डेटा कैश से लगभग तुरंत गायब हो रहा था। घंटों की माथापच्ची वाली डीबगिंग के बाद, उन्हें अपराधी मिला। फ्लीट में से एक नए सर्वर की सिस्टम क्लॉक गलत तरीके से सेट थी—यह बाकी सभी सर्वरों से पांच मिनट पीछे चल रहा था।

जब किसी यूज़र का रिक्वेस्ट एक सही सर्वर पर आता, तो वह डेटा को, मान लीजिए, 1678886400 (दोपहर 12:00 बजे) के एक्सपायरी टाइम के साथ कैश करता। यदि उसी डेटा के लिए अगला रिक्वेस्ट 'धीमे' सर्वर पर आता, तो उसकी घड़ी में 11:55 AM बज रहे होते। जब वह कैश की जाँच करता, तो उसे 12:00 बजे का एक्सपायरी टाइम दिखता और वह सही ढंग से डेटा सर्व कर देता। लेकिन अगर पहला रिक्वेस्ट धीमे सर्वर पर आता, तो वह 1678882800 (11:00 AM, उसका अपना समय, प्लस एक घंटा जो 12:00 PM है) का एक्सपायरी टाइम सेट करता। लेकिन तब तो 11:55 AM हो रहे थे। अरे, ये तो गड़बड़ है।

चलिए फिर से कोशिश करते हैं। सर्वर A का समय 12:00 है। यह 12:00 + 1 घंटा = 13:00 के लिए कैश एक्सपायरी सेट करता है। सर्वर B की घड़ी धीमी है; उसे लगता है कि 11:55 बजे हैं। जब सर्वर B को कैश में लिखना होता है, तो वह 11:55 + 1 घंटा = 12:55 की एक्सपायरी सेट करता है। अब, अगर सर्वर A को 12:55 पर एक्सपायर होने वाला आइटम दिखता है, तो उसे लगेगा कि 55 मिनट बचे हैं, जबकि सर्वर B सोचेगा कि पूरा एक घंटा बचा है। इससे असंगतताएँ होती हैं।

असली रायता तो तब फैलता है जब घड़ियाँ बहुत ज़्यादा आगे-पीछे हों। अगर सर्वर B की घड़ी एक घंटा पीछे सेट होती (जब 12:00 बज रहे हों तो उसे 11:00 लगता), तो वह 11:00 + 1 घंटा = 12:00 का एक्सपायरी टाइम सेट करता। सर्वर A के दृष्टिकोण से, यह नया कैश आइटम बनने के सेकंड भर में ही एक्सपायर हो जाता है। डेटा प्रभावी रूप से गायब हो गया।

सबक: Unix टाइमस्टैम्प एब्सोल्यूट होते हैं, लेकिन वे सिस्टम क्लॉक से जेनरेट होते हैं जो शायद न हों। डिस्ट्रिब्यूटेड सिस्टम्स में, घड़ियों को सिंक्रनाइज़ रखना (आमतौर पर नेटवर्क टाइम प्रोटोकॉल, या NTP से) सिर्फ एक अच्छी आदत नहीं है; यह बहुत ज़रूरी है।

वह API जो Milliseconds में बात करती थी

एक फ्रंटएंड डेवलपर यूज़र एक्टिविटी दिखाने के लिए एक डैशबोर्ड बना रहा था। बैकएंड API एक last_login फ़ील्ड देती थी जिसमें 1678886400 जैसा एक टाइमस्टैम्प होता था। डेवलपर ने इसे दिखाने के लिए एक JavaScript लाइब्रेरी का उपयोग किया: new Date(1678886400)।

नतीजा अजीब था। हर यूज़र का लास्ट लॉगिन "20 जनवरी, 1970" दिखाया जा रहा था। क्या हो रहा था?

डेवलपर ने एक घंटे तक लाइब्रेरी, अपने कोड और चाँद की दशा को दोष दिया। आखिर में, उसने उसी API के एक अलग एंडपॉइंट को इंटीग्रेट करने की कोशिश की। इस बार, टाइमस्टैम्प 1678886400123 था। इसमें 13 डिजिट थे! अचानक, उसकी बत्ती जली। JavaScript का Date ऑब्जेक्ट कंस्ट्रक्टर मिलीसेकंड में टाइमस्टैम्प की उम्मीद करता है, सेकंड में नहीं।

बैकएंड एक स्टैंडर्ड 10-डिजिट का सेकंड-आधारित टाइमस्टैम्प भेज रहा था। फ्रंटएंड 1,678,886,400 को epoch के बाद से मिलीसेकंड की संख्या के रूप में समझ रहा था, जो 1970 में epoch शुरू होने के कुछ ही हफ्तों बाद की तारीख है। फिक्स सरल था: new Date(1678886400 * 1000)।

सबक: हमेशा, हमेशा, हमेशा टाइमस्टैम्प की précision (सटीकता) की जाँच करें। तीन ज़ीरो का अंतर आज और 1970 के बीच का अंतर है।

आम गलतियाँ और जाल

  • टाइमज़ोन को भूल जाना। Unix टाइमस्टैम्प हमेशा, बिना किसी अपवाद के, UTC में होते हैं। जब आप इसे किसी इंसान द्वारा पढ़े जाने योग्य तारीख में बदलते हैं, तो आपकी प्रोग्रामिंग भाषा या टूल लगभग हमेशा आपके कंप्यूटर का लोकल टाइमज़ोन उपयोग करेगा। यदि आप इसका ध्यान नहीं रखते हैं तो इससे भारी भ्रम हो सकता है। 1728409200 समय का एक सटीक पल है, लेकिन यह न्यूयॉर्क में 06:00 और टोक्यो में 19:00 के रूप में दिखाई देगा। नंबर ही सच्चाई है; जो दिखता है वह सिर्फ एक व्याख्या है।

  • सेकंड और मिलीसेकंड को मिक्स कर देना। यह क्लासिक 'ऑफ़-बाय-1000' (off-by-1000) एरर है। टाइमस्टैम्प के साथ काम करते समय यह सबसे आम बग है। एक अंगूठे के नियम के रूप में: 10 डिजिट का मतलब सेकंड, 13 डिजिट का मतलब मिलीसेकंड। अगर आपको कुछ और दिखाई दे, तो बहुत सावधान रहें।

  • 2038 प्रॉब्लम को नज़रअंदाज़ करना। यदि आप एक मॉडर्न भाषा में एक स्टैंडर्ड वेब ऐप बना रहे हैं, तो आप शायद ठीक हैं। लेकिन अगर आप किसी एम्बेडेड IoT डिवाइस, कार के इंफोटेनमेंट सिस्टम के लिए C कोड लिख रहे हैं, या एक लेगेसी 32-बिट सिस्टम को मेंटेन कर रहे हैं, तो Y2038 बग एक बहुत ही वास्तविक, टिक-टिक करता टाइम बम है।

  • टाइमस्टैम्प बनाने के लिए अस्पष्ट स्ट्रिंग्स का उपयोग करना। "March 15, 2025 10:00 PM" जैसी स्ट्रिंग से टाइमस्टैम्प बनाना मुसीबत को दावत देना है। क्या यह आपके लोकल टाइमज़ोन में है? सर्वर के टाइमज़ोन में? या UTC में? हमेशा टाइमज़ोन-अवेयर ऑब्जेक्ट्स से टाइमस्टैम्प जेनरेट करें या स्पष्ट UTC स्ट्रिंग्स (जैसे ISO 8601 फ़ॉर्मैट: 2025-03-15T22:00:00Z) का उपयोग करें।

यह आपके रडार पर क्यों होना चाहिए

आप एक मॉडर्न डेवलपर होकर Epoch टाइम को समझे बिना काम नहीं कर सकते। यह कंप्यूटिंग में समय की lingua franca (सार्वभौमिक भाषा) है। आप इसे हर जगह पाएंगे:

  • APIs: JSON पेलोड में createdAt, updatedAt, और expires_at जैसी फ़ील्ड्स के लिए इसका लगातार उपयोग होता है।
  • JWTs: exp (expiration), iat (issued at), और nbf (not before) क्लेम सभी स्टैंडर्ड Unix टाइमस्टैम्प होते हैं।
  • डेटाबेस: समय को एक सिंगल इंटीजर के रूप में स्टोर करना अक्सर एक कॉम्प्लेक्स DATETIME टाइप का उपयोग करने की तुलना में इंडेक्सिंग और स्टोरेज के लिए ज़्यादा एफिशिएंट होता है।
  • लॉग फ़ाइलें: न्यूमेरिक टाइमस्टैम्प का उपयोग करने से दर्जनों अलग-अलग सर्वरों और सेवाओं पर हुई घटनाओं को कोरिलेट (correlate) करना बहुत आसान हो जाता है, भले ही वे अलग-अलग टाइमज़ोन में हों।
  • फ़ाइल सिस्टम: अधिकांश फ़ाइल सिस्टम फ़ाइल बनाने और मॉडिफाई करने की तारीखों को Unix टाइमस्टैम्प के रूप में स्टोर करते हैं।

यह कैसे काम करता है, यह समझना आपको समय से संबंधित मुश्किल बग्स की एक पूरी क्लास को आत्मविश्वास के साथ डीबग करने देता है। यह आपको टाइमज़ोन और कैलेंडर की इंसानी उलझी हुई दुनिया से बाहर निकलकर समय के बारे में वैसे ही सोचने देता है जैसे एक कंप्यूटर सोचता है: संख्याओं की एक सरल, व्यवस्थित लाइन के रूप में।

और गहराई में जाएं

  • Wikipedia: Unix time — एक व्यापक अवलोकन, जिसमें इतिहास, कार्यप्रणाली और संबंधित समस्याओं को शामिल किया गया है।
  • MDN Web Docs: Date.now() — JavaScript के मिलीसेकंड-प्रिसिजन वाले इपॉक टाइमस्टैम्प के उपयोग की व्याख्या करता है।
  • The Year 2038 Problem — 32-बिट इंटीजर ओवरफ्लो के कारणों और परिणामों पर एक विस्तृत नज़र।
  • RFC 822: Standard for the Format of ARPA Internet Text Messages — एक पुराना लेकिन foundational दस्तावेज़ जो टेक्स्ट-आधारित डेट फ़ॉर्मैट्स को निर्दिष्ट करता है, यह दिखाता है कि Unix टाइम किस जटिलता से बचाता है।
  • A brief history of time zones — इस बात का संदर्भ कि पहली बार में समय का मानकीकरण करना इतना महत्वपूर्ण क्यों था।

थ्योरी हो गई। अब हाथ आज़माइए — 100% आपके ब्राउज़र में।

टूल आज़माएँ: युग परिवर्तक