I understand that you need a LocalDateTime
for an API that due to a design problem beyond your control is trying to use LocalDateTime
for a point in time.
If an external contract dictates in which time zone or at which UTC offset the LocalDateTime
is to be understood, LocalDateTime
can be made to work, at least for 99.977 % of cases. You will still have a programming error waiting to happen on the day when some colleague programmer does not read the contract, a problem that we cannot solve in the code, only try to mitigate through good commenting.
If for example the contract says UTC, then we need to make sure we convert the time to UTC. And we need the offset from the string for doing so.
ZoneOffset contractualOffset = ZoneOffset.UTC;
String stringWeveGot = "Fri, 07 Aug 2020 18:00:00 +0000";
LocalDateTime convertedDateTime = OffsetDateTime
.parse(stringWeveGot, DateTimeFormatter.RFC_1123_DATE_TIME)
.withOffsetSameInstant(contractualOffset)
.toLocalDateTime();
System.out.println(convertedDateTime);
Output:
2020-08-07T18:00
If the offset in the string is required to be 0 already, you need to validate that it is, or errors will go unnoticed and users will get wrong results. For example:
OffsetDateTime parsedOdt = OffsetDateTime
.parse(stringWeveGot, DateTimeFormatter.RFC_1123_DATE_TIME);
if (! parsedOdt.getOffset().equals(contractualOffset)) {
throw new IllegalStateException("Offset must be " + contractualOffset
+ ", was " + parsedOdt.getOffset());
}
LocalDateTime convertedDateTime = parsedOdt.toLocalDateTime();
If the contract mentions some time zone, convert to that time zone. I am taking Australia/Victoria as an example.
ZoneId contractualZone = ZoneId.of("Australia/Victoria");
String stringWeveGot = "Fri, 07 Aug 2020 18:00:00 +0000";
LocalDateTime convertedDateTime = OffsetDateTime
.parse(stringWeveGot, DateTimeFormatter.RFC_1123_DATE_TIME)
.atZoneSameInstant(contractualZone)
.toLocalDateTime();
System.out.println(convertedDateTime);
2020-08-08T04:00
You will get an ambiguous result at time anomalies where the clock is turned backward, for example at the fall back when summer time (DST) ends.
What went wrong in your code?
The cause of your exception is explained here: