tl; Dr.
LocalDate // Represents an entire day, without time-of-day and without time zone.
.now( // Capture the current date.
ZoneId.of( "Asia/Tokyo" ) // Returns a `ZoneId` object.
) // Returns a `LocalDate` object.
.atStartOfDay( // Determines the first moment of the day as seen on that date in that time zone. Not all days start at 00:00!
ZoneId.of( "Asia/Tokyo" )
) // Returns a `ZonedDateTime` object.
Gün başlangıcı
Bir saat diliminde görüldüğü şekliyle bugünün tam uzunluğunu alın.
Başlangıçın kapsayıcı olduğu, sonun ise özel olduğu Yarı Açık yaklaşımı kullanma . Bu yaklaşım, kodunuzdaki günün son saniyesini hesaba katmayan kusurları çözer.
ZoneId zoneId = ZoneId.of( "Africa/Tunis" ) ;
LocalDate today = LocalDate.now( zoneId ) ;
ZonedDateTime zdtStart = today.atStartOfDay( zoneId ) ;
ZonedDateTime zdtStop = today.plusDays( 1 ).atStartOfDay( zoneId ) ;
zdtStart.toString () = 2020-01-30T00: 00 + 01: 00 [Afrika / Tunus]
zdtStop.toString () = 2020-01-31T00: 00 + 01: 00 [Afrika / Tunus]
Aynı anları UTC'de görün.
Instant start = zdtStart.toInstant() ;
Instant stop = zdtStop.toInstant() ;
start.toString () = 2020-01-29T23: 00: 00Z
stop.toString () = 2020-01-30T23: 00: 00Z
Bir tarihin tüm gününün saat dilimi yerine UTC'de görünmesini istiyorsanız, kullanın OffsetDateTime
.
LocalDate today = LocalDate.now( ZoneOffset.UTC ) ;
OffsetDateTime odtStart = today.atTime( OffsetTime.MIN ) ;
OffsetDateTime odtStop = today.plusDays( 1 ).atTime( OffsetTime.MIN ) ;
odtStart.toString () = 2020-01-30T00: 00 + 18: 00
odtStop.toString () = 2020-01-31T00: 00 + 18: 00
Bu OffsetDateTime
nesneler zaten UTC'de olacaktır, ancak toInstant
tanımları gereği her zaman UTC'de olan bu tür nesnelere ihtiyacınız varsa çağırabilirsiniz .
Instant start = odtStart.toInstant() ;
Instant stop = odtStop.toInstant() ;
start.toString () = 2020-01-29T06: 00: 00Z
stop.toString () = 2020-01-30T06: 00: 00Z
İpucu: Bu nesne çiftini temsil etmek üzere sınıfını kullanmak için ThreeTen-Extra kitaplığını projenize eklemek ilginizi çekebilir . Gibi karşılaştırma için Bu sınıf teklifler kullanışlı yöntemler , , ve daha fazlası.Interval
Instant
abuts
overlaps
contains
Interval interval = Interval.of( start , stop ) ;
interval.toString () = 2020-01-29T06: 00: 00Z / 2020-01-30T06: 00: 00Z
Yarı açık
Mprivat tarafından cevap doğrudur. Onun amacı, bir günün sonunu elde etmeye çalışmak değil, "ertesi gün başlamadan önce" ile karşılaştırmaktır. Onun fikri, bir zaman diliminin kapsayıcı bir başlangıca sahip olduğu , sonun ise özel olduğu "Yarı Açık" yaklaşım olarak bilinir .
- Java'nın geçerli tarih-saat çerçeveleri (java.util.Date/Calendar ve Joda-Time ), çağın milisaniyelerini kullanır . Ancak Java 8'de, yeni JSR 310 java.time. * Sınıfları nanosaniye çözünürlüğü kullanır. Günün son anının milisaniye sayımını zorlayarak yazdığınız herhangi bir kod, yeni sınıflara geçildiğinde yanlış olacaktır.
- Diğer kaynaklardan gelen verileri karşılaştırmak, başka çözünürlükler kullanırlarsa hatalı olur. Örneğin, Unix kitaplıkları tipik olarak tam saniyeleri kullanır ve Postgres gibi veritabanları tarih-saati mikrosaniye olarak çözümler.
- Bazı Gün Işığından Yararlanma Saati değişiklikleri gece yarısında meydana gelir ve bu durum işleri daha da karıştırabilir.
Joda-Time bu çok amaç için 2.3 teklifler bir yöntem, günün ilk anı elde etmek: withTimeAtStartOfDay()
. Benzer şekilde java.time LocalDate::atStartOfDay
,.
Daha fazla tartışma ve örnek görmek için StackOverflow'da "joda yarı açık" araması yapın .
Bill Schneider tarafından yazılan bu gönderiye bakın, Zaman aralıkları ve diğer aralıklar yarı açık olmalıdır .
Eski tarih-saat sınıflarından kaçının
Java.util.Date ve .Calendar sınıfları herkesin bildiği gibi zahmetlidir. Onlardan kaçının.
Java.time sınıflarını kullanın . Java.time çerçevesi son derece başarılı resmi halefi Joda-Time kütüphanesine.
java.time
Java.time çerçevesi, Java 8 ve sonraki sürümlerde yerleşiktir. Java 6 & 7 dön portlu ThreeTen-backport ayrıca, Android adapte projesi ThreeTenABP projesi.
An Instant
, nanosaniye çözünürlükte UTC'de zaman çizelgesinde bir andır .
Instant instant = Instant.now();
Bazı yerler için duvar saatini öğrenmek için bir saat dilimi uygulayın .
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
Günün ilk anını öğrenmek için LocalDate
dersi ve atStartOfDay
yöntemini gözden geçirin.
ZonedDateTime zdtStart = zdt.toLocalDate().atStartOfDay( zoneId );
Yarı Açık yaklaşımını kullanarak, ertesi günün ilk anını alın.
ZonedDateTime zdtTomorrowStart = zdtStart.plusDays( 1 );
Şu anda java.time çerçevesi Interval
, Joda-Time için aşağıda açıklandığı gibi bir sınıftan yoksundur . Bununla birlikte, ThreeTen-Extra projesi java.time'ı ek sınıflarla uzatır. Bu proje, java.time'a gelecekteki olası eklemeler için kanıtlayıcı zemindir. Sınıfları arasında Interval
. Bir Construct Interval
bir çift geçirilerek Instant
nesne. Biz çıkarabilir Instant
bizim dan ZonedDateTime
nesneler.
Interval today = Interval.of( zdtStart.toInstant() , zdtTomorrowStart.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
.
Daha fazla bilgi edinmek için Oracle Eğitimi'ne bakın . Ve birçok örnek ve açıklama için Stack Overflow'da arama yapın. Spesifikasyon JSR 310'dur .
Şu anda bakım modunda olan Joda-Time projesi, java.time sınıflarına geçişi tavsiye ediyor .
Sen değiştirebilir java.time sizin veritabanı ile doğrudan nesneleri. JDBC 4.2 veya üstü ile uyumlu bir JDBC sürücüsü kullanın . Dizelere gerek yok, derslere gerek yok . Hibernate 5 ve JPA 2.2 java.time'ı destekler .java.sql.*
Java.time derslerini nereden edinebilirim?
Joda-Time
GÜNCELLEME: Joda-Time projesi şu anda bakım modunda ve java.time sınıflarına geçişi tavsiye ediyor . Tarih için bu bölümü sağlam bırakıyorum.
Joda-Time çeşitli şekillerde bir zaman aralığını temsil etmek üç sınıf vardır: Interval
, Period
, ve Duration
. Bir Interval
bir spesifik başlayan ve Evrenin çizelgesinde biten sahiptir. Bu, "bir günü" temsil etme ihtiyacımıza uyuyor.
withTimeAtStartOfDay
Günün saatini sıfırlamaktan ziyade yöntemi çağırıyoruz . Yaz Saati Uygulaması ve diğer anormallikler nedeniyle günün ilk anı olmayabilir 00:00:00
.
Joda-Time 2.3 kullanan örnek kod.
DateTimeZone timeZone = DateTimeZone.forID( "America/Montreal" );
DateTime now = DateTime.now( timeZone );
DateTime todayStart = now.withTimeAtStartOfDay();
DateTime tomorrowStart = now.plusDays( 1 ).withTimeAtStartOfDay();
Interval today = new Interval( todayStart, tomorrowStart );
Gerekirse, java.util.Date'e dönüştürebilirsiniz.
java.util.Date date = todayStart.toDate();