1

Calling localDate.getDayOfWeek().getDisplayName in my UnitTest running on CircleCI returns a different value compared to running the UnitTest locally.

Here is the simplified sample code:

LocalDate localDate = LocalDate.of(2019, 12, 20);
String dayOfWeek = localDate.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.GERMANY);

assertEquals("Fr", dayOfWeek); // actual = "Fr."

dayOfWeek contains a '.' only on CI but I don't get why and how to fix it (properly).

This is the error log of the UnitTest:

junit.framework.ComparisonFailure: expected:<Fr[.]> but was:<Fr[]>
..

Hint: I'm using ThreeTen Android Backport

UPDATE As mentioned by @OleV.V.and @Arvind Kumar Avinash the reason for the different behaviour (local and CI) is the difference in the JDK versions (local 8.x and CI 11.x).

This leaves a part of my question open: "How to fix this properly?" This the correct/only way to change the JDK version on my CI docker image?

goemic
  • 1,092
  • 12
  • 24
  • goemic - Any update? – Arvind Kumar Avinash Dec 09 '20 at 20:58
  • Does this answer your question? [JDK dateformatter parsing DayOfWeek in German locale, java8 vs java9](https://stackoverflow.com/questions/46244724/jdk-dateformatter-parsing-dayofweek-in-german-locale-java8-vs-java9). [This](https://stackoverflow.com/questions/50248220/java-time-format-datetimeparseexception-text-mi-mai-09-091724-2018-could-no)? – Ole V.V. Dec 10 '20 at 04:14
  • Does ThreeTenABP run on CircleCI? Just curious. – Ole V.V. Dec 10 '20 at 04:17
  • 1
    @OleV.V. I'm pretty sure that this misbehaviour is related to different java versions (local and CI) but this does not answer my question on how to properly fix it – goemic Dec 10 '20 at 10:33

1 Answers1

2

Update:

After looking into the updated question, the problem seems to be because of missing library of ThreeTen Android Backport on the machine where CircleCI is running. In the absence of this library, probably it is defaulting to java.time when the code is getting re-compiled on this machine. You should check a few things on this machine:

  1. If the library has been imported successfully.
  2. If there is any setting to import the most appropriate types automatically if some types are missing.
  3. If the JDK version is the same as that of your local machine.

Original answer:

You can use TextStyle.SHORT_STANDALONE

import java.util.Locale;

import org.threeten.bp.LocalDate;
import org.threeten.bp.format.TextStyle;

class Main {
    public static void main(String[] args) {
        LocalDate localDate = LocalDate.of(2019, 12, 20);
        String dayOfWeek = localDate.getDayOfWeek().getDisplayName(TextStyle.SHORT_STANDALONE, Locale.GERMAN);
        System.out.println(dayOfWeek);
    }
}

Output:

Fr

I do not get a dot in the output for TextStyle.SHORT on my system though. Nevertheless, if you still want to use TextStyle.SHORT and not have the dot (or any punctuation mark) with it, you can replace every punctuation mark with a blank string.

import java.util.Locale;

import org.threeten.bp.LocalDate;
import org.threeten.bp.format.TextStyle;

class Main {
    public static void main(String[] args) {
        LocalDate localDate = LocalDate.of(2019, 12, 20);
        String dayOfWeek = localDate.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.GERMANY);
        System.out.println(dayOfWeek);

        // Remove all punctuation mark
        dayOfWeek = dayOfWeek.replaceAll("\\p{Punct}", "");
        System.out.println(dayOfWeek);
    }
}

Output:

Fr
Fr

Note: The result for TextStyle.SHORT changes with java.time API as shown below:

import java.time.LocalDate;
import java.time.format.TextStyle;
import java.util.Locale;

class Main {
    public static void main(String[] args) {
        LocalDate localDate = LocalDate.of(2019, 12, 20);

        String dayOfWeek = localDate.getDayOfWeek().getDisplayName(TextStyle.SHORT_STANDALONE, Locale.GERMANY);
        System.out.println(dayOfWeek);

        dayOfWeek = localDate.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.GERMANY);
        System.out.println(dayOfWeek);

        // Remove all punctuation mark
        dayOfWeek = dayOfWeek.replaceAll("\\p{Punct}", "");
        System.out.println(dayOfWeek);
    }
}

Output:

Fr
Fr.
Fr
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • Unfortunately `TextStyle.SHORT_STANDALONE` does not fix the problem. I still get the error on CI: `junit.framework.ComparisonFailure: expected: but was:` – goemic Dec 10 '20 at 09:08
  • @goemic - Looking at the error message, `assertEquals("Fr.", dayOfWeek);` will pass but then you are saying, `...running on CircleCI returns a different value compared to running the UnitTest locally.` which is surprising. – Arvind Kumar Avinash Dec 10 '20 at 09:15
  • Migrating to `java.time` is not an option (right now) because we are still facing some problems with r8 desugaring. Replacing the points is the 'hacky' fix I'm already doing but I'm looking for a real fix to make the code clean again - and to avoid too much hacks in the project ;) – goemic Dec 10 '20 at 09:17
  • it is definetly surprising that is the reason why I posted this question :D I think it is somehow related to the jdk version used in CI's docker image.. – goemic Dec 10 '20 at 09:19
  • @goemic - Co-incidentally, I was also updating the answer at the same time while you posted this comment :). I will wait for an update from you when the problem gets resolved. Even if my answer doesn't work for you, I suggest you post your own working solution which will be helpful to future visitors. – Arvind Kumar Avinash Dec 10 '20 at 09:27
  • it is indeed related to the jdk version but has nothing to do with a potential fallback to `java.time`. ThreeTen Android Backport is properly setup for the unit test. – goemic Dec 10 '20 at 14:50