Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set the time-of-day on a ZonedDateTime in java.time?

Tags:

How can I alter the time-of-day portion of an existing ZonedDateTime object? I want to keep the date and time zone but alter the hour and minutes.

like image 835
Basil Bourque Avatar asked Apr 27 '16 23:04

Basil Bourque


People also ask

How do I get current time in ZonedDateTime?

now() now() method of a ZonedDateTime class used to obtain the current date-time from the system clock in the default time-zone. This method will return ZonedDateTime based on system clock with default time-zone to obtain the current date-time. The zone and offset will be set based on the time-zone in the clock.

How do I add hours to ZonedDateTime?

ZonedDateTime plusHours() method in Java with ExamplesplusHours() method of a ZonedDateTime class used to add the number of hours in this ZonedDateTime and return a copy of ZonedDateTime after addition. This operates on the instant time-line, such that adding one hour will always be a duration of one hour later.

How do I get end of the day from ZonedDateTime?

If you want the last second of the day, you can use: ZonedDateTime eod = zonedDateTime. with(LocalTime. of(23, 59, 59));

Is ZonedDateTime a UTC?

A ZonedDateTime represents a date-time with a time offset and/or a time zone in the ISO-8601 calendar system. On its own, ZonedDateTime only supports specifying time offsets such as UTC or UTC+02:00 , plus the SYSTEM time zone ID.


1 Answers

tl;dr

zdt.with ( LocalTime.of ( 16 , 15 ) ) 

Immutable objects

The java.time classes use the Immutable Objects pattern to create fresh objects rather than alter (“mutate”) the original object.

with()

The ZonedDateTime::with method is a flexible way to generate a new ZonedDateTime based on another but with some particular difference. You can pass any object implementing the TemporalAdjustor interface.

In this case we want to change just the time-of-day. A LocalTime object represents a time-of-day without any date and without any time zone. And LocalTime implements the TemporalAdjustor interface. So just that time-of-day value is applied while keeping the date and the time zone as-is.

ZonedDateTime marketOpens = ZonedDateTime.of ( LocalDate.of ( 2016 , 1 , 4 ) , LocalTime.of ( 9 , 30 ) , ZoneId.of ( "America/New_York" ) ); ZonedDateTime marketCloses = marketOpens.with ( LocalTime.of ( 16 , 0 ) ); 

Double-check that the duration of the span of time is as expected, six and a half hours.

Duration duration = Duration.between ( marketOpens , marketCloses ); 

Dump to console.

System.out.println ( "marketOpens: " + marketOpens + " | marketCloses: " + marketCloses + " | duration: " + duration ); 

marketOpens: 2016-01-04T09:30-05:00[America/New_York] | marketCloses: 2016-01-04T16:00-05:00[America/New_York] | duration: PT6H30M

Keep in mind that in this example we are also implicitly adjusting the seconds and fractional second in the time-of-day. The LocalTime object carries with it the hour, minute, second, and fractional second. We specified an hour and a minute. Our omission of a second and fractional second resulted in a default value of 0 for both during construction of our LocalTime. All four aspects of the LocalTime were applied to get our fresh ZonedDateTime.

Quite a few classes implement the TemporalAdjustor interface. See the list on that class doc, including LocalDate, Month, Year, and more. So you can pass any of those to alter that aspect of a date-time value.

Read the comment by Hochschild. You must understand the behavior when you specify a time-of-day that is invalid for a specific date & zone. For example, during a Daylight Saving Time (DST) cut-over.

like image 91
Basil Bourque Avatar answered Oct 07 '22 12:10

Basil Bourque