Moshe Katz
Moshe Katz

Reputation: 16873

Calendar getDisplayName for weekday gives different output in different Android versions

I am consuming an API that returns the opening hours of various businesses.

Hours come to me in this form:

[
  { "day": "monday", "isOpen": true, "open": "09:00", "close": "15:00"},
  { "day": "tuesday", "isOpen": true, "open": "09:00", "close": "15:00" },
  { "day": "wednesday", "isOpen": true, "open": "09:00", "close": "15:00" },
  { "day": "thursday", "isOpen": true, "open": "09:00", "close": "15:00" },
  { "day": "friday", "isOpen": true, "open": "09:00", "close": "15:00" },
  { "day": "saturday", "isOpen": false, "open": "", "close": "" },
  { "day": "sunday", "isOpen": false, "open": "", "close": "" },
]

I have the following function that is supposed to get today's hours from the list and display them (the DaySchedule type is a data class made from the data structure above):

fun todayWorkingHours(schedule: List<DaySchedule>): String {
    val cal = Calendar.getInstance()
    val todayDay = cal.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.ROOT)!!.toLowerCase(Locale.ROOT)
    val workSchedule = schedule.find { it.day == todayDay }
        ?: return context.getString(R.string.non_working_day)

    if (workSchedule.isOpen) {
        val open = workSchedule.open
        val close = workSchedule.close
        return "${currentDay.capitalize(Locale.getDefault())}: $open - $close"
    }

    return "${currentDay.capitalize(Locale.getDefault())}: " + context.getString(R.string.non_working_day)
}

I have Android devices running version 7 (Samsung Galaxy S6) and 11 (Google Pixel 3a) to test with. On v7, this code works perfectly. However, on v11, it always returns the message in R.string.non_working_day.

Using the debugger, I determined that the problem is in the second line of the function:

How can I get all versions of Android to give me the full name of the day?


I also tried using the newer java.time API (with coreLibraryDesugaringEnabled for older OS versions):

val todayDay = DayOfWeek.from(LocalDate.now()).getDisplayName(TextStyle.FULL, Locale.ROOT).toLowerCase(Locale.ROOT)

It does the same thing - it gives the correct "tuesday" on older versions and the incorrect "tue" on Android 11. While I could find little documentation about the older Calendar classes, the Android docs for java.time.format.TextStyle explicitly say that TextStyle.LONG should be giving me the full month name.

Upvotes: 0

Views: 211

Answers (1)

Moshe Katz
Moshe Katz

Reputation: 16873

Apparently there is a bug in Locale.ROOT. Switching to Locale.ENGLISH makes it work properly, and I know that the server will always be using English.

Thanks to @MatPag for the hint of what direction to look.

Upvotes: 1

Related Questions