This is the 10th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”
❤️ About the author: Hello everyone, I am Xiao Xu Zhu. Java field quality creator 🏆, CSDN blog expert certification 🏆, Huawei Cloud enjoy expert certification 🏆
❤️ technology live, the appreciation
❤️ like 👍 collect ⭐ look again, form a habit
Before reading this article, it is recommended to have some knowledge of the date and time of Java source code. If not, you can read this article first:
Swastika blog teaches you to understand Java source code date and time related usage
Related articles:
Hutool actual combat (take you to master the various tools) directory
5hutool Combat :DateUtil- Parse the time that was formatted
Source code analysis purposes
Know what it is and why
Project reference
The basis of this blog: Hutool -5.6.5 version of the source code
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>5.6.5</version>
</dependency>
Copy the code
The method name: DateUtil. ParseLocalDateTime (Java. Lang. CharSequence)
Methods described
Construct LocalDateTime object format: YYYY-MM-DD HH: MM: SS
Source code Analysis 1
/** * Build the LocalDateTime object **@paramDateStr Time string (formatted) *@paramUse the format {@linkDatePattern} defines the format *@returnLocalDateTime object * /
public static LocalDateTime parseLocalDateTime(CharSequence dateStr, String format) {
return LocalDateTimeUtil.parse(dateStr, format);
}
Copy the code
ParseLocalDateTime (CharSequence dateStr, String format) the format of the method must use the format defined by DatePattern to ensure that it can be parsed.
**LocalDateTimeUtil.parse(dateStr, format)** localDateTimeUtil.parse (dateStr, format)** localDateTimeUtil.parse (dateStr, format)
//LocalDateTimeUtil
/** * parses the date and time string as {@link LocalDateTime}
*
* @paramText Date time character string *@paramFormat The date format, similar to YYYY-MM-DD HH: MM :ss,SSS *@return {@link LocalDateTime}
*/
public static LocalDateTime parse(CharSequence text, String format) {
if (null == text) {
return null;
}
DateTimeFormatter formatter = null;
if(StrUtil.isNotBlank(format)){
// Fix a problem where the yyyyMMddHHmmssSSS format cannot be resolved
// fix issue#1082
//see https://stackoverflow.com/questions/22588051/is-java-time-failing-to-parse-fraction-of-second
// jdk8 bug at: https://bugs.openjdk.java.net/browse/JDK-8031085
if(StrUtil.startWithIgnoreEquals(format, DatePattern.PURE_DATETIME_PATTERN)){
final String fraction = StrUtil.removePrefix(format, DatePattern.PURE_DATETIME_PATTERN);
if(ReUtil.isMatch("[S] {1, 2}", fraction)){
// Replace the yyyyMMddHHmmssS and yyyyMMddHHmmssSS dates into the yyyyMMddHHmmssSSS format with 0
text += StrUtil.repeat('0'.3-fraction.length());
}
formatter = new DateTimeFormatterBuilder()
.appendPattern(DatePattern.PURE_DATETIME_PATTERN)
.appendValue(ChronoField.MILLI_OF_SECOND, 3)
.toFormatter();
} else{ formatter = DateTimeFormatter.ofPattern(format); }}return parse(text, formatter);
}
Copy the code
Comments in writing to repair the JDK8 a bug bugs.openjdk.java.net/browse/JDK-…
Try:
@Test
public void localDateTimeTest5(a) {
String strDate = "20210805220359100";
DateTimeFormatter formatter =DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
System.out.println(formatter.parse(strDate));
}
Copy the code
It really does get an error.
There was an official solution, but it was fixed in java9. Put it in the 8U version.
Fix yyyyMMddHHmmssSSS format not parsing
//LocalDateTimeUtil
/** * parses the date and time string as {@link LocalDateTime}
*
* @paramText Date time character string *@paramFormat The date format, similar to YYYY-MM-DD HH: MM :ss,SSS *@return {@link LocalDateTime}
*/
public static LocalDateTime parse(CharSequence text, String format) {... formatter =new DateTimeFormatterBuilder()
.appendPattern(DatePattern.PURE_DATETIME_PATTERN)
.appendValue(ChronoField.MILLI_OF_SECOND, 3) .toFormatter(); .return parse(text, formatter);
}
Copy the code
Parse (text, formatter) is finally called;
/** * parses the date and time string as {@linkLocalDateTime}, the format can be date time, date, time * *@paramText Date time character string *@paramDate formatter, predefined format see: {@link DateTimeFormatter}
* @return {@link LocalDateTime}
*/
public static LocalDateTime parse(CharSequence text, DateTimeFormatter formatter) {
if (null == text) {
return null;
}
if (null == formatter) {
return LocalDateTime.parse(text);
}
return of(formatter.parse(text));
}
Copy the code
The first good habit is to check whether the input parameter is null.
LocalDateTime.parse(text)// Return the LocalDateTime object
DateTimeFormatter.parse(text)// Return the TemporalAccessor object
Copy the code
These are new apis for java8:
Swastika blog teaches you to understand Java source code date and time related usage
Finally, use **of(TemporalAccessor)** to convert to a LocalDateTime time object
First, TemporalAccessor:
The TemporalAccessor implementation class contains
- Instant
- LocalDateTime
- ZonedDateTime
- OffsetDateTime
- LocalDate
- LocalTime
- OffsetTime
public static LocalDateTime of(TemporalAccessor temporalAccessor) {
if (null == temporalAccessor) {
return null;
}
if(temporalAccessor instanceof LocalDate){
return ((LocalDate)temporalAccessor).atStartOfDay();
}
return LocalDateTime.of(
TemporalAccessorUtil.get(temporalAccessor, ChronoField.YEAR),
TemporalAccessorUtil.get(temporalAccessor, ChronoField.MONTH_OF_YEAR),
TemporalAccessorUtil.get(temporalAccessor, ChronoField.DAY_OF_MONTH),
TemporalAccessorUtil.get(temporalAccessor, ChronoField.HOUR_OF_DAY),
TemporalAccessorUtil.get(temporalAccessor, ChronoField.MINUTE_OF_HOUR),
TemporalAccessorUtil.get(temporalAccessor, ChronoField.SECOND_OF_MINUTE),
TemporalAccessorUtil.get(temporalAccessor, ChronoField.NANO_OF_SECOND)
);
}
Copy the code
First, we know from the above that LocalDate is the implementation class of temporalAccessor. ((LocalDate)temporalAccessor).atstartofDay () this will become localDate.atstartofDay ()
public LocalDateTime atStartOfDay(a) {
return LocalDateTime.of(this, LocalTime.MIDNIGHT);
}
Copy the code
LocalTime.MIDNIGHT:
/** * The time of midnight at the start of the day, '00:00'. */
public static final LocalTime MIDNIGHT;
Copy the code
LocalDateTime is a combination of LocalDate and LocalTime.
public static LocalDateTime of(LocalDate date, LocalTime time) {
Objects.requireNonNull(date, "date");
Objects.requireNonNull(time, "time");
return new LocalDateTime(date, time);
}
Copy the code
TemporalAccessorUtil. Get (temporalAccessor, chronofield.year) this is hutool source, let’s have a look
/** * Returns 0 ** if the attribute does not exist@paramTemporalAccessor Requires the acquisition of time objects *@paramField Specifies the property to obtain *@returnTime, which defaults to 0 */ if not available
public static int get(TemporalAccessor temporalAccessor, TemporalField field) {
if (temporalAccessor.isSupported(field)) {
return temporalAccessor.get(field);
}
return (int)field.range().getMinimum();
}
Copy the code
Determine whether temporalAccessor supports the specified fields, and if so, directly return the time value corresponding to the specified fields. If no, run the command
(int)field.range().getMinimum(), get the minimum value of the field.
System.out.println(ChronoField.YEAR.range().getMinimum());
System.out.println(ChronoField.MONTH_OF_YEAR.range().getMinimum());
System.out.println(ChronoField.DAY_OF_MONTH.range().getMinimum());
System.out.println(ChronoField.HOUR_OF_DAY.range().getMinimum());
System.out.println(ChronoField.MINUTE_OF_HOUR.range().getMinimum());
System.out.println(ChronoField.SECOND_OF_MINUTE.range().getMinimum());
System.out.println(ChronoField.NANO_OF_SECOND.range().getMinimum());
Copy the code
Year specifies the minimum and maximum value set during initialization