Lớp Java 8 Instant không có phương thức plusHours mặc dù được hiển thị trong mã ví dụ Hướng dẫn Oracle


76

Các Oracle Hướng dẫn trang cho các Instantlớp học cho thấy mã ví dụ này:

Instant oneHourLater = Instant.now().plusHours(1);

Khi tôi cố gắng biên dịch mã này, trình biên dịch sẽ gặp lỗi:

  • lỗi
InstantPrint.java:6: error: không thể tìm thấy biểu tượng
        Instant oneHourLater = Instant.now (). PlusHours (1);
                                            ^
  biểu tượng: method plusHours (int)
  vị trí: lớp học Instant

Nhưng tài liệu Java này đề cập đến plusHours()phương thức, nhưng tôi kiểm tra Instantlớp này và nó không chứa plusHours()phương thức.

Sau đó, tại sao lại đề cập đến plusHours()phương pháp này trong ví dụ?


1
liên kết không được tìm thấy. Không có phương pháp nào như vậy docs.oracle.com/javase/8/docs/api/java/time/Instant.html
Ravi

1
Bạn đã xem xét cố gắng Instant#plus(long, TemporalUnit)
MadProgrammer

1
kiểm tra lại @Ravi
Ng Sharma

2
Và vâng, hướng dẫn là sai: /
MadProgrammer

35
Những người bỏ phiếu: Lưu ý rằng Câu hỏi này đã phát hiện ra mã ví dụ bị lỗi trong Hướng dẫn chính thức của Oracle. Một câu hỏi xứng đáng thực sự.
Basil Bourque,

Câu trả lời:


59

Các Oracle Hướng dẫn là không chính xác

Thật không may, Hướng dẫn Oracle không chính xác về vấn đề này. Dòng mã ví dụ đó đơn giản là sai. Bạn nắm bắt tốt.

Lỗi này khá đáng tiếc vì Hướng dẫn này là một nguồn tốt để học và nghiên cứu Java.

Instant::plus

Các Instantlớp học không có phương pháp như plusHoursquy định tại một trong hai Java 8 hoặc Java 9.

Thay vào đó, bạn có thể gọi plusphương thức và chỉ định giờ.

Instant later = instant.plus( 1 , ChronoUnit.HOURS ) ;

ZonedDateTime::plusHours

Các Instantlớp là một lớp xây dựng khối cơ bản, chỉ một khoảnh khắc trên Timeline trong UTC . Thông thường, khi thực hiện các thao tác như thêm giờ, bạn có thể muốn tính đến các yếu tố bất thường chẳng hạn như Giờ tiết kiệm ánh sáng ban ngày và vì vậy bạn sẽ quan tâm đến múi giờ . Đối với điều đó, hãy sử dụng ZonedDateTimelớp học. Lớp đó cung cấp một plusHoursphương pháp thuận tiện , có thể là nguồn gây nhầm lẫn cho các tác giả Hướng dẫn .

Chỉ định một tên múi giờ thích hợp trong các định dạng của continent/region, chẳng hạn như America/Montreal, Africa/Casablancahoặc Pacific/Auckland. Không bao giờ sử dụng từ viết tắt 3-4 chữ cái, chẳng hạn như ESThoặc ISTvì chúng không phải là múi giờ thực, không được tiêu chuẩn hóa và thậm chí không phải là duy nhất (!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, but viewed through the lens of a region’s wall-clock time.
ZonedDateTime zdtLater = zdt.plusHours( 1 ) ;

Instant đấu với ZonedDateTime

Hãy xem một ví dụ về sự bất thường trong việc thêm giờ. Khi khoanh vùng, chúng tôi thêm một giờ vào thời điểm cụ thể là 1 giờ sáng ngày 23 tháng 3 năm 2017 và tất nhiên là dự kiến ​​2 giờ sáng, nhưng chúng tôi rất ngạc nhiên khi thấy 3 giờ sáng. Tuy nhiên, khi chúng tôi xem xét cùng một thời điểm ở UTC chứ không phải múi giờ cụ thể đó, cùng một điểm trên dòng thời gian, thêm một giờ hoạt động như mong đợi.

Sự bất thường đặc biệt này là do việc áp dụng Giờ tiết kiệm ánh sáng ban ngày (DST) ở hầu hết Bắc Mỹ, cụ thể là ở đây, múi giờ America/New_York. Vào mùa xuân, đồng hồ "chuyển tiếp" một giờ. Khi đồng hồ điểm 2 giờ sáng, chúng chuyển sang 3 giờ sáng. Vì vậy, giờ hai giờ không bao giờ tồn tại trong ngày đó.

// ZonedDateTime
LocalDate ld = LocalDate.of( 2017 , Month.MARCH , 12 ) ;
LocalTime lt = LocalTime.of( 1 , 0 ) ;
ZoneId z = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
ZonedDateTime zdtOneHourLater = zdt.plusHours( 1 ) ;

System.out.println( "zdt: " + zdt ) ;
System.out.println( "zdtOneHourLater: " + zdtOneHourLater ) ; 
System.out.println( "Yikes! 1 AM plus an hour is 3 AM? Yes, that is an anomaly known as Daylight Saving Time (DST)." ) ;
System.out.println( "" ) ;

// Instant
Instant instant = zdt.toInstant() ;  // Adjust into UTC. Same moment, same point on the timeline, but viewed by a different wall-clock.
Instant instantOneHourLater = instant.plus( 1 , ChronoUnit.HOURS ) ;

System.out.println( "instant: " + instant ) ;
System.out.println( "instantOneHourLater: " + instantOneHourLater ) ;  
System.out.println( "Instant is always in UTC. So no anomalies, no DST. Adding an hour to 1 AM results in 2 AM every time." ) ;

Xem này chạy trực tiếp tại IdeOne.com .

zdt: 2017-03-12T01: 00-05: 00 [Châu Mỹ / New_York]

zdtOneHourLater: 2017-03-12T03: 00-04: 00 [Mỹ / New_York]

Rất tiếc! 1 giờ sáng cộng với một giờ là 3 giờ sáng? Vâng, đó là một điều bất thường được gọi là Giờ tiết kiệm ánh sáng ban ngày (DST).

tức thì: 2017-03-12T06: 00: 00Z

InstantOneHourLater: 2017-03-12T07: 00: 00Z

Instant luôn ở UTC. Vì vậy, không có dị thường, không có DST. Thêm một giờ đến 1 giờ sáng, kết quả là 2 giờ sáng mọi lúc.


7
@ AK.Sharma @Ravi Trang Hướng dẫn đó không chính xác , cả theo JavaDoc của Instantlớp và theo thực tế sử dụng Java 8 Cập nhật 144 (Tôi mới thử nghiệm này bây giờ). Tôi khuyên bạn nên gửi một báo cáo lỗi, nhưng cảnh báo đó ở đầu các trang cho tôi cảm giác buồn nôn rằng Oracle đang từ bỏ việc duy trì Hướng dẫn.
Basil Bourque

"Lớp Instant là một lớp xây dựng cơ bản, cho biết một thời điểm trên dòng thời gian trong UTC." Tuyên bố đó không chính xác, làm thế nào thời điểm trong thời gian có thể ở UTC?
abc667

@ abc667 An Instanttheo định nghĩa là số giây cộng với giây phân số kể từ thời điểm tham chiếu kỷ nguyên của thời điểm đầu tiên năm 1970 theo giờ UTC. Vì vậy, an Instantluôn là một thời điểm trong UTC. Theo đó, toStringphương thức tạo ra một chuỗi đại diện cho ngày và giờ trong ngày theo giờ UTC. Đọc tài liệu lớp học để biết những chi tiết nhỏ nhặt không liên quan đến việc sử dụng thực tế trong các ứng dụng dành cho doanh nghiệp.
Basil Bourque vào

cả instant.plus(1, ChronoUnit.HOURS)zdt.plushHours(1)thời gian quay trở lại tương ứng với các trường hợp cùng một lúc ( later.equals(zdtLater.toInstant()))
JFS

@jfs Đúng, nhưng tôi không chắc về quan điểm của bạn. ZonedDateTime chỉ là một Instant với múi giờ được chỉ định. Thêm một giờ vào một trong hai kết quả trong cùng một thời điểm trên dòng thời gian.
Basil Bourque
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.