Java 8 Date Time API (java.time) ve Joda-Time arasındaki farklar


264

Java.util.Date ve Joda-Time ile ilgili sorular olduğunu biliyorum . Ancak bazı kazmalardan sonra, java.time API'sı ( Java 8'de yeni , JSR 310 tarafından tanımlanan ) ve Joda-Time arasındaki farklar hakkında bir iş parçacığı bulamadım .

Java 8'in java.time API'sının çok daha temiz olduğunu ve Joda-Time'dan çok daha fazlasını yapabileceğini duydum. Ama ikisini karşılaştıran örnekler bulamıyorum.

  • Java.time Joda-Time'ın yapamadığı ne yapabilir?
  • Java.time, Joda-Time'dan daha iyi ne yapabilir?
  • Java.time ile performans daha mı iyi?

8
Bu değil, Java 7, Java 8 değil. Bu sorunun cevabı Java 8 için çok az ayrıntıyla düzenlendi. Sorum özellikle Java 7'nin java.util.Date değil, Java 8'in yeni DateTime API'sini sormak. Sadece Java 8'i JodaTime ile karşılaştıran bir cevap arıyorum.
Zack

2
belki de bu Oracle belgesi size yardımcı olabilir.
MarioDS

Java 7'niz varsa, ek kitaplığı kullanın, Java 8'iniz varsa yerleşik kitaplığı kullanın. Her iki kütüphane de temel olarak aynı kişi tarafından tasarlandığından, hangi büyük farklılıkları beklediğinizden emin değilim.
Peter Lawrey

2
@PeterLawrey: Joda-Time ve Java 8 tarih ve saat API'sı aslında oldukça farklı.
jarnbjo

5
Bu blog gönderisini her iki projenin de birincil yazarı olan Stephen Colbourne'dan da okuyabilirsiniz .
Matt Johnson-Pint

Yanıtlar:


416

Ortak özellikler

a) Her iki kütüphane de değişmez tipler kullanır. Joda-Time ayrıca ek değişken tipleri de sunar MutableDateTime.

b) Ayrıca: Her iki kütüphaneden de Eric Evans'ın tasarım çalışması "TimeAndMoney" veya etki alanı güdümlü stil hakkında Martin Fowler'ın fikirlerinden esinlenerek akıcı bir programlama tarzı için az ya da çok çaba sarf ediyorlar (her zaman mükemmel olmasa da ;-)).

c) Her iki kütüphanede de gerçek bir takvim tarihi türü (denir LocalDate), gerçek bir duvar saati türü (denir LocalTime) ve kompozisyon (denir LocalDateTime) elde edilir. O eski ile karşılaştırıldığında çok büyük bir kazançtır java.util.Calendarve java.util.Date.

d) Her iki kütüphane de yöntemi merkezli bir yaklaşım kullanır, yani kullanıcıyı kullanmak getDayOfYear()yerine cesaretlendirir get(DAY_OF_YEAR). Bu, karşılaştırıldığında çok fazla ekstra yönteme neden olur java.util.Calendar(ikincisi aşırı miktarda kullanım nedeniyle hiç tür güvenli değildir).

Verim

@ OO7'nin Mikhail Vorontsov'un analizine işaret eden diğer cevabı görün, ancak nokta 3 (istisna yakalama) muhtemelen eski - bu JDK hatasını görün . Farklı performans (genel olarak JSR-310 lehine ) esas olarak Joda-Time'ın dahili uygulamasının her zaman makine zamanı benzeri uzun ilkel (milisaniye cinsinden) kullanmasından kaynaklanmaktadır.

Boş

Joda-Time genellikle sistem saat dilimi, varsayılan yerel ayar, geçerli zaman damgası vb. İçin varsayılan olarak NULL kullanır. JSR-310 neredeyse her zaman NULL değerlerini reddeder.

Hassas

Joda-Time milisaniye hassasiyetle sınırlıyken JSR-310 nanosaniye hassasiyetle çalışır.

Desteklenen alanlar:

Java-8'deki (JSR-310) desteklenen alanlar hakkında genel bilgi geçici paketteki bazı sınıflar tarafından verilir (örneğin ChronoField ve WeekFields ), Joda-Time bu alanda oldukça zayıftır - bkz. DateTimeFieldType . Joda-Time'ın en büyük eksikliği, burada yerelleştirilmiş haftala ilgili alanların olmamasıdır. Her iki saha uygulama tasarımının ortak bir özelliği, her ikisinin de uzun tip değerlere dayanmasıdır (başka türler, hatta numaralandırmalar değil).

Sıralama

JSR-310 teklifler enums gibi DayOfWeekveya MonthJoda-Time bunu sunmamaktadır ise çoğunlukla önce 2002-2004 yıllarında geliştirilen çünkü Java 5 .

Bölge API'sı

a) JSR-310, Joda-Time'dan daha fazla saat dilimi özelliği sunar. Sonuncusu, JSR-310 bunu yapabilirken, saat dilimi ofset geçişlerinin geçmişine programatik bir erişim sağlayamaz.

b) Bilginiz için: JSR-310 dahili saat dilimi deposunu yeni bir konuma ve farklı bir biçime taşımıştır. Eski kütüphane klasörü lib / zi artık mevcut değil.

Düzenleyici ve Mülkiyet

JSR-310 TemporalAdjuster, özellikle kütüphane veya çerçeve yazarları için zamansal hesaplamaları ve manipülasyonları dışsallaştırmak için resmi bir yol olarak -interface'i tanıttı. eski sınıflar java.util.Date).

Ancak çoğu kullanıcı için bu özellik çok sınırlı bir değere sahiptir, çünkü kod yazma yükü hala kullanıcıya aittir. New TemporalAdjuster-concept tabanlı yerleşik çözümler çok fazla değil, şu anda sadece TemporalAdjusterssınırlı bir manipülasyon seti olan yardımcı sınıf (ve numaralandırmalar Monthveya diğer geçici türler) var.

Joda-Time bir saha paketi sunuyor, ancak uygulama yeni saha uygulamalarının kodlanması çok zor olduğuna dair kanıtlar gösterdi. Diğer yandan Joda-Time, bazı manipülasyonları JSR-310'dan çok daha kolay ve zarif hale getiren özellikler sunar, örneğin property.withMaximumValue () .

Takvim sistemleri

JSR-310 4 ek takvim sistemi sunar. En ilginç olanı Umalqura'dır (Suudi Arabistan'da kullanılır). Diğer 3 tanesi: Minguo (Tayvan), Japonca (1871'den beri sadece modern takvim!) Ve ThaiBuddhist (sadece 1940'tan sonra düzeliyor ).

Joda-Time, Umalqura gibi nişangah tabanlı bir takvime değil, hesaplama tabanına dayalı İslami bir takvim sunuyor . Tay-Budist, Joda-Time tarafından Minguo ve Japonca değil benzer bir biçimde sunulmaktadır. Aksi takdirde Joda-Time da kıpti ve etiyopik takvim sunar (ancak uluslararasılaşma için herhangi bir destek olmadan).

Avrupalılar için daha ilginç: Joda-Time ayrıca bir Gregoryen , Julian ve karışık-gregoryan-julian takvimi sunuyor. Bununla birlikte, gerçek tarihsel hesaplamalar için pratik değer sınırlıdır, çünkü tarih tarihinde farklı yıl başlangıcı gibi önemli özellikler hiç desteklenmemektedir (aynı eleştiri eski için de geçerlidir java.util.GregorianCalendar).

İbranice veya Farsça veya Hindu gibi diğer takvimler her iki kütüphanede de eksiktir.

Dönem günleri

Joda-Time (sürüm 2.0) DateTimeUtils sınıfında bazı yardımcı yöntemler sunarken JSR-310 JulianFields sınıfına sahiptir .

saatler

JSR-310'da arabirim (tasarım hatası) yoktur ancak java.time.Clockherhangi bir saat bağımlılığı enjeksiyonu için kullanılabilen soyut bir sınıf vardır. Joda-Time, MillisProvider arabirimini ve DateTimeUtils'te bazı yardımcı yöntemler sunar . Böylece Joda-Time, farklı saatlere (alay etme vb.) Sahip test odaklı modelleri de destekleyebilir.

Süre aritmetiği

Her iki kütüphane de bir veya daha fazla zamansal birimde zaman mesafelerinin hesaplanmasını destekler. Ancak, tek birim sürelerle çalışırken JSR-310 stili açıkça daha güzeldir (ve int yerine uzun tabanlı):

JSR-310 => long days = ChronoUnit.DAYS.between(date1, date2);

Joda-Time => int days = DAYS.daysBetween(date1, date2).getDays();

Çok üniteli sürelerin kullanımı da farklıdır. Hesaplama sonuçları bile farklılık gösterebilir - bu kapalı Joda-Time sorununa bakın . JSR-310 sadece sınıfları Period(yıllar, aylar ve günler Durationbazında ) ve (saniye ve nanosaniye bazında ) kullanmak için çok basit ve sınırlı bir yaklaşım kullanırken, Joda-Time PeriodTypekontrol etmek için sınıfı kullanarak daha sofistike bir yöntem kullanır hangi birimlerde bir süre (Joda-Time "Dönem" olarak adlandırılır) ifade edilir. YaparkenPeriodType-API bir şekilde JSR-310 tarafından benzer bir şekilde kullanmak hiç de garip. Özellikle JSR-310'da karışık tarih ve saat sürelerini tanımlamak henüz mümkün değildir (örneğin gün ve saatlere göre). Bu yüzden bir kütüphaneden diğerine geçiş söz konusu olduğunda uyarınız. Tartışılan kütüphaneler, kısmen aynı sınıf adlarına rağmen uyumsuzdur.

Aralıklar

Joda-Time sınırlı bir desteğe sahipken JSR-310 bu özelliği desteklemez. Ayrıca bu SO-cevabına bakınız .

Biçimlendirme ve Ayrıştırma

Her iki kütüphaneyi karşılaştırmanın en iyi yolu, DateTimeFormatterBuilder (JSR-310) ve DateTimeFormatterBuilder (Joda-Time) adlı eşit sınıfları görüntülemektir . JSR-310 varyantı biraz daha güçlüdür ( TemporalFieldalan uygulayıcısının fix () gibi bazı uzantı noktalarını kodlamayı başarması şartıyla her türlü işlemi de yapabilir ). Ancak en önemli fark - bence:

JSR-310, saat dilimi adlarını (biçim deseni sembolü z) daha iyi ayrıştırabilirken, Joda-Time bunu önceki sürümlerinde hiç yapamadı ve şimdi sadece çok sınırlı bir şekilde.

JSR-310'un bir diğer avantajı, Rusça veya Lehçe vb. Dillerde önemli olan bağımsız ay adları için destek sağlamaktır. Joda-Time'ın Java-8 platformlarında bile bu kaynaklara erişimi yoktur .

JSR-310'daki desen sözdizimi Joda-Time'a göre daha esnektir, isteğe bağlı bölümlere (köşeli parantez kullanarak) izin verir, CLDR standardına göre daha yönlendirilir ve dolgu (harf sembolü p) ve daha fazla alan sunar.

Aksi takdirde Joda-Time'ın PeriodFormatter kullanarak süreleri biçimlendirebileceği unutulmamalıdır . JSR-310 bunu yapamaz.


Umarım bu genel bakış yardımcı olur. Toplanan tüm bilgiler, daha iyi bir tarih ve saat kütüphanesinin nasıl tasarlanacağı ve uygulanacağına dair çabalarım ve araştırmalarım nedeniyle oradadır (hiçbir şey mükemmel değildir).

2015-06-24'ten güncelleme:

Bu arada , Java'daki farklı zaman kitaplıkları için tablo halinde bir genel bakış yazma ve yayınlama zamanını buldum . Tablolar ayrıca Joda-Time v2.8.1 ve Java-8 (JSR-310) arasında bir karşılaştırma içerir. Bu yazıdan daha ayrıntılı.


12
Bu olağanüstü bir gönderi. Tüm bu bilgileri paylaştığınız için çok teşekkürler. Joda ve JSR-310 (yalnızca vanilya kullanım durumları için) arasında seçim yapılırsa hangisini seçerdiniz? Şu anda bu seçimle karşı karşıyayım. JSR-310'u sadece daha yeni olduğu için ve mümkün olan her yerde “ilerlemeye” desteklemeye çalıştığımı düşünüyorum.
kevinarpe

7
@kevinarpe Sadece JSR-310 ve Joda-Time arasında bir seçimim olsaydı, muhtemelen JSR-310'u tercih ederim çünkü Joda-Time neredeyse daha fazla gelişmeyi durdurdu (yeni büyük özellikler beklenemez - sadece hata düzeltme ve küçük güncellemeler). Ve JSR-310 tasarımı daha modern (ve daha iyi iç kaliteye sahip). Bu arada ve şaşırtıcı değil, gerçek kararım kendi kütüphanemi Time4J'yi tercih etmektir - ayrıca yazımın altında verilen tabloya genel bakış bağlantısına da bakın. Alternatiflere sahip olmak her zaman iyidir ve ihtiyacınız olan özelliklere bağlıdır.
Meno Hochschild

Duration Java8'in bir Interval sürümü değil mi?
Christian Hujer

1
@ChristianHujer Hayır, java.time.Durationbir zaman çizelgesine sabitlenen bir aralığın aksine, başlangıç ​​veya bitiş için sorgulanamaz. Bu JSR-310 tipi, bilinmeyen bir başlangıçtan bu yana geçen bir çift saniye ve nanosaniyedir.
Meno Hochschild

42

Java 8 Tarih / Saat:

  1. Java 8 sınıfları insanlığın etrafında oluşturulmuştur. İnsan tarih-saat aritmetiği / dönüşümü için onları hızlı yapar.
  2. getDayOfMonthJava 8 uygulamasında O (1) karmaşıklığına sahip tarih / saat bileşeni alıcıları .
  3. JDK'da dahili olarak yakalanan ve yakalanan istisnalar nedeniyle Java 8 ea b121'de OffsetDateTime/ OffsetTime/ ZonedDateTimeöğesinin ayrıştırılması çok yavaştır.
  4. Paketler kümesi: java.time.*, java.time.chrono.*, java.time.format.*, java.time.temporal.*,java.time.zone.*
  5. Örnekler (zaman damgaları) Tarih ve Saat Kısmi Tarih ve Saat Ayrıştırıcı ve Biçimlendirici Saat dilimleri Farklı kronolojiler (takvimler).
  6. Varolan sınıfların, Date'in I18N veya L10N'yi desteklememesi gibi sorunları vardır. Değişebilirler!
  7. Daha basit ve daha sağlam.
  8. Saatler enjekte edilebilir.
  9. Saatler çeşitli özelliklerle oluşturulabilir - Statik saatler, Alaycı saatler, Düşük hassasiyetli saatler (tam saniye, tam dakika, vb.).
  10. Saatler, belirli zaman dilimleriyle oluşturulabilir. Clock.system(Zone.of("America/Los_Angeles")).
  11. Kod işleme tarihini ve saatini test edilebilir hale getirir.
  12. Testleri saat diliminden bağımsız yapar.

Joda Saati:

  1. Joda-Time içeride makine zamanı kullanıyor. Uzun / uzun değerlere dayalı manuel uygulama çok daha hızlı olacaktır.
  2. Joda-Time alıcıları, her alıcı çağrısında bilgisayardan insana zaman hesaplaması gerektirir, bu da Joda-Time'ı bu tür senaryolarda bir darboğaz haline getirir.
  3. Örnekleri, Tarih ve Saati, Kısmi ve Süreleri işleyen değişmez sınıflardan oluşur Esnektir. İyi tasarlanmıştır.
  4. Tarihleri ​​örnek olarak temsil eder. Ancak bir tarih ve saat birden fazla anı gösterebilir. Gün ışığından yararlanma saati bittiğinde çakışan saat. Yanı sıra ona karşılık gelen herhangi bir an yok. Gün ışığının başladığı saat. Basit işlemler için karmaşık hesaplamalar yapmak zorundadır.
  5. Null değerlerini yöntemlerinin çoğunda geçerli değerler olarak kabul eder. İnce hatalara yol açar.

Daha ayrıntılı karşılaştırma için bakınız: -

Java 8 Tarih / Saat kitaplığı performansı (ayrıca Joda-Time 2.3 ve juCalendar) . 8'de Yeni & Tarih ve Saat API'sı


"Testleri saat diliminden bağımsız yapar." Bununla tam olarak ne kastediyorsun?
Zack

@Zack: Muhtemelen saat dilimine bağlı olarak farklı davranan kodu test ederseniz, testi işletim sistemi tarafından sağlanandan farklı bir varsayılan saat dilimiyle çalışmaya zorlamanız gerekebilir.
jarnbjo

Hah - Joda'nın makine zamanından ziyade dahili olarak bir zaman makinesinde çalıştığını söylediğini sanıyordum ... Ve şaşırmam
Kyranstar

4
@ OO7 'İnsan zamanı' ne demek? Zaman yine de makineler tarafından hesaplanır.
IgorGanapolsky

1

Joda-Time artık bakım modunda

Soruya doğrudan bir cevap değil, Joda-Time projesi artık aktif olarak geliştirilmiyor. Ekip, kullanıcıların daha yeni java.time API'sına geçiş yapmasını önerir . Oracle'ın eğitimine bakın .

Resmi GitHub proje sayfasından:

Joda-time, saat dilimi verilerini güncel tutmak dışında artık aktif geliştirme aşamasında değildir. Java SE 8'den itibaren, kullanıcıların JDK'nın bu projenin yerini alan temel bir parçası olan java.time'a (JSR-310) geçmeleri istenir. Android kullanıcıları için java.time, API 26+ sürümüne eklenir. Daha düşük API düzeylerini desteklemesi gereken projeler ThreeTenABP kütüphanesini kullanabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.