Before 2020, date formatting also creates a cross-grade bug for programmers. I wonder if your system has encountered one?

Near New Year of 2020 days, a lot of website appeared similar 2020/12/29 2020/12/30, 2020/12/31 such date display. Magic is not? Even the subscription assistant tool provided by wechat has such an error.

The following two pictures are screenshots from the subscription account “Program New Horizon” on December 31.

Added part of the fan time display.

Part of the time shown in the comment section.

In the image above, the new fans show the time and the comment time is “2020/12/31.” So, let’s analyze the cause of this bug. Example is worth a thousand words, first use an example to restore this bug.

Example 1, restore example:

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); }}Copy the code

Guess what the results of the first and second printed lines are respectively? It would be wise to guess a note correctly, as stated above, for this example to restore the bug.

The following logs are displayed:

Sun Dec 29 13:12:12 CST 2019
2020-12-29 13:12:12Copy the code

Magic is not? Parse the string “2020-1-1 13:12:12” into a date and print it out as December 29, 2019!! Then the date processing turned into 2020-12-29! This is all messed up. We want 2020-1-1.

Example 2, the extended example:

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); }Copy the code

This time just changed the date from 2020-1-1 to 2019-12-31 and guess what the print was? You won’t guess. Here is the printout:

Sun Dec 30 13:12:12 CST 2018
2019-12-30 13:12:12Copy the code

December 30, 2018? The year was wrong this time.

Well, no suspense, if your IDE installed on the Alibaba manual of operation of the plug-in. You will notice that “YYYY-MM-DD HH: MM :ss” has a prompt message. Similarly, if you open the new (Huashan edition) Alibaba Java Development manual, this issue has been clearly explained.

So where can I get the new version of the Alibaba Java Development Manual? Friends who follow the public account “Program New Horizon”, just reply “005” to get the PDF version. New Year, have no matter to see the development manual of big factory, draw lessons from experience, avoid stepping pit is also good. Of course, follow the public number continuous learning is another good choice.

At the same time, also can see the javadoc for the week – -based – year shows that the link is as follows: https://docs.oracle.com/javase/8/docs/api/java/time/temporal/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.Copy the code

To summarize: in week-based years, each week belongs to only one year. The first week of a year must start on the first day of the week and the number of days must be greater than the minimum number of days. Therefore, the specific year of the New Year week depends on specific circumstances.

In any case, it’s best to avoid using a capital “Y” for the year.

Let’s change the “Y” in the code to “Y” and run it again to see what happens.

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);
}Copy the code

The print result is as follows:

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:12Copy the code

Apparently, the New Year’s Eve bug has been fixed.

After this problem, whether we will think about a question: where is the difference between the master and the novice? Perhaps the above questions can be answered, the same is the date format, in normal circumstances both writing can be normal operation, unable to distinguish between the master and novice. And only in a certain moment in some extreme circumstances to see the high master.

So where do the masters come from? He jumped out of the pit. Maybe he fell in and got out before you did, or maybe he read a lot and had a “chance encounter,” or maybe he just read this article like you do.

New Year’s Eve Bug, did I run into you by accident?


New horizons for programs