tl; Dr.
Ana makinede sistem saatini manuel olarak değiştirmenin dışında, System.currentTimeMillis aracılığıyla sunulan geçerli saati geçersiz kılmanın kod içinde veya JVM bağımsız değişkenleriyle bir yolu var mı?
Evet.
Instant.now(
Clock.fixed(
Instant.parse( "2016-01-23T12:34:56Z"), ZoneOffset.UTC
)
)
Clock
Java.time içinde
Sahte tarih-saat değerleriyle testi kolaylaştırmak için tak-çıkar saat değişimi sorununa yeni bir çözümümüz var . Java.time paket içinde Java 8 soyut bir sınıf içeren java.time.Clock
bir hedefiyle,:
alternatif saatlerin gerektiğinde ve gerektiği zaman takılmasına izin vermek için
Kendi uygulamanızı takabilirsiniz Clock
, ancak muhtemelen ihtiyaçlarınızı karşılamak için zaten yapılmış bir uygulama bulabilirsiniz. Size kolaylık sağlamak için, java.time özel uygulamalar sağlamak için statik yöntemler içerir. Bu alternatif uygulamalar, test sırasında değerli olabilir.
Kadans değişikliği
Çeşitli tick…
yöntemler, geçerli anı farklı bir kadansla artıran saatler üretir.
Varsayılan , Java 8'de milisaniyeClock
kadar sık ve Java 9'da nanosaniye kadar (donanımınıza bağlı olarak) güncellenen bir zamanı bildirir . Gerçek geçerli anın farklı bir ayrıntı düzeyinde bildirilmesini isteyebilirsiniz.
Yanlış saatler
Bazı saatler yalan söyleyebilir ve ana işletim sisteminin donanım saatinden farklı bir sonuç üretebilir.
fixed
- Değişmeyen (artmayan) tek bir anı mevcut an olarak bildirir.
offset
- Geçerli anı bildirir, ancak geçirilen Duration
bağımsız değişken tarafından değiştirilir .
Örneğin, bu yıl en erken Noel'in ilk anını kilitleyin. başka bir deyişle, Noel Baba ve ren geyikleri ilk durduklarında . En erken saat dilimi bugünlerde gibi görünüyor Pacific/Kiritimati
at +14:00
.
LocalDate ld = LocalDate.now( ZoneId.of( "America/Montreal" ) );
LocalDate xmasThisYear = MonthDay.of( Month.DECEMBER , 25 ).atYear( ld.getYear() );
ZoneId earliestXmasZone = ZoneId.of( "Pacific/Kiritimati" ) ;
ZonedDateTime zdtEarliestXmasThisYear = xmasThisYear.atStartOfDay( earliestXmasZone );
Instant instantEarliestXmasThisYear = zdtEarliestXmasThisYear.toInstant();
Clock clockEarliestXmasThisYear = Clock.fixed( instantEarliestXmasThisYear , earliestXmasZone );
Her zaman aynı ana dönmek için o özel sabit saati kullanın. Kiritimati'de Noel gününün ilk anını alıyoruz , UTC'nin duvar saati on dört saat önce, 24 Aralık'ın önceki günü saat 10: 00'da gösteriliyor.
Instant instant = Instant.now( clockEarliestXmasThisYear );
ZonedDateTime zdt = ZonedDateTime.now( clockEarliestXmasThisYear );
instant.toString (): 2016-12-24T10: 00: 00Z
zdt.toString (): 2016-12-25T00: 00 + 14: 00 [Pacific / Kiritimati]
IdeOne.com'da canlı koda bakın .
Gerçek zaman, farklı saat dilimi
Clock
Uygulama tarafından hangi saat diliminin atanacağını kontrol edebilirsiniz . Bu, bazı testlerde faydalı olabilir. Ancak bunu, isteğe bağlı ZoneId
veya ZoneOffset
bağımsız değişkenleri her zaman açıkça belirtmeniz gereken üretim kodunda önermiyorum .
UTC'nin varsayılan bölge olmasını belirtebilirsiniz.
ZonedDateTime zdtClockSystemUTC = ZonedDateTime.now ( Clock.systemUTC () );
Herhangi bir belirli saat dilimini belirtebilirsiniz. Bir belirtme uygun bir zaman dilimi adı biçiminde continent/region
gibi America/Montreal
, Africa/Casablanca
ya da Pacific/Auckland
. Hiçbir zaman gibi 3-4 harfli bir kısaltma kullanın EST
veya IST
oldukları gibi değil , gerçek zaman dilimleri, değil standardize ve hatta benzersiz değil (!).
ZonedDateTime zdtClockSystem = ZonedDateTime.now ( Clock.system ( ZoneId.of ( "America/Montreal" ) ) );
JVM'nin geçerli varsayılan saat diliminin belirli bir Clock
nesne için varsayılan olması gerektiğini belirtebilirsiniz .
ZonedDateTime zdtClockSystemDefaultZone = ZonedDateTime.now ( Clock.systemDefaultZone () );
Karşılaştırmak için bu kodu çalıştırın. Hepsinin aynı anı, zaman çizelgesinde aynı noktayı bildirdiklerini unutmayın. Sadece duvar saati süresinde farklılık gösterirler ; başka bir deyişle, aynı şeyi söylemenin üç yolu, aynı anı göstermenin üç yolu.
System.out.println ( "zdtClockSystemUTC.toString(): " + zdtClockSystemUTC );
System.out.println ( "zdtClockSystem.toString(): " + zdtClockSystem );
System.out.println ( "zdtClockSystemDefaultZone.toString(): " + zdtClockSystemDefaultZone );
America/Los_Angeles
bu kodu çalıştıran bilgisayardaki JVM geçerli varsayılan bölgesiydi.
zdtClockSystemUTC.toString (): 2016-12-31T20: 52: 39.688Z
zdtClockSystem.toString (): 2016-12-31T15: 52: 39.750-05: 00 [Amerika / Montreal]
zdtClockSystemDefaultZone.toString (): 2016-12-31T12: 52: 39.762-08: 00 [Amerika / Los_Angeles]
Instant
Sınıf tanımı gereği UTC her zaman. Yani bölgeyle ilgili bu üç Clock
kullanım tamamen aynı etkiye sahiptir.
Instant instantClockSystemUTC = Instant.now ( Clock.systemUTC () );
Instant instantClockSystem = Instant.now ( Clock.system ( ZoneId.of ( "America/Montreal" ) ) );
Instant instantClockSystemDefaultZone = Instant.now ( Clock.systemDefaultZone () );
instantClockSystemUTC.toString (): 2016-12-31T20: 52: 39.763Z
instantClockSystem.toString (): 2016-12-31T20: 52: 39.763Z
instantClockSystemDefaultZone.toString (): 2016-12-31T20: 52: 39.763Z
Varsayılan saat
Varsayılan olarak kullanılan gerçekleme, tarafından Instant.now
döndürülendir Clock.systemUTC()
. Bu, a belirtmediğinizde kullanılan uygulamadır Clock
. Java 9 kaynak kodunun ön sürümündeInstant.now
kendiniz görün .
public static Instant now() {
return Clock.systemUTC().instant();
}
Varsayılan Clock
için OffsetDateTime.now
ve ZonedDateTime.now
olduğu Clock.systemDefaultZone()
. Kaynak koduna bakın .
public static ZonedDateTime now() {
return now(Clock.systemDefaultZone());
}
Varsayılan uygulamaların davranışı Java 8 ve Java 9 arasında değişti. Java 8'de, sınıfların çözünürlüğü nanosaniye depolayabilmesine rağmen, mevcut an yalnızca milisaniye cinsinden bir çözünürlükle yakalanır . Java 9, mevcut anı nanosaniye çözünürlükle yakalayabilen yeni bir uygulama getiriyor - elbette, bilgisayar donanım saatinizin kapasitesine bağlı olarak.
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 .
Şu anda bakım modunda olan Joda-Time projesi, java.time'a geçişi tavsiye ediyor sınıflarına .
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 desteğijava.sql.*
.
Java.time derslerini nereden edinebilirim?