membersound
membersound

Reputation: 86627

Equivalent of joda.ISODateTimeFormat in java.time?

I have the following joda date parser:

ISODateTimeFormat.dateTimeParser().withOffsetParsed().

I'd like to refactor this to java.time api. But what is the exact equivalent to the parser above, especially regarding the offset?

Upvotes: 5

Views: 3517

Answers (3)

ctranxuan
ctranxuan

Reputation: 815

I had the same issue. The best I've found given my constraints was to use two DateTimeFormatter one for parsing (based on suggestion of DateTimeFormatter Accepting Multiple Dates and Converting to One (java.time library)) and one for formatting:

@DataProvider
public static Object[][] dates() {
    return new Object[][] {
            { "2021-02-23T01:42:01.000-0000" },
            { "2021-02-23T01:42:01.000+0000" },
            { "2021-02-23T16:00:00.000-0800" },
            { "2021-02-23T05:42:00.000+0530" },
            { "2021-02-23T00:00:00.0Z" }
    };
}

@Test(dataProvider = "dates")
public void testFormatter(String date) {
    final DateTime jodaTime = ISODateTimeFormat.dateTime().withOffsetParsed().parseDateTime(date);
    final DateTimeFormatter dateTimeFormatterForParsing =
            new DateTimeFormatterBuilder().parseCaseInsensitive()
                                          .appendPattern("yyyy-MM-dd'T'HH:mm:ss.[SSSX][SX]")
                                          .toFormatter();
    final ZonedDateTime jdkTime = ZonedDateTime.parse(date, dateTimeFormatterForParsing);
    // see https://stackoverflow.com/questions/44600420/datetimeformatter-accepting-multiple-dates-and-converting-to-one-java-time-libr
    System.out.println(jodaTime + " vs " + jdkTime.format(dateTimeFormatterForParsing));

    final DateTimeFormatter dateTimeFormatterForFormatting =
            new DateTimeFormatterBuilder().parseCaseInsensitive()
                                          .appendPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
                                          .toFormatter();
    assertThat(jodaTime.toString()).isEqualTo(jdkTime.format(dateTimeFormatterForFormatting));
}

You can't use the same formatter for parsing and formatting because the above formatter used for parsing would output 2021-02-23T16:42:00.000-080-08 for 2021-02-23T16:42:00.000-0800.

That feels a bit hackish, though.

Upvotes: 0

Meno Hochschild
Meno Hochschild

Reputation: 44061

The best equivalent should be this constant in package java.time.format which prefers the parsed offset according to the documentation (like the behaviour when Joda-withOffsetParsed() is used):

DateTimeFormatter.ISO_OFFSET_DATE_TIME

However, there are still small differences. The decimal separator must be a dot in Java-8 (comma not tolerated although valid and even recommended in ISO-paper). Also: Java-8 manages nanosecond precision in contrast to Jodas millisecond precision. And maybe most important difference: If the offset is missing in your input then Java-8 throws an exception but Joda not (and applies the default time zone).

About choice of type: Since you are working with DateTime and fixed offsets the best equivalent should be here OffsetDateTime in Java-8. Example of migration:

DateTime dt = ISODateTimeFormat.dateTimeParser().withOffsetParsed().parseDateTime(input);

=>

OffsetDateTime odt = OffsetDateTime.parse(input, DateTimeFormatter.ISO_OFFSET_DATE_TIME); 

Upvotes: 10

Rahul Tripathi
Rahul Tripathi

Reputation: 172378

I dont think there is an exact equivalent for this. However you can use DateTimeFormatter class to construct the dates as per the required pattern.

Upvotes: 0

Related Questions