Temporal.Instant की मदद से, ज़्यादा सटीक टाइमस्टैंप को क्रम से लगाना

वेब की सुविधाएं: Temporal

लॉग व्यूअर, ऑडिट टाइमलाइन, और टेलीमेट्री यूज़र इंटरफ़ेस (यूआई) अक्सर ऐसे इवेंट को शामिल करते हैं जिनके ISO 8601 टाइमस्टैंप को किसी सर्वर, डेटाबेस या नेटिव क्लॉक ने माइक्रोसेकंड या नैनोसेकंड की सटीक जानकारी के साथ रिकॉर्ड किया हो. उदाहरण के लिए, 2026-04-01T12:00:00.000123456Z. लेगसी Date ऑब्जेक्ट सिर्फ़ मिलीसेकंड को सेव करता है. इसलिए, new Date() या Date.parse() का इस्तेमाल करके उन स्ट्रिंग को पार्स करने से, मिलीसेकंड से कम के अंक अपने-आप हट जाते हैं. इससे एक ही मिलीसेकंड के अंदर होने वाले अलग-अलग इवेंट आपस में टकराते हैं और उन्हें सही क्रम में नहीं लगाया जा सकता.

Temporal.Instant, यूटीसी टाइमलाइन पर नैनोसेकंड की सटीक जानकारी के साथ एक सटीक पॉइंट दिखाता है. इसमें कोई टाइम ज़ोन अटैच नहीं होता. Temporal.Instant.from() की मदद से, पहले से रिकॉर्ड किए गए हाई-प्रिसिज़न टाइमस्टैंप को पार्स करते समय, यह नैनोसेकंड की पूरी वैल्यू को सुरक्षित रखता है. साथ ही, Temporal.Instant.compare() की मदद से डिटरमिनिस्टिक तरीके से क्रम में लगाता है और इवेंट के बीच के सटीक Temporal.Duration इंटरवल की गिनती करता है. ध्यान दें कि ब्राउज़र में, Temporal.Now.instant() को जान-बूझकर मिलीसेकंड या माइक्रोसेकंड रिज़ॉल्यूशन पर सेट किया जाता है, ताकि Spectre टाइमिंग-अटैक को कम किया जा सके. बाहरी क्लॉक से जनरेट किए गए नैनोसेकंड टाइमस्टैंप को सुरक्षित रखने के लिए, Temporal.Instant.from() का इस्तेमाल करें. साथ ही, क्लाइंट में मिलीसेकंड से कम के इंटरवल को स्थानीय तौर पर मेज़र करते समय, performance.now() का इस्तेमाल करें.

इन्हें कैसे लागू करें

ज़्यादा सटीक टाइमस्टैंप के बीच के इंटरवल को पार्स करने, क्रम से लगाने, और मेज़र करने के लिए:

  1. रिकॉर्ड किए गए टाइमस्टैंप को Temporal.Instant के तौर पर पार्स करें: सर्वर, डेटाबेस या लॉग लाइन से मिली टाइमस्टैंप स्ट्रिंग पर Temporal.Instant.from(isoString) का इस्तेमाल करें. सोर्स से रिकॉर्ड किए गए टाइमस्टैंप को बनाए रखें; ब्राउज़र में इसे Temporal.Now.instant() से न बदलें.
  2. इवेंट को समय के हिसाब से क्रम में लगाना: Temporal.Instant.compare(a, b) को Array.prototype.sort() या Array.prototype.toSorted() को पास किए गए कंपैरेटर के तौर पर इस्तेमाल करें. यह नैनोसेकंड की पूरी वैल्यू की तुलना करता है, ताकि मिलीसेकंड से कम समय के क्रम को सुरक्षित रखा जा सके.
  3. इंटरवल का हिसाब लगाना: लगातार होने वाले इवेंट के बीच Temporal.Duration पाने के लिए, instant.since(previousInstant) का इस्तेमाल करें. एक जैसे टाइमस्टैंप वाले इवेंट का पता लगाने के लिए, a.equals(b) का इस्तेमाल करें.
  4. toLocaleString() के साथ इंटरवल दिखाएं: duration.toLocaleString() का इस्तेमाल करने वाले उपयोगकर्ताओं के लिए, Temporal.Duration को फ़ॉर्मैट करें. यह Intl.DurationFormat को डेलिगेट करता है. डिसप्ले के लिए, नैनो सेकंड की एक Number में न बदलें.
  5. ट्रांसमिशन के लिए सीरियलाइज़ करना: स्टैंडर्ड ISO 8601 स्ट्रिंग को एमिट करने के लिए, Temporal.Instant.prototype.toString() का इस्तेमाल करें. यह हमेशा यूटीसी में होती है और इसके आखिर में Z होता है.

उदाहरण कोड: हाई-प्रिसिज़न टाइमस्टैंप को क्रम से लगाना

// Events received with nanosecond-precision ISO 8601 timestamps.
const rawEvents = [
  { nodeId: 'api-2', eventType: 'db.query', ts: '2026-04-01T12:00:00.000123456Z' },
  { nodeId: 'api-1', eventType: 'request.start', ts: '2026-04-01T12:00:00.000120000Z' },
  { nodeId: 'api-2', eventType: 'request.end', ts: '2026-04-01T12:00:00.000987654Z' },
];

// 1. Parse recorded timestamps as Temporal.Instant (never `new Date(ts)`,
// which drops everything below the millisecond).
const events = rawEvents.map(evt => ({
  ...evt,
  timestamp: Temporal.Instant.from(evt.ts),
}));

// 2. Sort chronologically with the static compare() method
function sequenceEvents(items) {
  // Instant.compare returns -1, 0, or 1, which is what sort() expects.
  return [...items].sort((a, b) => Temporal.Instant.compare(a.timestamp, b.timestamp));
}

// 3. Calculate and display the interval between consecutive events
function analyzeTrace(sortedEvents) {
  for (let i = 1; i < sortedEvents.length; i++) {
    const prev = sortedEvents[i - 1];
    const curr = sortedEvents[i];

    // since() returns a Temporal.Duration that retains nanosecond precision.
    const gap = curr.timestamp.since(prev.timestamp);

    // 4. toLocaleString() formats the duration for people (e.g., "3μs 456ns").
    // Avoid gap.total('nanoseconds'): spans over ~104 days exceed Number.MAX_SAFE_INTEGER.
    // 'en-US' is used here for deterministic output; pass undefined to use the user's locale.
    console.log(`${prev.eventType} → ${curr.eventType}: ${gap.toLocaleString('en-US', { style: 'narrow' })}`);
  }
}

analyzeTrace(sequenceEvents(events));

रणनीति को लागू करने के तरीके और सबसे सही तरीके

  • ज़रूर करें: Temporal.Instant.from() का इस्तेमाल, किसी एक घड़ी (जैसे, सर्वर, डेटाबेस या लॉग पाइपलाइन) के हिसाब से रिकॉर्ड किए गए सटीक टाइमस्टैंप को पार्स करने के लिए करें. ऐसा तब करें, जब टाइमस्टैंप को क्रम से लगाना हो या उनके बीच का अंतर निकालना हो. Temporal.PlainDateTime के उलट, Temporal.Instant यूनिवर्सल टाइमलाइन पर एक सटीक समय दिखाता है.
  • सोर्स से रिकॉर्ड किए गए टाइमस्टैंप को बनाए रखें. ब्राउज़र में, Temporal.Now.instant() को मिलीसेकंड/माइक्रोसेकंड की सटीक वैल्यू पर सेट किया जाता है. इससे Spectre टाइमिंग-अटैक और फ़िंगरप्रिंटिंग के जोखिम को कम करने में मदद मिलती है. लोकल सब-मिलीसेकंड क्लाइंट इंटरवल के लिए, performance.now() / performance.mark() का इस्तेमाल करें. साथ ही, सर्वर या नेटिव क्लॉक से नैनोसेकंड टाइमस्टैंप को पार्स करने के लिए, Temporal.Instant.from() का इस्तेमाल करें.
  • DO क्रम से लगाने के लिए Temporal.Instant.compare() और समानता की जांच के लिए a.equals(b) का इस्तेमाल करें; Temporal.Instant.compare(a, b) === 0 की जांच न करें या .toString() आउटपुट की तुलना न करें.
  • क्रम में लगाने के लिए, ज़्यादा सटीक टाइमस्टैंप स्ट्रिंग को new Date() या Date.parse() के साथ पार्स न करें. ऐसा इसलिए, क्योंकि वे मिलीसेकंड में बदल जाती हैं और गड़बड़ियां पैदा करती हैं.
  • ऐसा न करें: किसी इंटरवल को छोटा करके, एक ही नंबर के तौर पर न दिखाएं. duration.total('nanoseconds'), Number दिखाता है. यह करीब 104 दिनों से ज़्यादा की अवधि के लिए, Number.MAX_SAFE_INTEGER से ज़्यादा होता है और सटीक जानकारी नहीं देता. epochNanoseconds (BigInt) को घटाने से सटीक वैल्यू मिलती है, लेकिन यूनिट का स्ट्रक्चर खारिज हो जाता है. इंटरवल को Temporal.Duration के तौर पर रखें और उन्हें .toLocaleString() के साथ फ़ॉर्मैट करें.
  • DO: जब आपको किसी उपयोगकर्ता को किसी इवेंट का स्थानीय समय दिखाना हो, तब instant.toZonedDateTimeISO(timeZone) का इस्तेमाल करके Instant को Temporal.ZonedDateTime में बदलें.

फ़ॉलबैक रणनीति

Temporal के लिए फ़ॉलबैक और ब्राउज़र की सुविधा

ऐसे ब्राउज़र जो अब तक नेटिव Temporal एपीआई के साथ काम नहीं करते हैं उनके लिए, सुविधा की पहचान करने वाले टूल का इस्तेमाल करें और temporal-polyfill (~15 केबी min+gz) को डाइनैमिक तौर पर लोड करें.

ध्यान दें कि temporal-polyfill को इंपोर्ट करने से, Temporal ऑब्जेक्ट अपने-आप ग्लोबल स्कोप को असाइन नहीं होता. अगर आपका कोड globalThis.Temporal पर निर्भर करता है, तो इसे साफ़ तौर पर असाइन करें.

// Check if Temporal is supported natively
(async () => {
  if (typeof Temporal === 'undefined') {
    // Load the polyfill conditionally
    const module = await import('https://esm.sh/temporal-polyfill');
    globalThis.Temporal = module.Temporal;
    // Extend Date.prototype if needed
    Date.prototype.toTemporalInstant = module.toTemporalInstant;
  }
  initializeApp();
})();