[Alarmy Android] Handling One-Letter DayOfWeek Localization

*This post was originally organized on Notion and presented at a Town Hall meeting before being moved to Medium.
DelightRoom's avatar
Jul 14, 2020
[Alarmy Android] Handling One-Letter DayOfWeek Localization

*This post was originally organized on Notion and presented at a Town Hall meeting before being moved to Medium.

TL;DR

  • After the Android redesign, we started displaying days of the week as a single letter, but this caused an issue making it hard to select days in certain languages.

  • This is being resolved starting from 4.27.50-beta.

  • I still have lingering regrets that if I had just done the manual grunt work using strings.xml, it would have been finished faster and more accurately.

Background

Previously, the Android Editor screen used to show a list in a pop-up like iOS, but after the redesign was completed, we started displaying days of the week as a single letter.

How It All Started

Jayde making an appearance once again

Along with praise that the redesign was great, we received user feedback that it would be better if Tuesday in Spanish was represented by a K.

However, the way we displayed days of the week relied on what a library provided.

The library we were using was ThreeTen Android Backport created by JakeWharton.

Here, ThreeTenABP is a backport library for using java.time.* available in Java 8, and before Android Gradle plugin 4.0 came out, we were using it so we could use java.time.* on lower Android API versions (25 and below).

The OS clock app (Google) also displays it as D L M M J V S!

The Android improvement feedback we received above was an issue that would be solved once the library got updated, and since there was no major issue with actual usability, we decided to just keep it as is.

But then,

Chan, like a detective, discovered that something was wrong with Chinese.

(-Since it's a mission alarm app-) setting the days is a mission in itself

From this point on, I could no longer blame the library and had reached the point where I had to fix the problem myself. -JakeWharton, why are you putting me through this ordeal...-

Previously, I was outputting the value using DayOfWeek.MONDAY.getDisplayName(TextStyle.NARROW_STANDALONE, Locale.getDefault()).

Here, for TextStyle, you can broadly use FULL (entire word), SHORT (typically 3 letters), and NARROW (minimum unit).
ex) Full - Monday, Short - Mon., Narrow - M

During my search for a solution, I found that someone had already submitted a Report on the Library Issue, and towards the end of that thread, I confirmed that the code was merged and the issue was marked as closed.

I happily expected that if I just bumped it up to the latest version, all problems would be solved with a magical 'ta-da!'.

However, after checking the code myself, it was simply grabbing the first letter from the full word of the day using substring(0, 1), and only adding an exception if it was Chinese.

While giving up on this method and looking into other alternatives, I confirmed that using 3 letters via SHORT caused no problems in conveying the meaning. The only issue, if any, was that the display length varied slightly by language.

But since there was no issue grasping the meaning, I made a sharp pivot to convince Bom in the Design Group to change it to 3 letters and release it with just a slight design tweak. (-It’s definitely not because I got exhausted from investigating technically-)

So I actively persuaded Bom and considered widening the margins of the day buttons a bit before releasing it, but then came two arguments that were hard to refute.

I decided to sort of drop the 3-letter argument and, while brainstorming the simplest way to fix this, I came up with the idea of utilizing strings.xml.

Managing the days of the week by utilizing strings.xml in a format like R.string.monday had the advantage of cleanly handling all translations and allowing us to customize the string exactly the way Alarmy wanted, but it required manual grunt work in that we ultimately had to support every single language that was currently localized.

So I needed to lock in a decision with the Design Group and the POM Group: whether to go with 3 letters, prioritize supporting 6 languages (English, Korean, Spanish, Chinese, Japanese) and sequentially add the rest, or just grind it out manually from the start and release all of them at once.

Around quitting time on Wednesday, we decided to discuss it on Thursday, and I figured I'd consider looking for another technical solution before the meeting.

Android Studio 4.0

I spent all day searching for nothing but day of week.

I did so much searching and tried so many things that I don't exactly remember what the whole process was like,

But somehow I ended up giving it a shot, and I confirmed that utilizing java.time.* instead of org.threeten.bp.* made the Narrow case work normally.

Then there was some good news from Android Studio 4. Java 8 Language library desugaring in D8 and R8 If you update to Android Studio 4, you can use java.time.* without a backport!

With a pounding heart, I referenced the developer guide doc and applied desugaring.

It really felt like the result was going to pop out magically without me having to use the manual grunt work method.

I waited for the build, excitedly set the language to Catalan, and looked at the result!!!

I was right back where I started. (-Does that d stand for dumb?-)

It displayed properly on the latest Android, but I found that the translation still didn't work on Android 6.0.

I started to suspect that maybe ThreeTenABP was being used under the hood where Java 8 couldn't be used.

Conclusion

After this, there was a whole lot of messing around, research, and despair, but since you're probably getting bored, I'll just skip to the conclusion.

I solved it by utilizing java.time.DayOfWeek to show the days for SDK 26 and above, and for anything below SDK 26, I calculated and displayed the dates by combining SimpleDateFormat("EEEEE") and java.util.Calendar.

To the question of whether there wouldn't be any issues just unifying it under the sub-SDK 26 case, I decided to use DayOfWeek because it is a managed library provided by Java, and I expected it to be stable.

Also, since it involved logic that calculates the date using SimpleDateFormat, I wasn't sure what side effects that might bring, so I chose the method of branching the logic.

I'm proud of it, so let's look at the results. (Heavy scrolling ahead + there's a little bit left at the end.)

Korean, which always outputted perfectly
Spanish
Chinese
Catalan
Hebrew
Zulu

Is That the End?

I thought it was the end. I ran a Release Build. A problem occurred.

On Android 4, a symptom appeared where the app would crash as soon as it launched.

I couldn't pinpoint the exact cause, but downgrading com.android.tools.build:gradle from 4.0.0 back to the 3.x.x series and turning off coreLibraryDesugaringEnabled fixed it.

But this time, a weird symptom appeared on SDK 26 and above where the days of the week I had painstakingly localized were suddenly displayed as numbers.

Painstakingly localized them, only to have them globally unified into numbers

At this point, I felt regret, thinking it would have been safer and faster to just have everyone do the manual grunt work and add them to Strings, but there was hope in the code meant for sub-SDK 26.

If I searched further, it felt like the issue with days showing up as numbers could be easily fixed too, but since other tasks were piled up, I logged it as a TODO (and thus created another piece of legacy code) and wrapped it up by applying the Calendar and SimpleDateFormat combo I wrote for sub-SDK 26 across the board regardless of Android version.

If trying not to be stupid still makes you stupid in the end!

Wrapping Up

  • This has been rolling out starting from 4.27.50-beta. (Live testing)

  • I realized the need to check localization designs while developing.

  • This whole thing started with a request to change Spanish from D L M M J V S > D L K M J V S. (I couldn't solve it. I should've just done the manual grunt work with strings...)

  • I still can't shake the thought that there might be a bunch of much simpler ways to do this.

  • After dropping Android 4, I'm starting to suffer from Android 5 and 6.

  • It ain't over till it's over.

You can read more posts on our 'Brunch Magazine'.

Share article