AntoCode
AntoCode

Reputation: 433

OffsetDateTime does not parse correctly the time when sending a defined time

OffsetDateTime does not correctly parse the time when a defined time is sent to me

I have a service with a timezone UTC +4:00

I am sent two possible cases in STRING:

1- 2022-03-30T11:22:33.44+04:00 
2- 2022-03-30T11:22:33.44+0400

but when I do a

DateTimeFormatter formatter = DateTimeFormatter
        .ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS[xxx][xx][X]");

OffsetDateTime.parse("2022-03-30T11:22:33.44+04:00", formatter);

always returns me 2022-03-30T11:22:33.440

This is technically incorrect because my servers are in the same zone, so it should be: 2022-03-30T07:22:22:33.44Z

but whatever parse I do it doesn't work, is there any way to do it this way?

Upvotes: -1

Views: 862

Answers (1)

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79620

... it should be: 2022-03-30T07:22:22:33.44Z

Z represents zero time zone offset i.e. a date-time with Z is at UTC. Since you want the date-time at UTC, there are a couple of ways:

  1. Convert them into Instants after parsing the date-time strings. The Instant#toString returns your desired pattern.
  2. If you want to keep the type as OffsetDateTime, convert the OffsetDateTimes (obtained after parsing) into OffsetDateTimes with UTC zone offset using OffsetDateTime#withOffsetSameInstant.

About the pattern

I suggest you build a DateTimeFormatter using DateTimeFormatter.ISO_LOCAL_DATE_TIME (to handle a varying number of digits in the fraction-of-second e.g. S, SS, SSS etc. automatically) and [XXX][XX].

Examples of zone offset format Pattern
-08 X
-0830 XX
-08:30 XXX
-08:30:15 XXXXX

Demo:

class Main {

    private static final DateTimeFormatter FORMATTER = 
        new DateTimeFormatterBuilder()
            .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
            .appendPattern("[XXX][XX]")
            .toFormatter(Locale.ENGLISH);

    public static void main(String[] args) {
        String str1 = "2022-03-30T11:22:33.44+04:00";
        String str2 = "2022-03-30T11:22:33.44+0400";

        // Converting to Instant
        System.out.println(OffsetDateTime.parse(str1, FORMATTER).toInstant());
        System.out.println(OffsetDateTime.parse(str2, FORMATTER).toInstant());

        // Converting an OffsetDateTime to another OffsetDateTime at UTC
        System.out.println(OffsetDateTime.parse(str1, FORMATTER)
                .withOffsetSameInstant(ZoneOffset.UTC));
        System.out.println(OffsetDateTime.parse(str2, FORMATTER)
                .withOffsetSameInstant(ZoneOffset.UTC));

    }
}

Output:

2022-03-30T07:22:33.440Z
2022-03-30T07:22:33.440Z
2022-03-30T07:22:33.440Z
2022-03-30T07:22:33.440Z

Online Demo

Learn more about the modern Date-Time API from Trail: Date Time.

Upvotes: 1

Related Questions