Reputation: 61
I would like to simply make a DateTimeFormatter
to be used in OffsetDateTime
parser. But I get DateTimeParseException
:
final DateTimeFormatter ISO_LOCAL_DATE;
ISO_LOCAL_DATE = new DateTimeFormatterBuilder()
.appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
.appendLiteral('-')
.appendValue(MONTH_OF_YEAR, 2)
.appendLiteral('-')
.appendValue(DAY_OF_MONTH, 2)
.appendLiteral('T')
.appendValue(HOUR_OF_DAY,2)
.appendLiteral(':')
.appendValue(MINUTE_OF_HOUR,2)
.appendLiteral(':')
.appendValue(SECOND_OF_MINUTE,2)
.toFormatter().withResolverStyle(ResolverStyle.STRICT).withChronology(IsoChronology.INSTANCE);
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
OffsetDateTime.parse("2012-03-06T00:00:00",ISO_LOCAL_DATE);
I looked into one similar issue but there was no clue there either :/
What is the problem with the code above? sth to do with Formatter
or Threeten lib?
Upvotes: 2
Views: 742
Reputation: 7117
You didn't specify an offset in the input data.
This is an example of date-time with offset:
2012-03-06T00:00+01:00
Example of ZonedDateTime
:
2012-03-06T00:00+02:00[Europe/Paris]
Europe/Berlin
- could be considered as ZoneId
here. But each zone may have different offset for different time of the year (summer/winter time).
There is no one-to-one mapping between ZoneId
and ZoneOffset
:
Is there any way to convert ZoneId to ZoneOffset in java 8?
Instead of specifying ZoneOffset
you can specify ZoneId
and the offset will be determined automatically.
Then you can get ZonedDateTime
and convert it to OffsetDateTime
.
public OffsetDateTime ZonedDateTime.toOffsetDateTime()
This creates an offset date-time using the local date-time and offset. The zone ID is ignored.
A fix for your case specifying ZoneId
:
public class Main {
private static final DateTimeFormatter ISO_LOCAL_DATE = new DateTimeFormatterBuilder()
.appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
.appendLiteral('-')
.appendValue(MONTH_OF_YEAR, 2)
.appendLiteral('-')
.appendValue(DAY_OF_MONTH, 2)
.appendLiteral('T')
.appendValue(HOUR_OF_DAY,2)
.appendLiteral(':')
.appendValue(MINUTE_OF_HOUR,2)
.appendLiteral(':')
.appendValue(SECOND_OF_MINUTE,2)
.toFormatter()
.withResolverStyle(ResolverStyle.STRICT)
.withChronology(IsoChronology.INSTANCE)
.withZone(ZoneId.systemDefault()); // or whatever you have
public static void main(String[] args) {
ZonedDateTime zonedDateTime = ZonedDateTime.parse("2012-03-06T00:00:00", ISO_LOCAL_DATE);
System.out.println(zonedDateTime);
System.out.println(zonedDateTime.toOffsetDateTime());
}
}
Approximate output:
2012-03-06T00:00+01:00[Europe/City]
2012-03-06T00:00+01:00
Second option to fix - add offsetId()
to your parser builder and specify offset part for the input string:
public class Main {
private static final DateTimeFormatter ISO_LOCAL_DATE = new DateTimeFormatterBuilder()
.appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
.appendLiteral('-')
.appendValue(MONTH_OF_YEAR, 2)
.appendLiteral('-')
.appendValue(DAY_OF_MONTH, 2)
.appendLiteral('T')
.appendValue(HOUR_OF_DAY,2)
.appendLiteral(':')
.appendValue(MINUTE_OF_HOUR,2)
.appendLiteral(':')
.appendValue(SECOND_OF_MINUTE,2)
.appendOffsetId()
.toFormatter()
.withResolverStyle(ResolverStyle.STRICT)
.withChronology(IsoChronology.INSTANCE);
public static void main(String[] args) {
OffsetDateTime offsetDateTime = OffsetDateTime.parse("2012-03-06T00:00:00+02:00", ISO_LOCAL_DATE);
System.out.println(offsetDateTime);
}
}
Output:
2012-03-06T00:00+02:00
You can specify your own offset pattern instead of .appendOffsetId()
like:
.appendOffset("+HH:mm", "Z")
By the way, there are bunch of standard DateTimeFormatter
s you can use out-of-the-box to parse OffsetDateTime
.
public class Main {
public static void main(String[] args) {
String offsetStringTime = "2012-03-06T00:00:00+02:00";
OffsetDateTime offsetDateTime = OffsetDateTime.parse(offsetStringTime);
OffsetDateTime offsetDateTime2 = OffsetDateTime.parse(offsetStringTime, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
OffsetDateTime offsetDateTime3 = OffsetDateTime.parse(offsetStringTime, DateTimeFormatter.ISO_ZONED_DATE_TIME);
System.out.println(offsetDateTime);
System.out.println(offsetDateTime2);
System.out.println(offsetDateTime3);
}
}
Output:
2012-03-06T00:00+02:00
2012-03-06T00:00+02:00
2012-03-06T00:00+02:00
Upvotes: 2