- JavaScript’in mevcut Date nesnesinin eksik ve tutarsız yapısına dikkat çekiliyor ve bunun yerine geçecek Temporal API tanıtılıyor
- Date, değiştirilebilir bir nesne (mutable object) olarak çalıştığı için gerçek tarih kavramıyla çelişiyor; ayrıca ayrıştırma hataları ve zaman dilimi işleme sınırlamaları gibi yapısal sorunlar barındırıyor
- Temporal, değişmezlik temelli yeni bir tarih ve saat işleme modeli sunuyor ve
PlainDate, ZonedDateTime, Duration gibi ayrıntılı sınıflar içeriyor
- Temporal yöntemleri mevcut nesneyi değiştirmek yerine yeni bir nesne döndürüyor, böylece açık ve güvenli zincirleme işlemler mümkün oluyor
- Temporal şu anda standartlaşma sürecinde 3. aşamada (Stage 3) ve Chrome ile Firefox gibi modern tarayıcılarda deneysel olarak destekleniyor
JavaScript’teki Date nesnesinin sorunları
Date yapıcısı, tutarsız ayrıştırma kuralları ve sezgisel olmayan indeksleme nedeniyle kafa karışıklığı yaratıyor
- Örnek: ay (month) 0’dan başlıyor, ancak gün (day) ve yıl (year) 1’den başlıyor
"99" dizesi 1999 yılı olarak, "100" ise 0100 yılı olarak yorumlanıyor; bu da tutarlılık eksikliğini gösteriyor
Date, zamanı (time) merkeze alacak şekilde tasarlanmış ve dahili olarak Unix zaman damgası (milisaniye cinsinden) biçiminde saklanıyor
- Zaman dilimi (time zone) desteği sınırlı; yaz saati uygulamasını (DST) veya Gregoryen olmayan takvimleri tanımıyor
- Bu sınırlamalar nedeniyle Moment.js, date-fns gibi büyük üçüncü taraf kütüphanelere bağımlılık yaygın hale gelmiş durumda ve bu da performans düşüşüne yol açıyor
Değişmezlik ile referans kavramının çatışması
- JavaScript’te ilkel değerler (primitive) değişmezdir ve doğrudan değer olarak saklanır; buna karşılık nesneler (object) referansla saklanır ve değiştirilebilir
Date, bir yapıcı (constructor) aracılığıyla oluşturulan nesne olduğu için değiştirilebilirdir
- Örnek:
setMonth() veya setDate() çağrıldığında özgün nesne doğrudan değişir
- Bu nedenle aynı nesneyi referanslayan değişkenler arasında beklenmedik değer değişiklikleri yaşanabilir
- Örnek:
today bir fonksiyona argüman olarak verildiğinde, fonksiyon içinde tarih değiştirilirse özgün today de değişir
Temporal: yeni tarih ve saat API’si
Temporal, bir yapıcı değil, bir ad alanı nesnesidir (namespace object) ve yapısı Math ile benzerdir
- Başlıca bileşenler:
PlainDate, PlainDateTime, PlainTime, ZonedDateTime, Duration, Now vb.
Temporal.Now, mevcut anı farklı biçimlerde döndürür
plainDateISO() → ISO biçiminde tarih
zonedDateTimeISO() → zaman dilimi içeren tarih-saat
- Temporal nesneleri açık bir yöntem sistemi sunar
add({ days: 1 }), subtract({ years: 2 }) gibi çağrılarla birim bazlı açık işlemler yapılır
- Mevcut nesne değiştirilmez, bunun yerine yeni bir nesne döndürülür ve değişmezlik korunur
Temporal’in çalışma biçimi ve avantajları
- Temporal nesneleri hâlâ nesne türündedir, ancak amaçlı bir değişmez kullanım deseni izler
- Örnek:
today.add({ days: 1 }) yeni bir tarih nesnesi döndürür; özgün today değişmez
Date ile karşılaştırıldığında daha sade ve daha açık bir sözdizimi sunar
- Zaman dilimi belirtme, süre hesaplama, ISO biçimini koruma gibi modern gereksinimlere uyum sağlar
add, subtract, since, until gibi yöntemlerin zincirlenmesiyle karmaşık tarih hesaplamaları kısa ve net şekilde ifade edilebilir
Standartlaşma durumu ve geleceğe bakış
Temporal, ECMAScript öneri sürecinde 3. aşamaya (Stage 3) ulaştı; yani tarayıcıların bunu uygulamaya başlaması tavsiye ediliyor
- Chrome ve Firefox’ta deneysel destek şimdiden başlamış durumda; diğer tarayıcıların da eklemesi bekleniyor
- Geliştiriciler şimdiden test ederek ve geri bildirim vererek spesifikasyonun iyileştirilmesine katkı sağlayabilir
Date varlığını sürdürecek olsa da, gelecekte Temporal’in varsayılan tarih işleme yöntemi haline gelmesi bekleniyor
- Yazı, “1995’te değiştirilmeliydi ama yine de Temporal.Now için en doğru zaman şu an” diyerek sona eriyor
1 yorum
Hacker News görüşleri
Bu yazı, JavaScript'in Date constructor'ının sahip olduğu çeşitli absürt davranışları ele alıyor
Özellikle
'YYYY-MM-DD'biçiminin UTC gece yarısı olarak yorumlanması ve bu yüzden yerel saat diliminde tarihin bir gün kayması sorununu açıklıyorAslında ISO 8601'e göre saat dilimi belirtilmemişse bunun yerel saat olarak kabul edilmesi gerekiyordu, ancak ES5 spesifikasyonu yazılırken yapılan bir hatayla “Z”(UTC) olarak işlendi
Daha sonra ES2015'te bunu düzeltmeye çalıştılar, ancak sayısız web sitesi mevcut hatalı davranışa bağlı olduğu için web uyumluluğu gerekçesiyle geri alındı
Ayrıntılar için Broken Parser bölümüne bakılabilir
'use strict'gibi bir'strict datetime'yönergesi olsaydı iyi olurduBöylece mevcut kodla uyumsuzluk sorunları yaratmadan doğru davranış seçmeli olarak uygulanabilirdi
Ya da
import Date from 'browser:date'gibi dahili bir modülle düzeltilmiş global nesneyi içe aktarma yaklaşımı da mümkün olabilirdiDoğum günü gibi yalnızca tarihi ifade eden bir değerin saat dilimi yüzünden değişmesi anlamsız
Eskiden Outlook'un doğum günlerini saat dilimiyle birlikte kaydetmesi nedeniyle, ülke değiştirdikçe doğum gününün bir gün kaydığı zamanları hatırlıyorum
Ama bir alternatif var mıydı? Eski IE5 dönemindeki gibi tarayıcı sürümüne göre dallanmayı zorunlu kılmak daha da kötü olurdu gibi geliyor
Rails ve Ruby'nin zaman işleme yaklaşımını gerçekten kıskanıyorum
Time.current.in_time_zone('America/Los_Angeles') + 3.days - 4.months + 1.hourgibi API'ler sezgisel ve güçlüRuby, Time nesnesini tek ve tutarlı bir nesne olarak overload ediyor; bu yüzden dönüşüm ya da cast etme konusunda neredeyse hiç kafa yormuyorsunuz
JS'te de
new Date().add({ days: 1 })gibi basitçe yazabilsek ne güzel olurdu diye düşünüyorumAyrıca core library'yi overload etmenin gerçekten iyi bir yaklaşım olup olmadığı da tartışmalı
Safari'nin hâlâ Temporal API desteği vermemesi üzücü
Gelecek yıl civarında destek gelmesini umuyorum
JavaScript Date'in birçok sorunu var, ama bir nesne olması başlı başına büyük sorun değil bence
Keşke immutable olsaydı, ama mutable bir nesnenin değişmesine şaşırmamak gerekir
Mutability'nin asıl tehlikesi yerel değil, yerel olmayan değişikliklerden doğuyor
Temporal API'nin artık saniye (leap second) bilgisini hiç ele almaması rahatsız edici
Astronomik hesaplamalar için bir JS aracı yapmak istiyorum ama UTC dönüşümü için artık saniye verisi gerekiyor
temporal-taigibi geçici çözümler var, ancak istemci tarafında artık saniye dosyasını tutmak gerektiği için uğraştırıcıSOP (CORS politikası) nedeniyle dış sitelerden dosyayı doğrudan almak da mümkün değil
Tarayıcılar düzenli olarak güncelleniyorken neden artık saniye bilgisinin gömülü gelmediği merak konusu
Sunucu
Access-Control-Allow-Originheader'ını ayarlarsa ya da veriyi JS dosyası olarak sunarsa bu mümkünYine de tarayıcının kendi içinde artık saniye verisini tutup güncellemesi maliyetli bir iş olabilir
UTC zaten doğası gereği artık saniyeleri içeren bir zaman ölçeği olduğundan, gerçekte yalnızca POSIX zamanı ile uğraşıyor demek daha doğru
Kod örneğinde
"33"değil,"50"ile başlayan değerlerin 1900'lü yıllar olarak işlendiği söylenmeliydi — bu sadece basit bir yazım hatası düzeltmesiTemporal polyfill kullanıyorum ve şu ana kadar oldukça memnunum
Sunucu tarafı ya da büyük uygulamalar için sorun olmayabilir, ama küçük uygulamalarda yük olabilir
Yazı tuhaf biçimde
Date.now()dan hiç söz etmiyorTemporal ile karşılaştırma yapılacaksa açıklama
Date.now()temel alınarak yapılmalıydıBu fonksiyon, 1 Ocak 1970'ten itibaren geçen milisaniye cinsinden süreyi döndürür
Temporal daha kullanıcı dostu bir API sunsa da, özünde amaç zamanın göreli mesafesini ifade etmektir
O halde Date'e uğramadan istenen biçime nasıl dönüştürülebileceği merak ediliyor
“daylight savings time” değil, “daylight saving time” denmesi gerektiğine dair küçük ama önemli bir düzeltme yapılmış
Şimdiye kadar JS Date'in bu kadar dağınık olduğunu bilmiyordum
O zaman biraz daha dikkatli olunsaydı, sayısız geliştirici bu tuzaklara düşmeyebilirdi