Be aware of the Date and Time Format in Android.
This blog is about a bug that can crash your app that you may not even consider.
I was developing an application. Everything was working as expected, and I was happy until I made some test releases and encountered crashes in some testing devices.
Hopefully, I already integrated firebase crashlytics. Guess what, the bug was happening in the date parsing section of the code:
fun parseDate(date: Long): String {
val format = DateFormat.getDateTimeInstance()
format.timeZone = TimeZone.getDefault()
return format.format(date * 1000).toString()
}
Ps: date comes from an API, and its format is in the epoch format.
Nothing odd happened until I used this to show users a portion of the date.
Text(
text = parseDate(someData.aDateTimeValue).getDate()
)
fun String.getDate(): String {
return this.split(" ").subList(0,3).joinToString(" ")
}
Did you guess the problem?
Let me explain:
The real problem is that some people prefer a 12-hour time format, and some others a 24-hour format on their devices. And by using getDateTimeInstance()
, you are converting to the device format. This is what the java doc says:
Gets the date/time formatter with the default formatting style for the default FORMAT locale.
And when you take a sublist of the wrong formatted string, you sometimes encounter the IndexOutOfBoundsException
.
How to fix this?
Instead of using DateFormat
, use SimpleDateFormat
and mention the format to which you want to cast the date. For instance, I changed the parseDate function to the following:
fun parseDate(date: Long): String {
val format = SimpleDateFormat("MMM dd, YYYY hh:mm:ss a")
format.timeZone = TimeZone.getDefault()
return format.format(date * 1000).toString()
}
⚠️ Note: This is a critical bug you may cause in production that causes App Crash. Also, It has a test scenario that one may not consider.
Best of luck with your bug tracking.