Java8 introduces new time format apis: LocalDateTime, LocalDate, and LocalTime for handling date-time, date, and time, respectively. Using them, we can easily convert dates to strings or parse strings to dates. Let’s take a closer look at the three modes Java provides for String to LocalDateTime. The LocalDateTime parse method is the most commonly used method for converting a String to a date.

public static LocalDateTime parse(CharSequence text) {
	return parse(text, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
}

public static LocalDateTime parse(CharSequence text, DateTimeFormatter formatter) {
	Objects.requireNonNull(formatter, "formatter");
	return formatter.parse(text, LocalDateTime::from);
}
Copy the code

The parse method provides two overloaded methods. Parse (CharSequence Text, DateTimeFormatter formatter) is used as the last call. The key here is DateTimeFormatter. The default resolution rule is datetimeFormatter.iso_local_date_time, which is formatted as follows:

/**
     * The ISO date-time formatter that formats or parses a date-time without
     * an offset, such as '2011-12-03T10:15:30'.
     * The returned formatter has a chronology of ISO set to ensure dates in
     * other calendar systems are correctly converted.
     * It has no override zone and uses the {@link ResolverStyle#STRICT STRICT} resolver style.
     */   
public static final DateTimeFormatter ISO_LOCAL_DATE_TIME;
    static {
        ISO_LOCAL_DATE_TIME = new DateTimeFormatterBuilder()
                .parseCaseInsensitive()
                .append(ISO_LOCAL_DATE)
                .appendLiteral('T')
                .append(ISO_LOCAL_TIME)
                .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
    }
Copy the code

Yyyy-mm-ddthh: MM :ss (the key point here is that the method ends with the resolverstyle. STRICT parameter, which is STRICT mode). This data format is a simplification of ECMAScript based on the ISO 8601 extension format and is common abroad. The format most commonly used is YYYY-MM-DD HH: MM: SS, which is convenient for front-end display. What if you want to convert to this format? We can do this by customizing a DateTimeFormatter.

LocalDateTime parse = LocalDateTime.parse( "The 2021-02-23 08:02:02", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
// Output the result
2021-02-23T08:02:02

LocalDateTime parse = LocalDateTime.parse( "The 2021-02-29 08:02:02", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
// Output the result
2021-02-28T08:02:02
        
Copy the code

If you are careful, you may have noticed that I sent 02-29. Why is the result 02-28? This involves the analysis mode mentioned in this article. First we see DateTimeFormatter. OfPattern source code:

public static DateTimeFormatter ofPattern(String pattern) {
	return new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter();
}

public DateTimeFormatter toFormatter(a) {
	return toFormatter(Locale.getDefault(Locale.Category.FORMAT));
}

public DateTimeFormatter toFormatter(Locale locale) {
	return toFormatter(locale, ResolverStyle.SMART, null);
}

Copy the code

SMART is a SMART mode, and ResolverStyle provides: STRICT, SMART and LENIENT are three modes for date parsing. Let’s discuss the differences between the three modes in detail.

Strict mode

We first define a strict date resolution rule and then use it to parse dates.

    /** * User-defined date format: YYYY-MM-DD HH: MM :ss **/
    public static DateTimeFormatter STRICT_DATE_TIME = new DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .append(ISO_LOCAL_DATE)
            .appendLiteral("")
            .append(ISO_LOCAL_TIME)
            .toFormatter(Locale.CHINESE)
            .withResolverStyle(ResolverStyle.STRICT);

LocalDateTime normal = LocalDateTime.parse( "The 2021-04-30 08:02:02", STRICT_DATE_TIME);
// Output the result
2021-04-30T08:02:02
LocalDateTime normal = LocalDateTime.parse( "The 2021-04-31 08:02:02", STRICT_DATE_TIME);
// Output the result
Caused by: java.time.DateTimeException: Invalid date 'APRIL 31'
Copy the code

As you can see from the code above, strict mode throws an exception directly for invalid dates. You can change other fields as well, and you’ll find that you have to stick strictly to the date and time values, otherwise the conversion will throw an exception.

Intelligent model

    /** * User-defined smart date format: YYYY-MM-DD HH: MM :ss **/
    public static DateTimeFormatter SMART_DATE_TIME = new DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .append(ISO_LOCAL_DATE)
            .appendLiteral("")
            .append(ISO_LOCAL_TIME)
            .toFormatter(Locale.CHINESE);// Default smart mode

    LocalDateTime normal = LocalDateTime.parse( "The 2021-02-29 18:02:02", SMART_DATE_TIME);
	// Output the result
	2021-02-28T18:02:02
    LocalDateTime unnormal = LocalDateTime.parse( "The 2021-04-31 08:02:02", SMART_DATE_TIME);
	// Output the result
	2021-04-30T08:02:02
Copy the code

For invalid dates, smart mode will automatically convert the data to the most recent valid date, but be aware that invalid dates are also regular and beyond the value range of the field can be problematic. You can make a “2021-02-32” format and still throw a DateTimeException.

Loose pattern

    public static DateTimeFormatter LENIENT_DATE_TIME = new DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .append(ISO_LOCAL_DATE)
            .appendLiteral("")
            .append(ISO_LOCAL_TIME)
            .toFormatter(Locale.CHINESE)
            .withResolverStyle(ResolverStyle.LENIENT);

	LocalDateTime normal = LocalDateTime.parse( "The 2021-02-3 2 18:02:02", LENIENT_DATE_TIME);
	// Output the result
	2021-03-04T18:02:02
    LocalDateTime unnormal = LocalDateTime.parse( "2021-13-31 08:02:02", LENIENT_DATE_TIME);
	// Output the result
	2022-01-31T08:02:02
Copy the code

The looser mode requires less data. As long as a number is parsed successfully, it automatically converts an invalid date to a valid date. For example, 13 becomes 12+1, so that 2021 becomes 2022.

To sum up, we can conclude that:

Analytical model The characteristics of
STRICT The time format is the most strict. Only valid time can be parsed
SMART For the expiration date field, can be resolved to the most recent expiration date, commonly with leap year February, and cross-month time format problems
LENIENT For the time format requirements of the most relaxed, as long as the number can be resolved, and will be automatically converted to the effective date, but the date after conversion and before the big difference, with caution!!