skip to Main Content

I have a logic to extract the exact time from the given date (e.g: 12:00 PM).

At the end of the logic, I’m using the SimpleDateFormat to parse the date.
When I run the code on the Android devices everything is working fine.
Also when I run the unit tests on my MacBook, windows os, and Bitbucket pipeline all the tests are passed.
But, when I run the unit tests on the MacBook M1-pro 2021 with the same Android studio and codebase one of the tests is failed.

This is the part of the code to format the date:

val output = SimpleDateFormat("hh:mm a")
return output.format(date)

The expected result is something like 12:00 PM which is totally fine in those scenarios I mentioned.

this is the UI on my Android device:

But on the MacBook M1-pro 2021 test fails because the formatter returns the 12:00 p.m.:

expected: 12:00 PM
but was : 12:00 p.m.

This is the result of the unit test on MacBook M1-pro 2021

2

Answers


  1. I would guess that you are implicitly relying on the JVM’s current default locale, and that locale differs between your various test environments.

    Or you are using different versions of Java or Android which have different definitions of the locale rules.

    And, another problem: You are using terrible date-time classes that were years ago supplanted by the modern java.time classes defined in JSR 310.

    The java.time classes are bundled with Java 8+, and with Android 26+. For earlier Android, use the latest tooling to provide most of the java.time functionality via “API desugaring”.

    Convert your legacy java.util.Date class to its replacement java.time.Instant by calling new conversion methods added to the old classes.

    Instant instant = myJavaUtilDate.toInstant() ;
    

    Adjust into your desired time zone.

    ZoneId z = ZoneId.of( "America/Edmonton" ) ;
    ZonedDateTime zdt = instant.atZone( z ) ;
    

    Extract the time portion, the focus of your Question.

    LocalTime lt = zdt.toLocalTime() ;
    

    Automatically localize the output. Specify the Locale explicitly. The Locale determines the human language and cultural norms to apply in localizing.

    Locale locale = Locale.CANADA ;
    DateTimeFormatter f = DateTimeFormatter.ofLocalizedTime( FormatStyle.SHORT ).withLocale( locale ) ;
    String output = lt.format( lt ) ;
    

    Be aware that Java 9 changed its default behavior to use the vastly richer set of locale definitions in the Common Locale Data Repository (CLDR) provided by the Unicode Consortium. This change may result in some differences such as your AM/PM formatting. Also, the CLDR data continues to evolve, so later versions may change some rules.

    Android may also have changed the rules across versions, but I don’t know the history there.

    I suggest you not worry about such minor differences in localized formatting. But if you insist, then you’ll need to:

    • Control for the Locale on which your code depends either implicitly or explicitly.
    • Control for the source and version of the locale rules/definitions
      used by that Locale.
    Login or Signup to reply.
  2. try this

    val currentTime = SimpleDateFormat("hh:mm a", Locale.getDefault()).format(Date())
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search