Günlük görüntüleyiciler, denetleme zaman çizelgeleri ve telemetri kullanıcı arayüzleri genellikle ISO 8601 zaman damgaları bir sunucu, veritabanı veya yerel saat tarafından mikrosaniye ya da nanosaniye hassasiyetinde kaydedilen etkinlikleri alır (örneğin, 2026-04-01T12:00:00.000123456Z). Eski Date nesnesi yalnızca milisaniyeleri depoladığından, bu dizeleri new Date() veya Date.parse() ile ayrıştırmak, milisaniyenin altındaki basamakları sessizce keser. Bu da aynı milisaniye içindeki farklı etkinliklerin çakışmasına ve kararsız bir sırada sıralanmasına neden olur.
Temporal.Instant, UTC zaman çizelgesinde nanosaniye hassasiyetinde ve ekli saat dilimi olmayan tam bir noktayı temsil eder. Temporal.Instant.from() ile önceden kaydedilmiş yüksek hassasiyetli zaman damgalarını ayrıştırırken tam nanosaniye değerini korur, Temporal.Instant.compare() ile kesin olarak sıralar ve etkinlikler arasındaki tam Temporal.Duration aralıklarını hesaplar. Tarayıcılarda Temporal.Now.instant(), Spectre zamanlama saldırısını azaltmak için kasıtlı olarak milisaniye veya mikrosaniye çözünürlüğüne sabitlenir. Harici saatler tarafından üretilen nanosaniye zaman damgalarını korumak için Temporal.Instant.from(), istemcide milisaniyenin altındaki aralıkları yerel olarak ölçerken performance.now() kullanın.
Nasıl uygulanır?
Yüksek hassasiyetli zaman damgaları arasındaki aralıkları ayrıştırmak, sıralamak ve ölçmek için:
- Kayıtlı zaman damgalarını
Temporal.Instantolarak ayrıştır: Sunucu, veritabanı veya günlük satırı tarafından sağlanan zaman damgası dizesindeTemporal.Instant.from(isoString)kullanın. Kaynağın kaydettiği zaman damgasını koruyun. TarayıcıdaTemporal.Now.instant()ile değiştirmeyin. - Etkinlikleri kronolojik olarak sıralama:
Array.prototype.sort()veyaArray.prototype.toSorted()işlevine iletilen karşılaştırıcı olarakTemporal.Instant.compare(a, b)kullanın. Tam nanosaniye değerini karşılaştırır, böylece milisaniye altı sıralama korunur. - Aralıkları hesaplama: Ardışık etkinlikler arasında
Temporal.Durationelde etmek içininstant.since(previousInstant)kullanın. Aynı zaman damgalarına sahip etkinlikleri tespit etmek içina.equals(b)kullanın. - Aralıkları
toLocaleString()ile göster:Temporal.Durationdeğerini,Intl.DurationFormatdeğerine yetki verenduration.toLocaleString()ile kullanıcılar için biçimlendirin. Görüntüleme için tek bir nanosaniyeNumberdeğerine dönüştürmeyin. - İletim için serileştirme: Standart bir ISO 8601 dizesi (her zaman
Zson ekiyle UTC'de) oluşturmak içinTemporal.Instant.prototype.toString()kullanın.
Örnek Kod: Yüksek Hassasiyetli Zaman Damgalarını Sıralama
// 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));
Stratejik Uygulama ve En İyi Uygulamalar
- Sıralanması veya farkının alınması gereken tek bir saate (sunucu, veritabanı veya günlük ardışık düzeni gibi) göre kaydedilen yüksek hassasiyetli zaman damgalarını ayrıştırmak için
Temporal.Instant.from()KULLANIN.Temporal.PlainDateTimedeğerinin aksineTemporal.Instant, evrensel zaman çizelgesinde net bir noktayı temsil eder. - Kaynak tarafından kaydedilen zaman damgasını KORUYUN. Tarayıcılarda
Temporal.Now.instant(), Spectre zamanlama saldırısı ve parmak izi azaltma için milisaniye/mikrosaniye hassasiyetine sabitlenir. Milisaniye altı yerel istemci aralıkları içinperformance.now()/performance.mark(), sunucudan veya yerel saatlerden nanosaniye zaman damgalarını ayrıştırmak içinTemporal.Instant.from()kullanın. - Sıralama için
Temporal.Instant.compare(), eşitlik kontrolleri içina.equals(b)KULLANIN;Temporal.Instant.compare(a, b) === 0çıkışını kontrol etmeyin veya.toString()çıkışını karşılaştırmayın. - Sıralama için yüksek hassasiyetli zaman damgası dizelerini
new Date()veyaDate.parse()ile ayrıştırmayın. Bu yöntem, dizeleri milisaniyeye kısaltır ve çakışmalara neden olur. - Aralığı, görüntüleme için tek bir sayıya DARALTMAMANIZ gerekir.
duration.total('nanoseconds'), ~104 günden uzun süreler içinNumber.MAX_SAFE_INTEGERdeğerini aşan birNumberdöndürür ve hassasiyeti sessizce kaybeder.epochNanoseconds(BigInt) değerini çıkarmak tam sonuç verir ancak birim yapısını siler. AralıklarıTemporal.Durationolarak tutun ve.toLocaleString()ile biçimlendirin. - Bir etkinliğin yerelleştirilmiş duvar saati zamanını kullanıcıya göstermeniz gerektiğinde
instant.toZonedDateTimeISO(timeZone)ileInstantdeğeriniTemporal.ZonedDateTimedeğerine DÖNÜŞTÜRÜN.
Yedek strateji
Temporal için yedekler ve tarayıcı desteği
Yerel Temporal API'yi henüz desteklemeyen tarayıcılar için özellik algılamayı kullanın ve temporal-polyfill'yi dinamik olarak yükleyin (~15 KB min+gz).
temporal-polyfill öğesini içe aktarmanın, Temporal nesnesini otomatik olarak global kapsama atamadığını unutmayın. Kodunuz globalThis.Temporal değerine bağlıysa bunu açıkça atayın.
// 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();
})();