The Oracle Tutorial page for the Instant
class shows this example code:
Instant oneHourLater = Instant.now().plusHours(1);
When I try to compile this code, the compiler throws the error:
InstantPrint.java:6: error: cannot find symbol Instant oneHourLater = Instant.now().plusHours(1); ^ symbol: method plusHours(int) location: class Instant
But this Java documentation mentions plusHours()
method, but I check this Instant
class and it doesn't contain plusHours()
method.
Thereafter, why mention this plusHours()
method in the example?
Unfortunately, the Oracle Tutorial is incorrect on this matter. That line of example code is simply wrong. Good catch on your part.
This error is quite unfortunate as the Tutorial is otherwise a fine resource for learning and studying Java.
Instant::plus
The Instant
class has no such method as plusHours
defined in either Java 8 or Java 9.
Instead, you can call the plus
method, and specify hours.
Instant later = instant.plus( 1 , ChronoUnit.HOURS ) ;
ZonedDateTime::plusHours
The Instant
class is a basic building-block class, indicating a moment on the timeline in UTC. Usually when performing manipulations such as adding hours, you’ll likely want to account for anomalies such as Daylight Saving Time, and so you will care about time zone. For that, use the ZonedDateTime
class. That class does offer a convenient plusHours
method, a likely source of the confusion for the Tutorial authors.
Specify a proper time zone name in the format of continent/region
, such as America/Montreal
, Africa/Casablanca
, or Pacific/Auckland
. Never use the 3-4 letter abbreviation such as EST
or IST
as they are not true time zones, not standardized, and not even unique(!).
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
versus ZonedDateTime
Let's look at an example of an anomaly in adding hours. When zoned, we add an hour to the particular moment of 1 AM on March 23, 2017 and of course expect 2 AM, but we are surprised to see 3 AM. Yet when we consider the very same moment in UTC rather than that particular time zone, the very same point on the timeline, adding an hour behaves as expected.
This particular anomaly is due to the adoption of Daylight Saving Time (DST) in most of North America, in particular here, the time zone America/New_York
. In the Spring, the clocks "spring-forward" an hour. As the clocks strike 2 AM, they jump to 3 AM. So the hour of two o’clock never existed on that day.
// 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." ) ;
See this code run live at IdeOne.com.
zdt: 2017-03-12T01:00-05:00[America/New_York]
zdtOneHourLater: 2017-03-12T03:00-04:00[America/New_York]
Yikes! 1 AM plus an hour is 3 AM? Yes, that is an anomaly known as Daylight Saving Time (DST).
instant: 2017-03-12T06:00:00Z
instantOneHourLater: 2017-03-12T07:00:00Z
Instant is always in UTC. So no anomalies, no DST. Adding an hour to 1 AM results in 2 AM every time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With