Java Dateve tarihle ilgili diğer dersler hakkında sıklıkla olumsuz geri bildirimlerle karşılaşıyorum . Bir .NET geliştiricisi olarak, aslında neyin yanlış olduğunu tam olarak (kullanmadan) anlayamıyorum.
Buna ışık tutan var mı?
Java Dateve tarihle ilgili diğer dersler hakkında sıklıkla olumsuz geri bildirimlerle karşılaşıyorum . Bir .NET geliştiricisi olarak, aslında neyin yanlış olduğunu tam olarak (kullanmadan) anlayamıyorum.
Buna ışık tutan var mı?
Yanıtlar:
Ah, Java Datesınıfı. Belki de herhangi bir dilde, hiçbir yerde bir şeyin nasıl yapılmamasının en iyi örneklerinden biri. Nereden başlayayım?
JavaDoc'u okumak, geliştiricilerin aslında bazı iyi fikirleri olduğunu düşünmeye sevk edebilir. İkisi arasındaki farkın temelde artık saniyeler olmasına rağmen (ki bu oldukça nadiren olur ) , UTC ve GMT arasındaki fark uzun uzadıya devam ediyor .
Bununla birlikte, tasarım kararları gerçekten iyi tasarlanmış bir API olma düşüncesini boşa harcıyor. İşte en sevdiğim hatalardan bazıları:
null. Sonuç olarak, 0..11'e sahibiz (ve bugün 109 yılının 11. ayı). Bir dizgeye dönüştürmek için aylarda benzer sayıda ++ ve - vardır.Calendar'düzeltmek' için tasarlanan, aslında aynı hataları yapıyor. Hala değişkendirler.Datea'yı temsil eder DateTime, ancak SQL topraklarındakilere ertelemek için java.sql.Datetek bir günü temsil eden başka bir alt sınıf vardır (bununla ilişkili bir saat dilimi olmasa da).TimeZoneile ilişkili hiçbir s yoktur Dateve bu nedenle aralıklar ('tam gün' gibi) genellikle gece yarısı-gece yarısı olarak temsil edilir (genellikle bazı rasgele zaman dilimlerinde)Son olarak, artık saniyelerin genellikle kendilerini bir saat içinde ntp ile güncellenen iyi bir sistem saatine karşı düzelttiğini belirtmek gerekir (aşağıdaki bağlantılara bakın). İki artık saniyenin (en az altı ayda bir, pratik olarak birkaç yılda bir) girişinde bir sistemin hala çalışır durumda ve çalışır durumda olma ihtimali oldukça düşüktür, özellikle de zaman zaman kodunuzun yeni sürümlerini yeniden dağıtmanız gerektiği gerçeği göz önüne alındığında . Sınıfları yeniden oluşturan dinamik bir dil veya bir WAR motoru gibi bir şey kullanmak bile sınıf alanını kirletecek ve sonunda permgen'in tükenmesine neden olacaktır.
Java 8'de java.time ile eski tarih-saat sınıflarının yerini alan JSR 310 , orijinal JSR'de şu şekilde haklı çıkar :
2.5 Java topluluğunun hangi ihtiyacı, önerilen şartname ile ele alınacaktır?
Şu anda Java SE'nin iki ayrı tarih ve saat API'si vardır - java.util.Date ve java.util.Calendar. Her iki API de tutarlı bir şekilde Java geliştiricileri tarafından web günlüklerinde ve forumlarda kullanılması zor olarak tanımlanmaktadır. Özellikle, her ikisi de aylarca sıfır endeks kullanır, bu da birçok hatanın bir nedenidir. Takvim ayrıca, esasen durumunu dahili olarak iki farklı şekilde depolaması nedeniyle yıllar boyunca birçok hatadan ve performans sorunundan muzdarip olmuştur.
Klasik bir hata (4639407), belirli tarihlerin bir Calendar nesnesinde oluşturulmasını engelledi. Bazı yıllarda bir tarih oluşturabilen ancak bazılarında oluşmayan bir kod dizisi yazılabilir, bu da bazı kullanıcıların doğru doğum tarihlerini girmesini engelleme etkisine sahiptir. Bunun nedeni, Takvim sınıfının, tarihsel olarak ikinci dünya savaşı sırasında artı 2 saat olduğu yaz aylarında yalnızca bir saatlik gün ışığından yararlanma süresi kazanımına izin vermesiydi. Bu hata şimdi düzeltilmiş olsa da, gelecekte bir ülke yaz aylarında artı üç saatlik bir gün ışığından yararlanma süresi kazancı sunmayı seçerse, Takvim dersi yine bozulur.
Mevcut Java SE API, çok iş parçacıklı ortamlarda da sorun yaşıyor. Değişmez sınıfların, durumları değiştirilemeyeceği için doğası gereği iş parçacığı açısından güvenli olduğu bilinmektedir. Bununla birlikte, hem Tarih hem de Takvim değiştirilebilir, bu da programcıların klonlamayı ve iş parçacığını açıkça düşünmesini gerektirir. Ek olarak, DateTimeFormat'ta iş parçacığı güvenliği eksikliği yaygın olarak bilinmemektedir ve izlenmesi zor olan birçok iş parçacığı sorunlarının nedeni olmuştur.
Java SE'nin datetime için sahip olduğu sınıflarla ilgili sorunların yanı sıra, diğer kavramları modellemek için sınıfları yoktur. Java SE'de saat dilimi dışındaki tarihler veya saatler, süreler, dönemler ve aralıkların sınıf temsili yoktur. Sonuç olarak, geliştiriciler sık sık bir süreyi temsil etmek için bir int kullanır ve javadoc birimi belirtir.
Kapsamlı bir tarih ve saat modelinin olmaması, birçok genel işlemin olması gerekenden daha yanıltıcı olmasına neden olur. Örneğin, iki tarih arasındaki günlerin sayısını hesaplamak şu anda özellikle zor bir sorundur.
Bu JSR, tarihler ve saatler (saat dilimleri olan ve olmayan), süreler ve zaman dönemleri, aralıklar, biçimlendirme ve ayrıştırma dahil olmak üzere eksiksiz bir tarih ve saat modeli sorununu çözecektir.
getMonth()sıfır tabanlı, getYear()1900 tabanlı (yani, 2009 yılı 109 olarak temsil edilir).Datesınıftan beklediğiniz pek çok işlev eksiktir .Senin için hissediyorum ... eski bir .NET programcısı olarak, aynı soruları sordum, .NET'teki API (zaman aralığı, operatör aşırı yükleme) çok uygun.
İlk olarak, belirli bir tarih oluşturmak için ya kullanımdan kaldırılmış bir API kullanırsınız ya da:
Calendar c = Calendar.getInstance();
c.set(2000, 31, 12)
Bir günü çıkarmak için kötü şeyler yaparsın.
Date firstDate = ...
Calendar c = Calendar.getInstance();
c.setTime(fistDate);
c.add(Calendar.DATE,-1);
Date dayAgo = c.getTime();
veya daha kötüsü
Date d = new Date();
Date d2 = new Date(d.getTime() - 1000*60*60*24);
İki tarih arasında (gün / hafta / ay olarak) ne kadar zaman geçtiğini öğrenmek ... daha da kötüleşiyor
Ancak apache ( ) ' deki DateUtilsorg.apache.commons.lang.time.DateUtils bazı kullanışlı yöntemler sunar ve son zamanlarda kendimi yalnızca bunları kullanırken buldum
Brabster'ın yazdığı gibi, Joda Time aynı zamanda iyi bir harici kitaplıktır, ancak apache her şeyden daha "ortak" görünüyor ...
Periodve Durationsınıflarını kullanın.
Dürüst olmak gerekirse, Java'nın Date API'sini kullanılabilir buluyorum. Gördüğüm ve duydum sorunların çoğu ayrıntı, yararlı bir şey (yapmak için birden çok sınıfları dahil edilmesinin gerekliliği ile ilgilidir Calendar, Date, DateFormat/ SimpleDateFormat) ve benzeri basit erişimcilerine eksikliği getDayOfWeek().
Joda Time , Java'da saygın bir alternatif API'dir ve Why Joda Time bölümünde, neden ilgi çekici olabilecek uygun bir alternatif olduğuna dair daha fazla argüman sunar.