TL; DR
มีวิธีการในรหัสหรือด้วยอาร์กิวเมนต์ JVM เพื่อแทนที่เวลาปัจจุบันตามที่นำเสนอผ่าน System.currentTimeMillis นอกเหนือจากการเปลี่ยนนาฬิการะบบด้วยตนเองบนเครื่องโฮสต์หรือไม่
ใช่.
Instant.now(
Clock.fixed(
Instant.parse( "2016-01-23T12:34:56Z"), ZoneOffset.UTC
)
)
Clock
ใน java.time
เรามีโซลูชั่นใหม่ในการแก้ไขปัญหาของการเปลี่ยนนาฬิกา pluggable เพื่อความสะดวกในการทดสอบกับมารยาทค่าวันเวลา แพคเกจ java.timeในJava 8รวมถึงระดับนามธรรมjava.time.Clock
มีวัตถุประสงค์อย่างชัดเจน:
เพื่อให้สามารถเสียบนาฬิกาสำรองได้ตามต้องการ
คุณสามารถเชื่อมต่อการใช้งานของคุณเองClock
ได้แม้ว่าคุณจะพบว่ามีอยู่แล้วเพื่อตอบสนองความต้องการของคุณ เพื่อความสะดวกของคุณ java.time มีวิธีการแบบคงที่เพื่อให้การใช้งานพิเศษ การใช้งานทางเลือกเหล่านี้อาจมีประโยชน์ในระหว่างการทดสอบ
จังหวะที่เปลี่ยนแปลง
tick…
วิธีการต่างๆ ผลิตนาฬิกาที่เพิ่มช่วงเวลาปัจจุบันด้วยจังหวะที่แตกต่างกัน
ค่าเริ่มต้นจะClock
รายงานเวลาที่อัปเดตบ่อยเป็นมิลลิวินาทีใน Java 8 และใน Java 9 โดยละเอียดเท่ากับนาโนวินาที (ขึ้นอยู่กับฮาร์ดแวร์ของคุณ) คุณสามารถขอให้รายงานช่วงเวลาปัจจุบันที่แท้จริงด้วยรายละเอียดที่แตกต่างกัน
นาฬิกาเท็จ
นาฬิกาบางตัวสามารถโกหกได้ซึ่งให้ผลลัพธ์ที่แตกต่างจากนาฬิกาฮาร์ดแวร์ของโฮสต์ OS
fixed
- รายงานช่วงเวลาเดียวที่ไม่เปลี่ยนแปลง (ไม่เพิ่มขึ้น) เป็นช่วงเวลาปัจจุบัน
offset
- รายงานช่วงเวลาปัจจุบัน แต่เปลี่ยนไปตามDuration
อาร์กิวเมนต์ที่ส่งผ่าน
ตัวอย่างเช่นล็อกในช่วงเวลาแรกของคริสต์มาสที่เร็วที่สุดในปีนี้ ในคำอื่น ๆ เมื่อซานต้าและกวางเรนเดียของเขาให้หยุดแรกของพวกเขา โซนเวลาที่เร็วที่สุดในปัจจุบันน่าจะเป็นที่Pacific/Kiritimati
+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 );
ใช้นาฬิกาคงที่พิเศษเพื่อย้อนกลับไปยังช่วงเวลาเดิมเสมอ เราได้รับช่วงเวลาแรกของวันคริสต์มาสในKiritimatiโดย UTC จะแสดงเวลานาฬิกาแขวนที่สิบสี่ชั่วโมงก่อนหน้านี้ 10.00 น. ของวันก่อนหน้าของวันที่ 24 ธันวาคม
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
เวลาจริงเขตเวลาที่แตกต่างกัน
คุณสามารถควบคุมเขตเวลาที่กำหนดโดยClock
การนำไปใช้ สิ่งนี้อาจมีประโยชน์ในการทดสอบบางอย่าง แต่ฉันไม่แนะนำสิ่งนี้ในโค้ดการผลิตซึ่งคุณควรระบุอย่างชัดเจนเสมอว่าเป็นทางเลือกZoneId
หรือZoneOffset
อาร์กิวเมนต์
คุณสามารถระบุให้ UTC เป็นโซนเริ่มต้น
ZonedDateTime zdtClockSystemUTC = ZonedDateTime.now ( Clock.systemUTC () );
คุณสามารถระบุเขตเวลาใดก็ได้ ระบุชื่อโซนเวลาที่เหมาะสมในรูปแบบของcontinent/region
เช่นAmerica/Montreal
, หรือAfrica/Casablanca
Pacific/Auckland
อย่าใช้อักษรย่อ 3-4 ตัวเช่นEST
หรือIST
เนื่องจากไม่ใช่เขตเวลาจริงไม่เป็นมาตรฐานและไม่ซ้ำกัน (!)
ZonedDateTime zdtClockSystem = ZonedDateTime.now ( Clock.system ( ZoneId.of ( "America/Montreal" ) ) );
คุณสามารถระบุโซนเวลาเริ่มต้นปัจจุบันของ JVM ควรเป็นค่าเริ่มต้นสำหรับClock
ออบเจ็กต์หนึ่ง ๆ
ZonedDateTime zdtClockSystemDefaultZone = ZonedDateTime.now ( Clock.systemDefaultZone () );
เรียกใช้รหัสนี้เพื่อเปรียบเทียบ โปรดทราบว่าพวกเขารายงานในช่วงเวลาเดียวกันจุดเดียวกันบนไทม์ไลน์ พวกเขาต่างกันเพียง แต่ในเวลาผนังนาฬิกา ; กล่าวอีกนัยหนึ่งคือสามวิธีในการพูดสิ่งเดียวกันสามวิธีในการแสดงช่วงเวลาเดียวกัน
System.out.println ( "zdtClockSystemUTC.toString(): " + zdtClockSystemUTC );
System.out.println ( "zdtClockSystem.toString(): " + zdtClockSystem );
System.out.println ( "zdtClockSystemDefaultZone.toString(): " + zdtClockSystemDefaultZone );
America/Los_Angeles
เป็นโซนเริ่มต้นปัจจุบันของ JVM บนคอมพิวเตอร์ที่เรียกใช้รหัสนี้
zdtClockSystemUTC.toString (): 2016-12-31T20: 52: 39.688Z
zdtClockSystem.toString (): 2016-12-31T15: 52: 39.750-05: 00 [อเมริกา / มอนทรีออล]
zdtClockSystemDefaultZone.toString (): 2016-12-31T12: 52: 39.762-08: 00 [อเมริกา / Los_Angeles]
Instant
ระดับอยู่เสมอในเวลา UTC โดยความหมาย ดังนั้นClock
ประเพณีที่เกี่ยวข้องกับโซนทั้งสามนี้จึงมีผลเหมือนกันทุกประการ
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
นาฬิกาเริ่มต้น
การดำเนินงานที่ใช้โดยเริ่มต้นสำหรับการเป็นหนึ่งที่ส่งกลับโดยInstant.now
Clock.systemUTC()
นี่คือการนำไปใช้เมื่อคุณไม่ได้ระบุไฟล์Clock
. ดูตัวเองในรุ่นก่อนวางจำหน่าย Java 9 Instant.now
ซอร์สโค้ด
public static Instant now() {
return Clock.systemUTC().instant();
}
เริ่มต้นClock
สำหรับการOffsetDateTime.now
และเป็นZonedDateTime.now
Clock.systemDefaultZone()
ดูรหัสที่มา
public static ZonedDateTime now() {
return now(Clock.systemDefaultZone());
}
ลักษณะการทำงานของการปรับใช้เริ่มต้นเปลี่ยนไประหว่าง Java 8 และ Java 9 ใน Java 8 ช่วงเวลาปัจจุบันจะถูกบันทึกด้วยความละเอียดเป็นมิลลิวินาทีเท่านั้นแม้ว่าคลาสจะสามารถจัดเก็บความละเอียดได้ในระดับนาโนวินาทีก็ตาม Java 9 นำเสนอการใช้งานใหม่ที่สามารถจับภาพช่วงเวลาปัจจุบันด้วยความละเอียดนาโนวินาที - แน่นอนขึ้นอยู่กับความสามารถของนาฬิกาฮาร์ดแวร์คอมพิวเตอร์ของคุณ
เกี่ยวกับjava.time
java.timeกรอบถูกสร้างขึ้นใน Java 8 และต่อมา ชั้นเรียนเหล่านี้แย่งลำบากเก่ามรดกเรียนวันที่เวลาเช่นjava.util.Date
, และCalendar
SimpleDateFormat
ต้องการเรียนรู้เพิ่มเติมโปรดดูที่ออราเคิลกวดวิชา และค้นหา Stack Overflow สำหรับตัวอย่างและคำอธิบายมากมาย สเปกJSR 310
โครงการJoda-Timeขณะนี้อยู่ในโหมดการบำรุงรักษาแนะนำการโยกย้ายไปยังคลาสjava.time
คุณสามารถแลกเปลี่ยนวัตถุjava.timeโดยตรงกับฐานข้อมูลของคุณ ใช้ไดรเวอร์ JDBC ที่สอดคล้องกับJDBC 4.2หรือใหม่กว่า ไม่จำเป็นต้องมีสตริงไม่จำเป็นต้องมีjava.sql.*
คลาส Hibernate 5 & JPA 2.2 สนับสนุนjava.time
จะหาคลาส java.time ได้ที่ไหน?