Reputation: 563
I am receiving instant from a service and below are the cases.
In first case, say instant = "2021-03-23T04:17:35Z"
& In second case,
instant = "2021-07-15T05:27:00Z"
Then required to convert instant to offsetDateTime, doing like
OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.UTC)
Now I want to calculate hours gap between above offsetDateTime and instant.now
ChronoUnit.HOURS.between(Instant.parse(offsetDateTime), Instant.now())
Results
case 1 : it works fine
case 2 : ERROR :
DateTimeParseException: Text '2021-07-15T05:27Z' could not be parsed at index 16
Figured out the reason :
in case 2, if it would have pass the same 2021-07-15T05:27:00Z
. it would work but as instant.atOffset(ZoneOffset.UTC)
internally will call to below method, where zero would be removed, basically minute part will be sorted out. so below fn will return 2021-07-15T05:27Z
, this will lead to DateTimeParseException.
public static OffsetDateTime ofInstant(Instant instant, ZoneId zone) {
Objects.requireNonNull(instant, "instant");
Objects.requireNonNull(zone, "zone");
ZoneRules rules = zone.getRules();
ZoneOffset offset = rules.getOffset(instant);
LocalDateTime ldt = LocalDateTime.ofEpochSecond(instant.getEpochSecond(), instant.getNano(), offset);
return new OffsetDateTime(ldt, offset);
}
One solution I am assuming manually append the zero but that's might not be good practice.
Upvotes: 6
Views: 20758
Reputation: 338785
The Answer by Avinash is correct.
In addition, let’s look at this code from the Question:
public static OffsetDateTime ofInstant(Instant instant, ZoneId zone)
{
Objects.requireNonNull(instant, "instant");
Objects.requireNonNull(zone, "zone");
ZoneRules rules = zone.getRules();
ZoneOffset offset = rules.getOffset(instant);
LocalDateTime ldt = LocalDateTime.ofEpochSecond(instant.getEpochSecond(), instant.getNano(), offset);
return new OffsetDateTime(ldt, offset);
}
Firstly, if you want to apply an offset to a moment, there is no need for LocalDateTime
class. Simply do this:
OffsetDateTime odt = instant.atOffset( myZoneOffset ) ;
See the tutorial on naming conventions for at…
, from…
, with…
, etc.
When you want to perceive a moment thought the wall-clock time used by the people of a particular region, apply a time zone (ZoneId
) to an Instant
to get a ZonedDateTime
. Use ZonedDateTime
rather than OffsetDateTime
. A ZonedDateTime
is preferable to a mere OffsetDateTime
because it contains more information. This information may be critical if adding or subtracting to move to another moment. This information is also useful when producing text to represent the content of this date-time object.
Understand that an offset from UTC is simply a number of hours-minutes-seconds. A time zone is much more. A time zone is a history of the past, present, and future changes to the offset used by the people of a particular region as decided by politicians.
ZonedDateTime zdt = instant.atZone( myZoneId ) ;
So your method should be something like this.
public static ZonedDateTime ofInstant(Instant instant, ZoneId zone)
{
ZonedDateTime zdt =
Objects.requireNonNull( instant )
.atZone(
Objects.requireNonNull( zone )
)
;
return zdt ;
}
If you really need a OffsetDateTime
, despite ZonedDateTime
being preferred, extract one.
OffsetDateTime odt = zdt.toOffsetDateTime() ;
Upvotes: 6
Reputation: 79095
DateTimeFormatter
You do not need any DateTimeFormatter
to parse your Date-Time strings. The modern Date-Time API is based on ISO 8601 and does not require using a DateTimeFormatter
object explicitly as long as the Date-Time string conforms to the ISO 8601 standards.
import java.time.Instant;
import java.time.temporal.ChronoUnit;
public class Main {
public static void main(String[] args) {
Instant instant1 = Instant.parse("2021-03-23T04:17:35Z");
Instant instant2 = Instant.parse("2021-07-15T05:27:00Z");
System.out.println(instant1);
System.out.println(instant2);
System.out.println(ChronoUnit.HOURS.between(instant1, instant2));
}
}
Output:
2021-03-23T04:17:35Z
2021-07-15T05:27:00Z
2737
Learn more about the modern Date-Time API from Trail: Date Time.
Upvotes: 5