0

I solved the problem itself, but I wanted to know why this is happening.

The problem is this: Initially, a date and time with a time zone in String format ("dd-MM-yyyy HH:mm:ss:SSSS OOOO") is sent to the database. The application receives this date in the same format, through the mapper this date is converted to ZonnedDateTime ("dd-MM-yyyy HH:mm:ss:SSSS OOOO"), and from it back to a String in the date and time format ("dd-MM -yyyy HH:mm"). In Intellij IDEA this code works perfectly, but in Android studio an error pops up. The problem was solved by changing the format when converting time from the database to ZonnedDateTime ("dd-MM-yyyy HH:mm:ss:SSSS zzzz").

I would like to know why this is happening.

Code in Android studio:

ZonedDateTime zonedDateTime = ZonedDateTime.parse(
                "22-12-2022 15:05:49:1200 GMT+10:00",
                DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss:SSSS OOOO")
        );

Error:

2022-12-23 12:18:13.558 24464-24464/com.example.sendmessages E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.sendmessages, PID: 24464
    java.time.format.DateTimeParseException: Text '22-12-2022 15:05:49:1200 GMT+10:00' could not be parsed: length=34; index=34
        at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1920)
        at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1855)
        at java.time.ZonedDateTime.parse(ZonedDateTime.java:591)
        at com.example.sendmessages.Mapping.MessageMapper.getEntityToDto(MessageMapper.java:18)

Same code in intellij IDEA:

ZonedDateTime zonedDateTime = ZonedDateTime.parse(
                    "22-12-2022 15:05:49:1200 GMT+10:00",
                    DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss:SSSS OOOO")
            );
            System.out.print(dateTimeFormatter.format(zonedDateTime));

# 22-12-2022 15:05

How the problem was solved:

ZonedDateTime zonedDateTime = ZonedDateTime.parse(
                "22-12-2022 15:05:49:1200 GMT+10:00",
                DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss:SSSS zzzz")
        );

# 22-12-2022 15:05
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • What versions are you using? – Basil Bourque Dec 23 '22 at 03:03
  • minSdk 26, targetSdk 32, Java 8 version, but I installed newer versions, but it didn't work. – Кирилл Протченко Dec 23 '22 at 03:22
  • 1
    I believe its a Java problem. https://stackoverflow.com/questions/37287103/why-does-gmt8-fail-to-parse-with-pattern-o-despite-being-copied-straight-ou. So I guess you are using a different Java version in IntelliJ IDEA which have fixed the issue you met. – Android Newbie A Dec 23 '22 at 03:41
  • Tip: You can avoid much trouble and headache by educating the publisher of your data to use only standard [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) formats for exchanging date-time values textually. – Basil Bourque Dec 23 '22 at 04:02
  • are the `1200` fraction of second (so equal to 120 milliseconds)? It’s a funny non-standard notation with colon as decimal separator. – Ole V.V. Dec 23 '22 at 05:19
  • Even though the exception message looks funny, perhaps like an internal error, the cause of it is probably a locale problem. I can reproduce a similar error in several locales including some French, Swedish, Arab and Farsi ones. For example in Bulgarian locale (`bg`) your formatter expects the localized offset written as `Гринуич+10:00` and therefore throws an exception for `GMT+10:00`. Which is the default locale in your Android Studio? Fix by specifying locale: `DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss:SSSS OOOO", Locale.ROOT)`. – Ole V.V. Dec 23 '22 at 05:35

1 Answers1

1

OffsetDateTime, not ZonedDateTime

GMT+10:00 is not a time zone. It is an offset-from-UTC, simply a number of hours-minutes-seconds ahead of or behind the temporal prime meridian of UTC (GMT, same thing for general business purposes).

A time zone is much more. A time zone is a named history of the past, present, and future changes to the offset used by the people of a particular region as decided by their politicians.

Since your input contains an offset, but not a time zone, you should be using OffsetDateTime class rather than ZonedDateTime.

Java

Let's run some code on the Java platform before trying Android.

String input = "22-12-2022 15:05:49:1200 GMT+10:00";
DateTimeFormatter f = null;
f = DateTimeFormatter.ofPattern( "dd-MM-yyyy HH:mm:ss:SSSS OOOO" );
OffsetDateTime odt = OffsetDateTime.parse( input , f );
System.out.println( "odt = " + odt );
String input2 = odt.format( f );
OffsetDateTime odt2 = OffsetDateTime.parse( input2 , f );
System.out.println( "input2 = " + input2 );
System.out.println( "odt2 = " + odt2 );

When run with Java 19.0.1+10:

odt = 2022-12-22T15:05:49.120+10:00

input2 = 22-12-2022 15:05:49:1200 GMT+10:00

odt2 = 2022-12-22T15:05:49.120+10:00

Android Studio

While I do not do Android work, I installed Android Studio just to verify your problem. The JetBrains Toolbox app installed version Dolphin 2021.3.1 Patch 1 on my MacBook Pro with M1 Pro chip.

I created a project using the "Phone and Tablet" template named Basic Activity. I used all defaults except switching the language from Kotlin to Java. After waiting a long while for downloads to complete, I was able to execute Make Project, and then run the default emulator.

I added code to the onCreate method of MainActivity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    String input = "22-12-2022 15:05:49:1200 GMT+10:00";
    DateTimeFormatter f = null;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
        f = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss:SSSS OOOO");
        OffsetDateTime odt = OffsetDateTime.parse(input, f);
        System.out.println("odt = " + odt);
        String input2 = odt.format(f);
        OffsetDateTime odt2 = OffsetDateTime.parse(input2, f);
        System.out.println("input2 = " + input2);
        System.out.println("odt2 = " + odt2);
    }
…

The result on the console is:

I/System.out: odt = 2022-12-22T15:05:49.120+10:00

I/System.out: input2 = 22-12-2022 15:05:49:1200 GMT+10:00

I/System.out: odt2 = 2022-12-22T15:05:49.120+10:00

So I cannot recreate your issue when using the appropriate class. Runs correctly.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • 1
    I tried to replace ZonedDateTime with OffsetDateTime, it did not fix the error. There is just a suggestion that this is due to different versions in Java in IDEA. But thanks a lot for the clarification! – Кирилл Протченко Dec 23 '22 at 04:25
  • 2
    As our friend Arvind so often says: never use `DateTimeFormatter` without locale (also see my comment under the question). – Ole V.V. Dec 23 '22 at 05:37