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.