Search
Write a publication
Pull to refresh

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 нужно знать и при специфичных требованиях логики отображения года использовать этот формат.

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

Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.