Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use java.time to replace time part in the time instant

Tags:

java

time

java-8

I would like to change a time of an instant:

Instant instant = Instant.parse("2016-03-23T17:14:00.092812Z");
LocalTime newTime = LocalTime.parse("12:34:45.567891");
instant.with(newTime);

I expect to get an instant with the same date, but with the new time, i.e. 2016-03-23 12:34:45.567891.

But it throws the exception:

java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: NanoOfDay
    at java.time.Instant.with(Instant.java:720)
    at java.time.Instant.with(Instant.java:207)
    at java.time.LocalTime.adjustInto(LocalTime.java:1333)
    at java.time.Instant.with(Instant.java:656)

Any ideas how to fix?

like image 782
kan Avatar asked Jan 23 '26 14:01

kan


2 Answers

An Instant has no notion of a local calendar date or a local time. Its method toString() describes a moment on UTC-timeline in terms of date and time at offset UTC+00:00, but it is still a moment, not an information with local context.

You can use following conversion, however. Convert to a local timestamp, manipulate the local timestamp and then convert back to an instant/moment. It is very important to see that the conversion depends on the concrete timezone.

Instant instant = Instant.parse("2016-03-23T17:14:00.092812Z");
LocalTime newTime = LocalTime.parse("12:34:45.567891");

// or choose another one, the conversion is zone-dependent!!!
ZoneId tzid = ZoneId.systemDefault(); 
Instant newInstant =
    instant.atZone(tzid).toLocalDate().atTime(newTime).atZone(tzid).toInstant();
System.out.println(newInstant); // 2016-03-23T11:34:45.567891Z (in my zone Europe/Berlin)
like image 102
Meno Hochschild Avatar answered Jan 25 '26 03:01

Meno Hochschild


Setting the time on an instant doesn't make much sense. You would need a timezone to set a time. Transform the Instant to a ZonedDateTime, choosing the timezone. Then set the time on the ZonedDateTime. Then transform the ZonedDateTime to an Instant:

Assuming the time is for the UTC timezone:

Instant instant = Instant.parse("2016-03-23T17:14:00.092812Z");
LocalTime newTime = LocalTime.parse("12:34:45.567891");
ZonedDateTime dt = instant.atZone(ZoneOffset.UTC);
dt = dt.with(newTime);
instant = dt.toInstant();
System.out.println("instant = " + instant);
// prints 2016-03-23T12:34:45.567891Z
like image 27
JB Nizet Avatar answered Jan 25 '26 03:01

JB Nizet



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!