Whenever – Python için tip güvenli ve DST güvenli tarih-saat işleme kütüphanesi
(github.com/ariebovenberg)- Whenever, Python’un
datetimemodülündeki naive/aware karışımını ve DST hesaplama hatalarını tiplerle engelleyen; Rust uygulaması ya da saf Python uygulaması olarak kullanılabilen bir tarih-saat kütüphanesidir - Standart kütüphane
datetimeDST’yi her zaman yansıtmaz; örnek olarakdatetime(2023, 3, 25, 22, tzinfo=ZoneInfo("Europe/Paris")) + timedelta(hours=8)ifadesinin, DST nedeniyle bir saat atlanmasına rağmen 7 yerine 6 döndürdüğü gösteriliyor - Tip sistemi tek bir
datetimeile naive ve aware ayrımını yapamazken, WheneverInstant,ZonedDateTime,PlainDateTimegibi kullanım amacına göre ayrılmış tipler sunarak tip denetleyicisinin hataları yakalayabilmesini sağlar - Karşılaştırma tablosunda Arrow ve Pendulum’un DST güvenliği, typed aware/naive ve performansın tamamını karşılamadığı; Whenever’ın ise DST-safe, typed aware/naive ve fast maddelerinin tamamını desteklediği belirtiliyor
- Henüz 1.0 öncesinde olduğu için minor sürümlerde API değişebilir; değişiklikler changelog’da açıklanır ve tip denetleyicileri ya da IDE’ler uyarlama konusunda yardımcı olabilir
Whenever’ın çözmeye çalıştığı sorun
- Whenever, Python’da doğru ve tip denetimi yapılabilir tarih-saat kodu yazmaya yardımcı olan bir kütüphanedir
- Rust uygulaması sunar; Rust istemeyen kullanıcılar için saf Python sürümü de vardır
- Modern diğer dillerdeki tarih-saat kütüphanelerinde kullanılan kanıtlanmış kavramlara dayanarak tasarlanmıştır
- Diğer üçüncü taraf kütüphanelerden çok daha hızlı, çoğu zaman da standart kütüphaneden daha hızlı olduğu belirtilir
- 1.0 sürümü, uzun vadeli API’yi daha da iyileştirmek için bekletiliyor; özellikle duration ile ilgili geri bildirim alınıyor
Standart kütüphane datetime’ın sınırları
- Python’un
datetimemodülü 20 yılı aşkın süredir gelişirken, modern tarih-saat kütüphanelerinden beklenen yaklaşımlarla uyuşmayan bazı yönlere sahip oldu -
DST hesaplama sorunu
datetime, Daylight Saving Time(DST) durumunu her zaman dikkate almaz- Örnek kodda
Europe/Parissaat diliminde 25 Mart 2023 saat 22:00’ye 8 saat eklendiğinde, DST nedeniyle bir saat atlandığı için sonucun 7 olması gerekirken 6 döner - Bu bir bug değil; DST’nin yalnızca iki saat diliminin dahil olduğu hesaplamalarda dikkate alınmasını öngören bir tasarım kararıdır
-
naive/aware tip ayrımı sorunu
- Tek bir
datetimetipiyle naive datetime ve aware datetime tip sisteminde ayırt edilemez def schedule_meeting(at: datetime) -> None: ...gibi bir fonksiyon imzasından naive mı yoksa aware mı beklendiği anlaşılamaz
- Tek bir
Arrow ve Pendulum ile karşılaştırma
- Karşılaştırma tablosuna göre Whenever, DST-safe, typed aware/naive ve fast özelliklerinin tamamını karşılar
datetimeyalnızca fast maddesini karşılar; DST-safe ve typed aware/naive özelliklerini karşılamaz- Arrow, standart kütüphaneden daha tanıdık bir API sunmaya çalışır ancak temel sorunu çözmez
- Aynı footgun’ı korur
- Tipleri tek bir
arrow.Arrowtipine indirme kararı nedeniyle tip denetleyicisinin hataları yakalaması daha zor hale gelir
- Pendulum, 2016’da daha iyi DST işleme ve performans iyileştirmesi iddiasıyla ortaya çıktı ancak DST ile ilgili tuzakların yalnızca bir kısmını giderdi
- Performansı zaman içinde ciddi biçimde düştü
- Son 4 yılda yalnızca 2 sürüm yayımlanan uzun bir bakım durgunluğu içinde ve ciddi, eski birçok issue hâlâ duruyor
Başlıca özellikler
- DST-safe arithmetic destekler
- Tip güvenli API ile yaygın bug’ları önler
- Arrow ve Pendulum’un düzeltemediği sorunları düzeltir
- Kanıtlanmış ve aşina kavramlara dayanır
- Yüksek performans sunar
- Testleri ve dokümantasyonu güçlüdür
- Tarih aritmetiğini destekler
- Nanosaniye hassasiyeti destekler
- SQLAlchemy desteği sunar
- Pydantic desteği beta durumundadır
- Rust uygulaması ve saf Python seçeneği sunar
- free-threading desteği beta durumundadır
- per-interpreter GIL’i destekler
Kullanım örneği akışı
Instant,ZonedDateTime,PlainDateTimegibi açık tipleri içe aktararak farklı kullanım senaryolarını ifade ederInstant.now(), saat dilimi veya takvim karmaşıklığı olmadan belirli bir anı tanımlarnow.to_tz("Europe/Paris")gibi saat dilimini açıkça dönüştürürPlainDateTime("2023-10-28 22:00")diğer tiplerle tesadüfen karışmazadd(hours=6)çağrıldığında, yerel zaman ayarlamasının DST’yi yok saydığına dairNaiveArithmeticWarningoluşur- Saat dilimi
assume_tz("Europe/Amsterdam")ile açıkça varsayılmalıdır
ZonedDateTimeüzerindeadd(hours=6)yapıldığında DST geçişi dikkate alınır ve2023-10-29 03:00:00+01:00[Europe/Amsterdam]sonucu döner- Karşılaştırma, yuvarlama ve kırpma, ISO8601/RFC3339/RFC2822 format ayrıştırma ve özel desenle formatlamayı destekler
- Gerekirse standart kütüphane
datetimetipine ya da tersine dönüştürülebilir - Ayrıntılı kullanım feature overview ve API reference sayfalarında görülebilir
Kısıtlar ve kararlılık politikası
- Destek kapsamı 1 yılından 9999 yılına kadar proleptic Gregorian calendar’dır
- Saat dilimi offset’leri, IANA TZ DB ile tutarlı şekilde saniye cinsinden tam sayılarla sınırlıdır
- Whenever semantic versioning’i izler
- 1.0 öncesinde minor sürümlerde API değişebilir
- breaking change’ler changelog’da ayrıntılı biçimde açıklanır
- API tamamen tiplendirilmiş olduğundan, tip denetleyicileri veya IDE’ler API değişikliklerine uyum sağlamaya yardımcı olabilir
Lisans ve tasarım etkileri
- Whenever MIT License ile dağıtılır
- binary wheel, MIT, Apache-2.0 gibi benzer şekilde izin verici lisanslara sahip Rust bağımlılıklarını içerir
- Noda Time ve Joda Time kavram bazlı tip yaklaşımına öncülük etti; Noda Time’ın tip hiyerarşisi Whenever tasarımına doğrudan ilham verdi
- Temporal, DST belirsizliği ve yuvarlama çevresindeki karmaşık durumların ele alınmasına ilham verdi
- Python’un
datetimemodülü, Whenever’ın saf Python uygulamasında düşük seviyeli tarih-saat işleme için yaygın olarak kullanılır - Jiff projesindeki bazı fikirler de ödünç alınmıştır
- Benchmark karşılaştırma grafiği Ruff projesinden uyarlanmıştır
Henüz yorum yok.