Рубрики
Без рубрики

ГГГГ против гггг – День, когда форматер даты Java повредил мой мозг

Даты вступления в программирование – это сложно. Стандарт даты ISO-8601 сделал их проще, но так и должно быть… Помеченный java, json, iso, датами.

Даты в программировании – это сложно. Стандарт даты ISO-8601 упростил их, но, честно говоря, я не сертифицирован по стандарту ISO-8601 так что я не очень хорошо справляюсь со своей работой. Однако что я знаю, так это очень важное различие между ГГГГ и гггг при форматировании дат.

В соответствии с документами Java DateTimeFormatter (которые реализуют спецификацию ISO-8601)

  • y (в нижнем регистре) – год
  • Y (в верхнем регистре) означает “год, основанный на неделе”.

Эта разница приведет к тому, что ваш код будет работать совершенно нормально, за исключением случаев, когда речь идет о датах в самом конце нескольких лет.

Вот пример, с которым я имел абсолютное УДОВОЛЬСТВИЕ иметь дело в прошлом году. На дату 31/12/2019 (31 декабря 2019 года) гггг выйдет 2019 год но ГГГГ выйдет в 2020 году. Причина этого в том, что неделя, на которую приходится 31 декабря, технически является первой неделей 2020 года. Эту проблему может быть трудно заметить и отладить. В моем случае 31/12/2019 отправлялся с внешнего интерфейса, правильно сохранялся в БД, но при возврате превращался в 31/12/2020, и никто понятия не имел, почему. Виновником был наш форматировщик данных JSON по умолчанию, использующий ГГГГ где он должен был использовать гггг (некоторые неуклюже скопировали и вставили быстрое решение самостоятельно, конечно).

Объявлять форматеры

// y (Lowercase) 
DateTimeFormatter formatteryyyy = DateTimeFormatter.ofPattern("yyyy-MM-dd");
// Y (Uppercase)
DateTimeFormatter formatterYYYY = DateTimeFormatter.ofPattern("YYYY-MM-dd");

При преобразовании даты в строку

// Contains value from Database (December 31st 2019) 
LocalDateTime dateTime;

// String value will be 2019-12-31
String yyyy = dateTime.format(formatteryyyy);

// String value will be 2020-12-31
String YYYY = dateTime.format(formatterYYYY);

При преобразовании из строки в дату

// Actual date value will be 2020-12-31
LocalDateTime parsedDateyyyy = LocalDateTime.parse("2020-12-31", formatteryyyy); 

// Actual date value will be 2019-12-31
LocalDateTime parsedDateYYYY= LocalDateTime.parse("2020-12-31", formatterYYYY);  

В 99% случаев верно следующее:

  • гггг хорошо
  • ГГГГ плохо

Оригинал: “https://dev.to/shane/yyyy-vs-yyyy-the-day-the-java-date-formatter-hurt-my-brain-4527”