Diğer cevaplar doğrudur, özellikle arganzheng'in java.time cevabı . Bazıları belirtildiği gibi, kötü tasarlanmış, kafa karıştırıcı ve zahmetli oldukları için eski java.util.Date/.Calendar sınıflarından kaçınmalısınız. Java.time sınıfları tarafından desteklenmiştir.
Gece yarısını ele alma stratejisi ve zaman dilimleri hakkında notlar ekleyeyim .
Yarı açık
Tarih-saat çalışmasında, zaman dilimleri genellikle “Yarı Açık” yaklaşımı kullanılarak tanımlanır. Bu yaklaşımda başlangıç kapsayıcı biten iken münhasır . Bu, sorunları çözer ve tutarlı bir şekilde kullanılırsa, tarih-zaman işlemenizle ilgili mantığı çok daha kolay hale getirir.
Çözülen bir sorun, günün sonunu tanımlamaktır. Günün son anı mı 23:59:59.999
( milisaniye )? Belki de java.util.Date sınıfında (en eski Java'dan; zahmetli - bu sınıftan kaçının!) Ve son derece başarılı Joda-Time kütüphanesinde. Ancak Postgres gibi veritabanı gibi diğer yazılımlarda son an 23:59:59.999999
( mikrosaniye ) olacaktır. Ancak java.time çerçevesi (Java 8 ve üstü, Joda-Time'ın halefi) gibi diğer yazılımlarda ve H2 Veritabanı gibi bazı veritabanlarında son an 23:59.59.999999999
( nanosaniye ) olabilir . Saçları ayırmak yerine, sadece ilk anı düşünün, son anı düşünmeyin.
Half-Open'da bir gün, bir günün ilk anından başlar ve ertesi günün ilk anına kadar gider, ancak bunu içermez . Öyle düşünmek yerine:
… Bugünden 00:00 (bu sabah erken gece yarısı) ile 12:00 (gece yarısı) arasında.
… Böyle düşün…
bugünün ilk anından yarının ilk anına kadar devam eder, ancak dahil değildir:
(> = 00:00:00.0
bugün VE < 00:00:00.0
yarın)
Veritabanı çalışmasında, bu yaklaşım anlamına değil kullanarak BETWEEN
operatörü SQL.
Günün başlangıcı
Ayrıca, günün ilk anı her zaman günün saati değildir00:00:00.0
. Yaz saati uygulaması (DST) bazı saat dilimlerinde ve muhtemelen diğer anormalliklerde, günün farklı bir saatte başladığı anlamına gelebilir.
Bu nedenle, java.time sınıfları bir çağrıyla günün başlangıcını belirleme işini yapsın LocalDate::atStartOfDay( ZoneId )
. Bu yüzden , bu örnek kodda gördüğünüz gibi LocalDate
tekrardan sapmalıyız ZonedDateTime
.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );
ZonedDateTime todayStart = now.toLocalDate().atStartOfDay( zoneId );
ZonedDateTime tomorrowStart = todayStart.plusDays( 1 );
İsteğe bağlı geçişi not edin ZoneId
. Atlanırsa, JVM'nizin geçerli varsayılan saat dilimi örtülü olarak uygulanır. Açık olmak daha iyi.
Saat dilimi, tarih-saat çalışması için çok önemlidir. Soru ve diğer bazı Cevaplar potansiyel olarak kusurludur, çünkü zaman dilimini bilinçli olarak ele almazlar.
Dönüştürmek
Eğer varsa gereken bir java.util.Date veya .Calendar kullanın o eski sınıfların eklenen yeni dönüşüm yöntemlerinin arayın.
java.util.Date utilDate = java.util.Date.from( todayStart.toInstant() );
java.util.GregorianCalendar gregCal = java.util.GregorianCalendar.from( todayStart );
Zaman aralığı
Bu arada, zaman dilimleri ile çok fazla iş yapıyorsanız, şunlara bir göz atın:
Duration
Period
Interval
Interval
Sınıf bulunur ThreeTen-Extra , proje java.time çerçevesine bir uzantı. Bu proje, java.time'a gelecekteki olası eklemeler için kanıt zeminidir.
Interval todayMontreal = Interval.of( todayStart.toInstant() , tomorrowStart.toInstant() );
Hakkında java.time
Java.time çerçevesi daha sonra Java 8 ve yerleşiktir. Bu sınıflar zahmetli eski yerini mirası gibi tarih-saat sınıfları java.util.Date
, Calendar
& SimpleDateFormat
.
Artık bakım modunda olan Joda-Time projesi java.time sınıflarına geçişi tavsiye ediyor .
Daha fazla bilgi için Oracle Eğiticisine bakın . Ve birçok örnek ve açıklama için Stack Overflow'da arama yapın. Spesifikasyon JSR 310'dur .
Sen değiştirebilir java.time sizin veritabanı ile doğrudan nesneleri. JDBC 4.2 veya sonraki bir sürümüyle uyumlu bir JDBC sürücüsü kullanın . Dizeye gerek yok, gerek yokjava.sql.*
sınıflara .
Java.time sınıflarını nereden edinebilirsiniz?
ThreeTen-Ekstra proje ek sınıfları ile java.time uzanır. Bu proje, java.time'a gelecekteki olası eklemeler için bir kanıt zeminidir. Burada bazı yararlı sınıfları gibi bulabilir Interval
, YearWeek
, YearQuarter
, ve daha .