Новогодний баг форматирования даты, вы столкнулись с ним неожиданно?

Java

Перед наступлением 2020 года операция форматирования даты также подготовила новый баг уровня года для программистов.Интересно, сталкивалась ли с этим ваша система?

В дни, приближающиеся к Новому году в 2020 году, на многих веб-сайтах отображаются даты, такие как 2020/12/29, 2020/12/30 и 2020/12/31. Удивительно, не так ли? Даже инструмент помощника по подписке, предоставляемый WeChat, имеет такую ​​​​ошибку.

Следующие две картинки — это скриншоты официального аккаунта «Program New Horizon» в помощнике по подписке аккаунта от 31 декабря.

Добавлена ​​часть содержимого отображения времени фанатов.

image

Часть содержимого отображения времени в области комментариев.image

На картинке выше время, отображаемое новыми фанатами, и время комментариев — «2020/12/31». Итак, давайте разберем причины этого бага. Пример стоит тысячи слов, давайте воспользуемся примером, чтобы исправить эту ошибку.

Пример 1, пример восстановления:

public class DateFormatBug {

    public static void main(String[] args) throws ParseException {
        // 示例一
        printBugDate();
    }

    private static void printBugDate() throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
        Date date = sdf.parse("2020-1-1 13:12:12");
        System.out.println(date);
        String dateStr = sdf.format(date);
        System.out.println(dateStr);
    }
}

Угадайте, какой результат будет напечатан в первой и второй строках? Это умно, если вы угадаете одно верно, потому что, как упоминалось выше, этот экземпляр является уменьшением количества ошибок.

Журнал печати:

Sun Dec 29 13:12:12 CST 2019
2020-12-29 13:12:12

Удивительно, не так ли? Разберите строку «2020-1-1 13:12:12» на дату и распечатайте ее как 29 декабря 2019 года! ! ! А потом дата обработки превратилась в 2020-12-29! Полная лажа, мы хотим дату 2020-1-1.

Пример второй, расширенный пример:

private static void printBugDateExtend() throws ParseException {
    SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
    Date date = sdf.parse("2019-12-31 13:12:12");
    System.out.println(date);
    String dateStr = sdf.format(date);
    System.out.println(dateStr);
}

На этот раз я просто изменил дату с 2020-1-1 на 2019-12-31, угадайте, каков результат печати? Гарантированно не угадаешь. Вот результат печати:

Sun Dec 30 13:12:12 CST 2018
2019-12-30 13:12:12

30 декабря 2018? На этот раз даже год неверный.

Ну не будем продавать, если у вас в IDE установлен плагин руководства по эксплуатации Alibaba. Вы обнаружите, что "ГГГГ-ММ-дд ЧЧ:мм:сс" уже содержит подсказку. Точно так же, если вы откроете новую версию (Huashan Edition) Руководства по разработке Java для Alibaba, эта проблема будет четко объяснена.

image

Итак, где я могу получить новую версию «Руководства по разработке Java для Alibaba»? Друзья, которые подписаны на официальный аккаунт «Program New Horizon», просто ответьте «005», чтобы получить PDF-версию. В новом году полезно читать руководства по разработке крупных производителей, учиться на собственном опыте и не наступать на ямы. Конечно, обратить внимание на публичный аккаунт, чтобы продолжить обучение, — еще один хороший выбор.

В то же время вы также можете обратиться к описанию недели на основе года в javadoc, Соответствующие ссылки следующие: https://docs.oracle.com/javase/8/docs/api/java/time/ временной/WeekFields.html

A week is defined by:

(1) The first day-of-week. For example, the ISO-8601 standard considers Monday to be the first day-of-week.

(2) The minimal number of days in the first week. For example, the ISO-8601 standard counts the first week as needing at least 4 days.

Together these two values allow a year or month to be divided into weeks.

Подводя итог: в недельном году каждая неделя принадлежит только одному году. Первая неделя года обязательно должна начинаться с первого дня недели, а количество дней должно быть больше 4 дней (минимальное количество дней), поэтому конкретный год новогодней недели зависит от конкретного ситуация.

Но в любом случае лучше всего не использовать заглавную букву «Y» для обозначения года.

Лучше не иметь книги, чем верить в книгу Мы изменим «Y» в коде на «y» и выполним его снова, чтобы увидеть эффект.

private static void printDate() throws ParseException {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date date = sdf.parse("2020-1-1 13:12:12");
    System.out.println(date);
    String dateStr = sdf.format(date);
    System.out.println(dateStr);
}

private static void printDateExtend() throws ParseException {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date date = sdf.parse("2019-12-31 13:12:12");
    System.out.println(date);
    String dateStr = sdf.format(date);
    System.out.println(dateStr);
}

Результат печати выглядит следующим образом:

Wed Jan 01 13:12:12 CST 2020
2020-01-01 13:12:12
Tue Dec 31 13:12:12 CST 2019
2019-12-31 13:12:12

Судя по всему, эта новогодняя ошибка исправлена.

После этого вопроса подумаем над вопросом: в чем разница между мастером и новичком? Пожалуй, на поставленный выше вопрос можно ответить.То же самое и с форматом даты.В нормальных условиях оба способа записи могут нормально работать,и отличить экспертов от новичков невозможно. И только в крайних случаях в какой-то момент времени можно увидеть высоту мастера.

Так откуда взялись мастера? выпрыгнул из ямы. Может быть, он попал и вышел раньше вас, может быть, у него была «неожиданная встреча», когда он прочитал много книг, а может, он просто увидел эту статью, как вы сейчас.

Оригинальная ссылка: "Новогодняя ошибка, вы столкнулись с ней неожиданно?


Программа Новые Горизонты: Захватывающие и растущие нельзя пропустить

程序新视界-微信公众号