Как стать автором
Обновить

SimpleDateFormat YYYY против yyyy

Привет всем!

Это мой первый пост на Хабре и он связан с форматом года в SimpleDateFormat в мире Android.

Предыстория

При разработки очередной фичи я написал экстеншен функцию расширяющую возможности класса Date.

@Throws(IllegalArgumentException::class)
fun Date.toString(pattern: String): String {    
	val simpleDateFormat = SimpleDateFormat(pattern, Locale.getDefault())    
	return simpleDateFormat.format(this)
}

По "счастливой" случайности, при использовании данного экстеншена, я написал формат года капсом.

textOperationDateTime.text = date.toString(pattern = "dd MMMM YYYY, HH:mm")

При тестировании никаких проблем обнаружено не было и данный код пошел в продакшн.

Проблема

В один прекрасный день на мою почту приходит письмо из Firebase c сообщением о массовых сбоях в приложении, а сбои связаны как раз с моим экстеншеном Date.toString.

Ошибка гласит, что используется неизвестный символ в паттерне.

java.lang.IllegalArgumentException: Unknown pattern character 'Y'

В чем же проблема и почему при тестировании не было этих сбоев?

А проблема в том, что существует разница между YYYY и yyyy:

1. Оба они представляют год, но yyyy представляет календарный год, а YYYY представляет год недели.

var date = SimpleDateFormat("yyyy-MM-dd").parse("2018-12-01")
date.toString("YYYY") //результат: 2018
date.toString("yyyy") //результат: 2018

date = SimpleDateFormat("yyyy-MM-dd").parse("2018-12-31")
date.toString("YYYY") //результат: 2019
date.toString("yyyy") //результат: 2018

2. YYYY появился в java 8 и поддерживается только в Android >= api 24

Запускаем на Android 7 или выше

var date = SimpleDateFormat("yyyy-MM-dd").parse("2018-12-01")
date.toString("YYYY") //результат: 2018
date.toString("yyyy") //результат: 2018

date = SimpleDateFormat("yyyy-MM-dd").parse("2018-12-31")
date.toString("YYYY") //результат: 2019
date.toString("yyyy") //результат: 2018

обратите внимание на 6-ую строчку кода.

Запускаем на Android 6 или ниже

var date = SimpleDateFormat("yyyy-MM-dd").parse("2018-12-31")
date.toString("YYYY") //результат: java.lang.IllegalArgumentException: Unknown pattern character 'Y'
date.toString("yyyy") //результат: 2018

обратите внимание на 2-ую строчку кода.

А сбоев при тестировании не было из-за того, что данный блок не тестировался на устройствах с Android ниже 7 версии.

Итог

И в итоге мы должны помнить, что почти всегда нужно использовать формат года yyyy, а про YYYY нужно знать и при специфичных требованиях логики отображения года использовать этот формат.

Будьте внимательны и не совершайте мою ошибку!

Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.