Geleneksel JavaScript Date nesnesi, proleptik Gregoryen takvimini temel alır. Bu nedenle, İslam (ay), İbrani (ay-güneş) veya Çin (ay-güneş) takvimleri gibi diğer takvim sistemlerini kullanan kullanıcılar için uygulama geliştirmek zor olabilir. Geliştiriciler daha önce bu sistemleri desteklemek için karmaşık üçüncü taraf kitaplıklarına veya manuel hesaplamalara güvenmek zorundaydı.
Temporal API, birden fazla takvim sistemi için birinci sınıf destek sağlar. Temporal, takvim tanımlayıcılarını tarih nesneleriyle ilişkilendirerek farklı kültürel bağlamlar için gereken karmaşık aritmetik ve biçimlendirme işlemlerini yerel olarak gerçekleştirir.
Nasıl uygulanır?
Temporal kullanarak global takvim sistemlerini desteklemek için:
- Takvim ilişkilendirme (Zorunlu): Bir Temporal nesnesi (ör.
Temporal.PlainDate) oluştururken veya dönüştürürken takvime duyarlı işlemler gerçekleştirmek içinwithCalendar()kullanarak istediğiniz takvim sistemini belirtmeniz gerekir. - Sabit tanımlayıcılar kullanın (ay-güneş takvimleri için zorunludur): Ay-güneş takvimlerinde yıllar içindeki belirli ayları tanımlamak için sayısal
monthdizini yerinemonthCodekullanmanız gerekir. Bu seçeneği yalnızca İbrani ve Çin takvimleri gibi artık ay kullanan takvimler için kullanın. - Takvim Değişmezlerine Uyma (Zorunlu): Ayları veya günleri yinelerken sabit değerler (ör. bir yılda 12 ay veya bir ayda 31 gün) varsaymamalısınız. Kodunuzun tüm takvimlerde çalıştığından emin olmak için
monthsInYearvedaysInMonthgibi özellikleri kullanın. - Takvime Duyarlı Karşılaştırmalar Kullanın (Zorunlu): Belirli bir takvim sistemindeki tarihleri karşılaştırırken yıl/ay/gün özelliklerini manuel olarak karşılaştırmak yerine
Temporal.PlainDate.compare()kullanmanız gerekir. Bu, takvim kuralları dahilinde kronolojik sıralamayı doğru şekilde işler.
Örnek Kod: Takvimleri Dönüştürme ve Yineleme
// 1. Helper to check calendar support
function isCalendarSupported(calendarId) {
try {
return Intl.supportedValuesOf('calendar').includes(calendarId);
} catch {
// Fallback for environments where supportedValuesOf is not available
return false;
}
}
// 2. Get current date in default ISO 8601 calendar
const isoDate = Temporal.Now.plainDateISO();
// 3. Convert to Hebrew calendar if supported
const calendarId = 'hebrew';
const targetDate = isCalendarSupported(calendarId)
? isoDate.withCalendar(calendarId)
: isoDate; // Fallback to ISO if not supported
if (targetDate.calendar.id !== calendarId) {
console.warn(`Calendar ${calendarId} not supported; falling back to ISO 8601`);
}
// 4. Log properties specific to the calendar
console.log(`Calendar: ${targetDate.calendar.id}`);
console.log(`Year: ${targetDate.year}`);
console.log(`Month Code: ${targetDate.monthCode}`); // Stable across leap years
// 5. Safely iterate through months in the current year
for (let m = 1; m <= targetDate.monthsInYear; m++) {
console.log(`Month ${m} has ${targetDate.with({ month: m }).daysInMonth} days.`);
}
// 6. Compare dates within the same calendar
const today = Temporal.Now.plainDateISO().withCalendar(calendarId);
const comparison = Temporal.PlainDate.compare(targetDate, today);
const relative = comparison < 0 ? 'Past' : comparison > 0 ? 'Future' : 'Today';
console.log(`Timeline: ${relative}`);
// 7. Format for display using toLocaleString (including era for era-based calendars like 'japanese')
const localizedDisplay = targetDate.toLocaleString('en-u-ca-hebrew', {
day: 'numeric',
month: 'long',
year: 'numeric',
era: 'long'
});
Stratejik Uygulama ve En İyi Uygulamalar
- Aylar arasında döngü oluştururken 12'yi varsaymak yerine üst sınır olarak
monthsInYearKULLANIN. - YAPIN: Yıldan bağımsız olarak artık ay kullanan takvimlerde (ör. İbrani veya Çin takvimi) belirli ayları tanımlamak için
monthCodekullanın. date.month === 12ayının yılın son ayı olduğunu VARSAYMAYIN.date.month === date.monthsInYearkullanın.inLeapYear === trueifadesinin, yılın yalnızca bir gün daha uzun olduğu anlamına geldiğini varsaymayın. Ay-güneş takvimlerinde tam bir artık ay ekleyebilir.- Yıl/Ay/Gün özelliklerini manuel olarak karşılaştırmak yerine belirli bir takvim sistemindeki iki tarihi karşılaştırırken
Temporal.PlainDate.compare()KULLANIN. - Kullanıcılar için tarihleri biçimlendirirken manuel dize birleştirme yerine
toLocaleString()KULLANIN. - Takvime özgü Temporal nesneleri oluşturmadan önce hedef takvim sisteminin
Intl.supportedValuesOf('calendar')kullanan ortam tarafından desteklendiğini DO (DO) ile doğrulayın. - DO Bazı takvimlerin (ör. İslami takvimin varyantları) sabit hesaplamalar yerine görsel gözleme dayalı olabileceğini unutmayın.
TemporalAPI'si, genellikle hesaplanan yaklaşımları kullanan ortamınIntluygulamasını takip eder. Kültürel veya dini açıdan önemli tarih hesaplamaları için alan uzmanlarına danışın ya da özel kitaplıklar kullanın. - Dönemleri kullanan takvimleri (ör. Japon, Budist) kullanırken
toLocaleString()kullanarak dönem adlarını HESABA KATIN.
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();
})();