J
Java | Фишки и трюки
@java_tips_and_tricks7.0K подп.
1.8Kпросмотров
25.3%от подписчиков
17 февраля 2026 г.
Score: 1.9K
📅 LocalDate и DateTimeFormatter: вечная путаница с YYYY и yyyy Каждый Новый год эта ошибка просыпается и незаметно портит данные в логах, отчётах и экспортах. Разница между YYYY и yyyy - всего одна буква, но она может сдвинуть дату на целый год вперёд или назад в первую неделю января. Вот как не попасть в эту ловушку и почему это происходит 👇 📁 Шаг 1: Наглядный пример ошибки (31 декабря 2024 года) DateTimeFormatter wrongFormatter = DateTimeFormatter.ofPattern("dd.MM.YYYY"); DateTimeFormatter correctFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy"); LocalDate date = LocalDate.of(2024, 12, 31); System.out.println("Неправильно (YYYY): " + date.format(wrongFormatter)); // 31.12.2025 ← вот он, сдвиг на год! System.out.println("Правильно (yyyy): " + date.format(correctFormatter)); // 31.12.2024 ➡️ Да, 31 декабря 2024 года форматируется как... 2025 год. Это не баг, а фича, о которой мало кто знает. 📁 Шаг 2: В чём разница? (Год vs Год недели) - yyyy — это обычный календарный год (year-of-era). То, что мы все понимаем под годом. - YYYY — это год недели (week-based-year) по стандарту ISO 8601. ➡️ YYYY используется вместе с номером недели (ww) и днём недели (E). Он нужен для отображения года, к которому относится неделя, а не календарная дата. 📁 Шаг 3: Почему происходит сдвиг? (Магия первой недели года) По ISO 8601: 1. Неделя начинается с понедельника. 2. Первая неделя года — это неделя, содержащая первый четверг года. 3. Год недели (YYYY) — это год, к которому относится эта неделя. // Пример: 1 января 2025 года — это среда LocalDate jan1 = LocalDate.of(2025, 1, 1); System.out.println("Год недели: " + jan1.format(DateTimeFormatter.ofPattern("YYYY"))); // 2025 — потому что неделя (30 дек - 5 янв) содержит первый четверг 2025 года (2 января) // А 30 декабря 2024 года — это понедельник, начало недели 1 (2025 года!) LocalDate dec30 = LocalDate.of(2024, 12, 30); System.out.println("Год недели: " + dec30.format(DateTimeFormatter.ofPattern("YYYY"))); // 2025 — потому что эта неделя (30 дек - 5 янв) содержит первый четверг 2025 года ➡️ Критические периоды: последние 3-4 дня декабря и первые 3-4 дня января. Именно здесь YYYY и yyyy чаще всего расходятся. 📁 Шаг 4: Где используется YYYY (правильно) Только вместе с номером недели! // Для отображения номера недели и года недели (отчёты, планирование) DateTimeFormatter weekFormatter = DateTimeFormatter.ofPattern("'Неделя' ww, YYYY"); LocalDate date = LocalDate.of(2024, 12, 30); System.out.println(date.format(weekFormatter)); // "Неделя 01, 2025" ← это правильно для систем, работающих по неделям ➡️ Используй YYYY только если ты точно понимаешь, что такое год недели, и используешь его с ww (номер недели). 📁 Шаг 5: Где НЕЛЬЗЯ использовать YYYY (опасные случаи) 1. Логирование — дата в логах внезапно станет 2025 годом 30 декабря. 2. Экспорт в CSV/Excel для отчётности. 3. Формирование имён файлов с датами. 4. Любые даты, которые потом будут парситься обратно. // ❌ Опасный парсинг (может сломаться) String wrong = "31.12.2024"; LocalDate parsed = LocalDate.parse(wrong, DateTimeFormatter.ofPattern("dd.MM.YYYY")); // Может выкинуть исключение или спарсить не ту дату 📁 Шаг 6: Как избежать ошибки навсегда 1. Используй готовые форматеры вместо ручных паттернов: DateTimeFormatter.ISO_LOCAL_DATE; // yyyy-MM-dd DateTimeFormatter.BASIC_ISO_DATE; // yyyyMMdd 2. Пиши тесты на граничные даты: @Test void dateFormatting_aroundNewYear() { LocalDate dec30 = LocalDate.of(2024, 12, 30); LocalDate jan1 = LocalDate.of(2025, 1, 1); assertThat(dec30.format(DateTimeFormatter.ofPattern("dd/MM/yyyy"))) .isEqualTo("30/12/2024"); assertThat(jan1.format(DateTimeFormatter.ofPattern("dd/MM/yyyy"))) .isEqualTo("01/01/2025"); } 3. Включи в code review проверку всех DateTimeFormatter на наличие YYYY. 🗣️ Запомни: YYYY - это не опечатка, а отдельная концепция. Используй yyyy для всего, что связано с календарными датами.
1.8K
просмотров
4000
символов
Нет
эмодзи
Нет
медиа

Другие посты @java_tips_and_tricks

Все посты канала →
📅 LocalDate и DateTimeFormatter: вечная путаница с YYYY и y — @java_tips_and_tricks | PostSniper