0

In an Android project I created the following functions to output a formatted date string:

static final String INPUT_DATE_PATTERN = "yyyy-MM-dd'T'HH:mm:ssZ";

public static long getDateInMilliseconds(String text) {
    Date date = getDate(text, INPUT_DATE_PATTERN);
    return date == null ? 0 : date.getTime();
}

public static String getFormattedDate(long dateInMillisecons) {
    Date date = new Date(dateInMillisecons);
    DateFormat dateFormat = SimpleDateFormat.getDateTimeInstance(
            SimpleDateFormat.FULL, SimpleDateFormat.SHORT);
    return dateFormat.format(date);
}

private static Date getDate(String text, String pattern) {
    SimpleDateFormat dateFormat = new SimpleDateFormat(pattern, Locale.US);
    Date date = null;
    try {
        date = dateFormat.parse(text);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return date;
}

An example value of the text is:

"2016-04-02T09:00:00+02:00"

That means the time zone +02:00 complies with the RFC 822 time zone standard. However, there is no way I can rely on the time zone in the string stays the same - it is served by a remote machine.

Here are two unit tests to check for the desired behavior.

@Test
public void getFormattedDateWithSummerTime() {
    assertThat(DateFormatting.getFormattedDate(1459580400000L))
            .isEqualTo("Saturday, April 2, 2016 9:00 AM");
}

@Test
public void getFormattedDateWithLeapYear() {
    assertThat(DateFormatting.getFormattedDate(1456783200000L))
            .isEqualTo("Monday, February 29, 2016 11:00 PM");
}

The tests pass on my machine. However, when I let the CI build run in the cloud they fail with the following error output:

org.junit.ComparisonFailure:
Expected :"Saturday, April 2, 2016 9:00 AM"
Actual :"Saturday, April 2, 2016 7:00 AM"

org.junit.ComparisonFailure:
Expected :"Monday, February 29, 2016 11:00 PM"
Actual :"Monday, February 29, 2016 10:00 PM"

JJD
  • 50,076
  • 60
  • 203
  • 339
  • Possible hint: add the timezone to the format for a quick test –  Mar 24 '16 at 12:38
  • Please add timezone information. Check the answer [here](http://stackoverflow.com/questions/31796262/java-date-timezone-conversion-from-string-to-date-to-string) – Raghu Nagaraju Mar 24 '16 at 12:47
  • @JJD what is the cause that you found to fix this issue? For me, in mac machine, it's working fine and in ubuntu, it's started failing. – Rameshbabu May 05 '22 at 13:57
  • @Rameshbabu Check if you using different Java version. Try `echo $JAVA_HOME` or `java -version`. The date format changed with Java 9 or at least Java 11. – JJD May 09 '22 at 22:20

1 Answers1

0

The reason for failures is quite simple. If you use DateFormatting.getFormattedDate(1459580400000L)then you actually apply the system timezone (by just setting up a SimpleDateFormat-instance without any explicit timezone).

So you create a formatted string dependent on your system timezone and compare it to a hardwired fixed local representation string of the same time which might be right for your local timezone but not on another system.

Your JUnit-test is not universally applicable. Better compare global timestamps like "elapsed milliseconds since Unix epoch" than compare local representations.

Meno Hochschild
  • 42,708
  • 7
  • 104
  • 126