JAVA8 battle-date API
This is the 9th day of my participation in the August Wen Challenge.More challenges in August
preface
In this section we will look at the date class in JAVA8. The source code is actually written by joda-time, so you can see that many of the apis are similar to the Joda class. Date classes have always been difficult to use, but JAVA8 provides a new set of apis for date classes to make them easier to use.
This article is more code, it is recommended to run the code to understand.
Mind mapping:
Address: www.mubucm.com/doc/ck5ZCrg…
Content Overview:
- JDK8’s three core date classes: LocalDate, LocalTime, and LocalDateTime
- Machine time and date formats
Instant
And other fine – grained time operations - TemporalAdjusters is used for more complex date calculations, such as calculating the next business day. The class provides some implementation
- DateTimeFormatter, very flexible, belongs to
SimpleDateFormat
Substitutes for. - Some personal tool encapsulation examples of the date API, as well as some personal stumbles when using JDK8
Finally, I hope this article can help you get rid of new Date().
What is ISO-8601?
The date cannot be separated from ISO-8601. The following is a brief description of ISO-8601, referring to Baidu Encyclopedia:
- Iso-8601: Date and time representation method developed by the International Organization for Standardization, known as “Data storage and exchange forms, Information Exchange, date and time representation method”, abbreviated as ISO-8601.
- Representation of the day: hours, minutes, and seconds are represented by two digits, with a capital Z at the end of UTC time. Other time zones are represented by the actual time plus the time difference. For example, 2:30pm UTC time is represented as 14:30:05Z or 143005Z. Beijing time at that time is represented as 22:30:05+08:00 or 223005+0800, which can also be simplified to 223005+08.
- The combination of date and time is expressed as follows: add a capital letter T in front of the time. For example, to represent 5:30pm Beijing time on May 3, 2004, it can be written as 2004-05-03T17:30:08+08:00 or 20040503T173008+08.
LocalDate, LocalTime, LocalDateTime
JDK8 splits time into three parts, one is time, which represents the information of year, month and day, one is date, which represents the part of hour, minute and second, and finally, the specific time of the sum of these two objects.
LocalDate
LocalDate: The class represents a specific date, but does not contain a specific time and does not contain time zone information. You can create an instance of LocalDate using the static of() method. LocalDate also contains methods to get the year, month, day, day, and so on.
@Test
public void localDateTest(a) throws Exception {
// Create a LocalDate:
LocalDate of = LocalDate.of(2021.8.9);
// Get the current time
LocalDate now = LocalDate.now();
/ / format
LocalDate parse1 = LocalDate.parse("2021-05-11");
// Specify a date format
LocalDate parse2 = LocalDate.parse("2021-05-11", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
// The following code has a formatting exception
// java.time.format.DateTimeParseException: Text '2021-05-11 11:53:53' could not be parsed, unparsed text found at index 10
// LocalDate parse3 = LocalDate.parse("2021-05-11 11:53:53", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
// Correct formatting methods
LocalDate parse3 = LocalDate.parse("The 2021-05-11 11:53:53", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
// The current time
System.out.println("now() => "+ now);
// Get the month
int dayOfMonth = parse1.getDayOfMonth();
System.out.println("dayOfMonth => " + dayOfMonth);
// Get the year
int dayOfYear = parse1.getDayOfYear();
System.out.println("getDayOfYear => " + dayOfYear);
// Get that week, notice that we're getting objects here
DayOfWeek dayOfWeek = parse1.getDayOfWeek();
System.out.println("getDayOfWeek => " + dayOfWeek);
// Get monthly data
int monthValue = parse3.getMonthValue();
System.out.println("getMonthValue => " + monthValue);
// Get the year
int year = parse3.getYear();
System.out.println("getYear => " + year);
// getChronology is the chronology of the current time, where the output is ISO
System.out.println("getChronology => " + parse3.getChronology());
System.out.println("getEra => " + parse3.getEra());
TemporalField is an interface that defines how to access the value of TemporalField. ChronnoField implements this interface
/* LocalDate supports the following formats: case DAY_OF_WEEK: return getDayOfWeek().getValue(); case ALIGNED_DAY_OF_WEEK_IN_MONTH: return ((day - 1) % 7) + 1; case ALIGNED_DAY_OF_WEEK_IN_YEAR: return ((getDayOfYear() - 1) % 7) + 1; case DAY_OF_MONTH: return day; case DAY_OF_YEAR: return getDayOfYear(); case EPOCH_DAY: throw new UnsupportedTemporalTypeException("Invalid field 'EpochDay' for get() method, use getLong() instead"); case ALIGNED_WEEK_OF_MONTH: return ((day - 1) / 7) + 1; case ALIGNED_WEEK_OF_YEAR: return ((getDayOfYear() - 1) / 7) + 1; case MONTH_OF_YEAR: return month; case PROLEPTIC_MONTH: throw new UnsupportedTemporalTypeException("Invalid field 'ProlepticMonth' for get() method, use getLong() instead"); case YEAR_OF_ERA: return (year >= 1 ? year : 1 - year); case YEAR: return year; case ERA: return (year >= 1 ? 1:0); * * /
// Unsupported field: HourOfDay
// System.out.println("ChronoField.HOUR_OF_DAY => " + parse1.get(ChronoField.HOUR_OF_DAY));
// Unsupported field: MinuteOfHour
// System.out.println("ChronoField.MINUTE_OF_HOUR => " + parse1.get(ChronoField.MINUTE_OF_HOUR));
// Unsupported field: MinuteOfHour
// System.out.println("ChronoField.SECOND_OF_MINUTE => " + parse1.get(ChronoField.SECOND_OF_MINUTE));
System.out.println("ChronoField.YEAR => " + parse1.get(ChronoField.YEAR));
// Unsupported field: MinuteOfHour
// System.out.println("ChronoField.INSTANT_SECONDS => " + parse1.get(ChronoField.INSTANT_SECONDS));
}/* Result: now() => 2021-08-08 dayOfMonth => 11 getDayOfYear => 131 getDayOfWeek => TUESDAY getMonthValue => 5 getYear => 2021 getChronology => ISO getEra => CE ChronoField.YEAR => 2021 */
Copy the code
TemporalField is an interface that defines how to access the value of TemporalField. ChronnoField implements this interface
LocalTime
LocalTime: is similar to LocalDate, except that it contains the specific time and has more specific time. The following are the corresponding methods and tests:
@Test
public void localTimeTest(a) throws Exception {
LocalTime now = LocalTime.now();
System.out.println("LocalTime.now() => "+ now);
System.out.println("getHour => "+ now.getHour());
System.out.println("getMinute => "+ now.getMinute());
System.out.println("getNano => "+ now.getNano());
System.out.println("getSecond => "+ now.getSecond());
LocalTime systemDefault = LocalTime.now(Clock.systemDefaultZone());
/ / ZoneName = > Java. Time. The format. The ZoneName. ZidMap from this map on the inside to get it
LocalTime japan = LocalTime.now(Clock.system(ZoneId.of("Japan")));
// Change the time zone
LocalTime japan2 = LocalTime.now(ZoneId.of("Japan"));
// Format the time
LocalTime localTime = LocalTime.of(15.22);
// From transforms from another time, as long as their interfaces are compatible
LocalTime from = LocalTime.from(LocalDateTime.now());
// the value of nanosecond
LocalTime localTime1 = LocalTime.ofNanoOfDay(1);
LocalTime localTime2 = LocalTime.ofSecondOfDay(1);
Invalid value for MinuteOfHour (valid values 0-59): 77
// LocalTime.of(15, 77);
// Get the local default time
System.out.println("LocalTime.now(Clock.systemDefaultZone()) => "+ systemDefault);
// Get the time of Japan time zone
System.out.println("LocalTime.now(Clock.system(ZoneId.of(\"Japan\"))) => "+ japan);
System.out.println("LocalTime.now(ZoneId.of(\"Japan\")) => "+ japan2);
System.out.println("LocalTime.of(15, 22) => "+ localTime);
System.out.println("LocalTime.from(LocalDateTime.now()) => "+ from);
System.out.println("LocalTime.ofNanoOfDay(1) => "+ localTime1);
System.out.println("LocalTime.ofSecondOfDay(1) => "+ localTime2);
}/* Result: Localtime.now () => 12:58:13.553 getHour => 12 getMinute => 58 getNano => 553000000 getSecond => 13 Localtime.now (clock. systemDefaultZone()) => 12:58:13.553 localtime.now (clock. system(zoneid.of ("Japan"))) => 13:58:13.553 LocalTime. Now (ZoneId) of (" Japan ")) = > 13:58:13. 553 LocalTime. Of (15, From (localDatetime.now ()) => 12:58:13.553 localTime.ofnanoofDay (1) => 00:00:00.000000001 LocalTime.ofSecondOfDay(1) => 00:00:01 */
Copy the code
LocalDateTime
LocalDateTime: The LocalDateTime class is a combination of LocalDate and LocalTime and can be created directly with the of() method, It is also possible to combine a LocalDate or LocalTime into a LocalDateTime by calling the atTime() method of LocalDate or the atDate() method of LocalTime. Here are some simple method tests. You’ll later write code for a utility class that combines this.
@Test
public void localDateTimeTest(a) throws Exception {
//Text '2021-11-11 15:30:11' could not be parsed at index 10
// LocalDateTime parse = LocalDateTime.parse("2021-11-11 15:30:11");
// The ISO time format is used by default
LocalDateTime parse1 = LocalDateTime.parse("2011-12-03T10:15:30");
// If you want your own format, you need to format it manually
LocalDateTime parse = LocalDateTime.parse("The 2021-11-11 15:30:11", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println("LocalDateTime.parse(....) => "+ parse1);
System.out.println("LocalDateTime.parse(....) => "+ parse);
LocalDateTime of = LocalDateTime.of(LocalDate.now(), LocalTime.now());
LocalDateTime japan = LocalDateTime.now(ZoneId.of("Japan"));
System.out.println("LocalDateTime.of(LocalDate.now(), LocalTime.now()) => "+ of);
System.out.println("LocalDateTime.now(ZoneId.of(\"Japan\")) => "+ japan);
}/* Localdatetime.parse (....) => 2011-12-03T10:15:30 LocalDateTime.parse(....) => 2021-11-11T15:30:11 LocalDateTime.of(LocalDate.now(), Localtime.now ()) => 21-08-08T13:22:59.697 localtime.now (zoneid.of ("Japan")) => 21-08-08T14:22:59.697 */
Copy the code
Fine grained machine time operation
JDK8 also classifies machine time, as shown below
Instant
Instant is used to represent a timestamp, similar to the common system.currentTimemillis (), but accurate to nano-second.
Note: Two constants are used internally, seconds for the number of seconds since 1970-01-01 00:00:00 and nanos for the nanosecond part (nanos does not exceed 999,999,999).
Here are some specific test cases:
@Test
public void instantTest(a) throws Exception {
Instant now = Instant.now();
// Unable to obtain Instant from TemporalAccessor: 2021-08-08T13:37:34.403 of type java.time.LocalDateTime
// Instant from = Instant.from(LocalDateTime.now());
Instant instant = Instant.ofEpochSecond(3.0);
Instant instant1 = Instant.ofEpochSecond(5.1 _000_000_000);
System.out.println("Instant.now() => "+ now);
// System.out.println("Instant.from(LocalDateTime.now()) => "+ from);
System.out.println("Instant.ofEpochSecond => "+ instant);
System.out.println("Instant.ofEpochSecond => "+ instant1);
System.out.println("Instant.get(ChronoField.NANO_OF_SECOND) => "+ now.get(ChronoField.NANO_OF_SECOND));
}/* Result: Instant. Now () => 2021-08-08T05:42:42.465z Instant. OfEpochSecond => 1970-01-01 t00:03z Instant. 1970-01-01T00:00:06Z Instant.get(ChronoField.NANO_OF_SECOND) => 465000000 */
Copy the code
Duration
The internal implementation of Duration is similar to Instant in that it has two parts: seconds for seconds and nanos for nanoseconds. The difference between the two is that Instant is used to represent a timestamp (or point in time), while Duration is used to represent a time period, such as when you want to get the difference between two times:
@Test
public void durationTest(a) throws Exception {
// Text '201-08-08T10:15:30' could not be parsed at index 0
Duration between = Duration.between(LocalDateTime.parse("2011-12-03T10:15:30"), LocalDateTime.parse("2021-08-08T10:15:30"));
System.out.println("Duration.between(LocalDateTime.parse(\"2011-12-03T10:15:30\"), LocalDateTime.parse(\"2021-08-08T10:15:30\")) => "+ between);
Duration duration = Duration.ofDays(7);
System.out.println("Duration.ofDays(7) => "+ duration);
}
Copy the code
Period
Period is conceptually similar to Duration, except that Period is measured by year, month and day (e.g. 2 years, 3 months and 6 days). Here is the corresponding unit test and related code:
@Test
public void periodTest(a) throws Exception {
Period between = Period.between(LocalDate.parse("2011-12-03"), LocalDate.parse("2021-08-08"));
Period period = Period.ofWeeks(53);
Period period1 = Period.ofWeeks(22);
System.out.println("Period.between(LocalDate.parse(\"2011-12-03\"), LocalDate.parse(\"2021-08-08\")) => "+ between);
System.out.println("Period.ofWeeks(53) => "+ period);
System.out.println("Period.ofWeeks(53) getDays => "+ period.getDays());
// Note that 0 is present if there is no corresponding value
System.out.println("Period.ofWeeks(53) getMonths => "+ period.getMonths());
System.out.println("Period.ofWeeks(22) getMonths => "+ period1.getMonths());
System.out.println("Period.ofWeeks(22) getYears => "+ period1.getYears());
}/* Result: Period.between(LocalDate.parse("2011-12-03"), LocalDate.parse("2021-08-08")) => P9Y8M5D Period.ofWeeks(53) => P371D Period.ofWeeks(53) getDays => 371 Period.ofWeeks(53) getMonths => 0 Period.ofWeeks(22) getMonths => 0 Period.ofWeeks(22) getYears => 0 */
Copy the code
TemporalAdjusters complex date operation
This class can do all sorts of more complex operations on time, such as the next business day, the last day of the month, with the with method:
@Test
public void testTemporalAdjusters(a){
LocalDate of = LocalDate.of(2021.8.1);
// Get the first day of the current year
LocalDate with = of.with(TemporalAdjusters.firstDayOfYear());
System.out.println(" TemporalAdjusters.firstDayOfYear => "+ with);
// Get the next Saturday of the specified date
LocalDate with1 = of.with(TemporalAdjusters.next(DayOfWeek.SATURDAY));
System.out.println(" TemporalAdjusters.next(DayOfWeek.SATURDAY) => "+ with1);
// Get the last day of the month
LocalDate with2 = of.with(TemporalAdjusters.lastDayOfMonth());
System.out.println("TemporalAdjusters.lastDayOfMonth() => "+ with2);
}
Copy the code
Here’s a list of all the methods from the network
The method name | describe |
---|---|
dayOfWeekInMonth |
Returns the day of the week in the same month |
firstDayOfMonth |
Returns the first day of the month |
firstDayOfNextMonth |
Return to the first day of the next month |
firstDayOfNextYear |
Return to the first day of the next year |
firstDayOfYear |
Return to the first day of the year |
firstInMonth |
Returns the first day of the month |
lastDayOfMonth |
Returns the last day of the month |
lastDayOfNextMonth |
Return to the last day of the next month |
lastDayOfNextYear |
Return to the last day of the next year |
lastDayOfYear |
Return to the last day of the year |
lastInMonth |
Returns the last day of the month |
next / previous |
Returns the day of the following/preceding given week |
nextOrSame / previousOrSame |
Returns the next/previous given day of the week, or if the value meets the criteria |
DateTimeFormatter Formatter
This class can be thought of as an alternative to SimpleDateFormat in that it has more powerful customization and is thread-safe so you don’t have to worry about multithreaded access.
Build a local formatter based on the DateTimeFormatter, and the code is very simple to understand:
private static DateTimeFormatter generateDefualtPattern(String timeFormat) {
return new DateTimeFormatterBuilder().appendPattern(timeFormat)
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter(Locale.CHINA);
}
Copy the code
Time zone information
Time zone information is rarely used, which may be used in operations related to internationalization. For example, I recently bought something from Apple. Although I placed an order on 6th, the phone said I placed the order on 5th, so I think the exact time apple placed the order is calculated according to the American time.
Strong JDK8 date class about time zones related classes (note the case.brass appeared JDK8 class, don’t be mistaken for compatible) of class before, in the previous unit testing is already used in the relevant time zone, the method of using the ZoneId in JDK8 this class, but sometimes we don’t know how to get in, you can refer to the following contents:
/ / ZoneName = > Java. Time. The format. The ZoneName. ZidMap from this map on the inside to get it
LocalTime japan = LocalTime.now(Clock.system(ZoneId.of("Japan")));
Copy the code
Field – Encapsulate the date utility class
Of course, the best way is to give yourself a few more requirements, forced to use JDK8 method to achieve, you will find that you master these API will be particularly fast.
Matters needing attention:
All utility code uses the same local formatter build method: generateDefualtPattern() :
/** * generates the default formatter **@paramTimeFormat Specifies the format *@returnThe default time formatter */
private static DateTimeFormatter generateDefualtPattern(String timeFormat) {
return new DateTimeFormatterBuilder().appendPattern(timeFormat)
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter(Locale.CHINA);
}
Copy the code
Gets the last and next business days for the specified time
Note that this version does not judge holidays, but of course this is the manual version.
/** * Gets the last working day of the specified time **@paramTime Specifies the time *@paramFormattPattern Format parameter *@return* /
public static String getPreWorkDay(String time, String formattPattern) {
DateTimeFormatter dateTimeFormatter = generateDefualtPattern(formattPattern);
LocalDateTime compareTime1 = LocalDateTime.parse(time, dateTimeFormatter);
compareTime1 = compareTime1.with(temporal -> {
// The current date
DayOfWeek dayOfWeek = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));
// Normally, subtract one day at a time
int dayToMinu = 1;
// If it is Sunday, subtract 2 days
if (dayOfWeek == DayOfWeek.SUNDAY) {
dayToMinu = 2;
}
// If it is Saturday, subtract one day
if (dayOfWeek == DayOfWeek.SATURDAY) {
dayToMinu = 1;
}
return temporal.minus(dayToMinu, ChronoUnit.DAYS);
});
return compareTime1.format(dateTimeFormatter);
}
/** * Gets the next working day of the specified time **@paramTime Specifies the time *@paramFormattPattern Format parameter *@return* /
public static String getNextWorkDay(String time, String formattPattern) {
DateTimeFormatter dateTimeFormatter = generateDefualtPattern(formattPattern);
LocalDateTime compareTime1 = LocalDateTime.parse(time, dateTimeFormatter);
compareTime1 = compareTime1.with(temporal -> {
// The current date
DayOfWeek dayOfWeek = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));
// Normally, add one day at a time
int dayToAdd = 1;
// If it is Friday, add 3 days
if (dayOfWeek == DayOfWeek.FRIDAY) {
dayToAdd = 3;
}
// If it is Saturday, add two days
if (dayOfWeek == DayOfWeek.SATURDAY) {
dayToAdd = 2;
}
return temporal.plus(dayToAdd, ChronoUnit.DAYS);
});
return compareTime1.format(dateTimeFormatter);
}
Copy the code
Check whether the current time is less than the target time
To determine whether the current time is less than the target time, this is a combination of some of the methods we learned earlier. Note that the time zone used here is the current system time zone. If you switch to another time zone, you will see a different effect. And I’m using LocalDateTime so don’t get confused.
/** * Use JDK 1.8 date classes to compare times ** determine whether the current time is less than the target time **@paramTime Time character string *@paramFormat Specifies the format *@returnCheck whether the current time is less than the target time */
public static boolean isBefore(String time, String format) {
DateTimeFormatter dateTimeFormatter = generateDefualtPattern(format);
LocalDateTime compareTime = LocalDateTime.parse(time, dateTimeFormatter);
GetNowByNew encapsulates the now() method
LocalDateTime current = LocalDateTime.parse(getNowByNew(format), dateTimeFormatter);
long compare = Instant.from(compareTime.atZone(ZoneId.systemDefault())).toEpochMilli();
long currentTimeMillis = Instant.from(current.atZone(ZoneId.systemDefault())).toEpochMilli();
return currentTimeMillis < compare;
}
Copy the code
Gets the day of the week for the specified time
It is a secondary encapsulation of JDK8’s own methods.
/** * returns the enumeration object **@paramThe date date *@paramFormattPattern format *@return* /
public static DayOfWeek getDayOfWeek(String date, String formattPattern) {
DateTimeFormatter dateTimeFormatter = generateDefualtPattern(formattPattern);
return LocalDate.parse(date, dateTimeFormatter).getDayOfWeek();
}
Copy the code
Gets the date between the start date and end date
Here need to pay attention to is not very rigorous, it is best to execute before the date of judgment
public static final String yyyyMMdd = "yyyy-MM-dd";
/** * Gets the date between the start date and the end date (returns List<String>) **@paramStartTime Start date *@paramEndTime End date *@returnAll dates between start and end, including start and end */
public static List<String> getMiddleDateToString(String startTime, String endTime) {
LocalDate begin = LocalDate.parse(startTime, DateTimeFormatter.ofPattern(yyyyMMdd));
LocalDate end = LocalDate.parse(endTime, DateTimeFormatter.ofPattern(yyyyMMdd));
List<LocalDate> localDateList = new ArrayList<>();
long length = end.toEpochDay() - begin.toEpochDay();
// The number of days to collect the difference
for (long i = length; i >= 0; i--) {
localDateList.add(end.minusDays(i));
}
List<String> resultList = new ArrayList<>();
for (LocalDate temp : localDateList) {
resultList.add(temp.toString());
}
return resultList;
}
Copy the code
Common pits in the date API:
LocalDateTime
The format ofyyyy-MM-dd
Error:
The most problematic diamante for first use is shown in the following form, as we do
LocalDateTime parse2 = LocalDateTime.parse("2021-11-11", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
Copy the code
When run, the following exception is thrown:
java.time.format.DateTimeParseException: Text '2021-11-11' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {},ISO resolved to 2021-11-11 of type java.time.format.Parsed
Copy the code
Here’s the solution:
The first solution is more painful, but it is a very safe solution.
try {
LocalDate localDate = LocalDate.parse("2019-05-27", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
LocalDateTime localDateTime = localDate.atStartOfDay();
System.out.println(localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
} catch (Exception ex) {
ex.printStackTrace();
}
Copy the code
Another way is to build a “Chinese” date formatter using the following method:
/** * generates the default formatter **@paramTimeFormat Specifies the format *@returnThe default time formatter */
private static DateTimeFormatter generateDefualtPattern(String timeFormat) {
return new DateTimeFormatterBuilder().appendPattern(timeFormat)
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter(Locale.CHINA);
}
Copy the code
Call format appearsxx not be parsed, unparsed text found at index 10
Error: Use incorrect format to format string, such as YYYY-MM-DD format 2020-05-12 12:15:33
The fundamental solution to the above problems is as follows: Because localdateTime does not find the corresponding format in the case of formatting, there will be similar to the unsupport method
/** * generates the default formatter **@paramTimeFormat Specifies the format *@return* /
private static DateTimeFormatter generateDefualtPattern(String timeFormat) {
return new DateTimeFormatterBuilder().appendPattern(timeFormat)
.parseDefaulting(ChronoField.HOUR_OF_DAY, 1)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 1)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter(Locale.CHINA);
}
Copy the code
Here are some answers to other questions:
DateTimeParseException: Text could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor
Text: Cannot get LocalDateTime from TemporalAccessor
Cannot obtain LocalDateTime from TemporalAccessor when parsing LocalDateTime (Java 8)
DateTimeParseException a few craters
Referring to the exception log below, the root cause is that DateTimeFormatter formatting does not have the HH option, which is where the pit is
java.time.format.DateTimeParseException: Text 'the 2017-02-02 08:59:12' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {MinuteOfHour=59, NanoOfSecond=0, SecondOfMinute=12, MicroOfSecond=0, MilliOfSecond=0, HourOfAmPm=8},ISO resolved to 2017-02-02 of type java.time.format.Parsed
Copy the code
Conclusion:
In the process of writing my own utility classes, I found them to work much better than the previous Date and Calendar classes, and the Date classes in JDK8 are thread-safe. Of course JDK8 is not very friendly for domestic use, there is no way after all is a foreign thing, but there are a lot of solutions, used to solve the routine can also accept. Finally, conditional had better use the search engine of Google, can help you cross pit not only in the past, a lot of big god still can give you talk about principle, be very useful.
Write in the last
Writing is not easy, beg for praise, beg for collection.
Finally, I would like to recommend my personal wechat public account: “Laishi Xiaowu”. If you have any questions, please communicate with me through the public account. Of course, the comments will be answered as soon as you see them.
Other problems
- A pit about LocalDate
About LocalDate some source code analysis
Directly to the source code, LocalDate represents only a date, not a DateTime. Therefore, “HH: mm: ss” is meaningless during formatting. If our formatting parameters do not conform to the following rules, this method will throw an exception and indicate that the corresponding formatting operation is not supported.
private int get0(TemporalField field) {
switch ((ChronoField) field) {
case DAY_OF_WEEK: return getDayOfWeek().getValue();
case ALIGNED_DAY_OF_WEEK_IN_MONTH: return ((day - 1) % 7) + 1;
case ALIGNED_DAY_OF_WEEK_IN_YEAR: return ((getDayOfYear() - 1) % 7) + 1;
case DAY_OF_MONTH: return day;
case DAY_OF_YEAR: return getDayOfYear();
case EPOCH_DAY: throw new UnsupportedTemporalTypeException("Invalid field 'EpochDay' for get() method, use getLong() instead");
case ALIGNED_WEEK_OF_MONTH: return ((day - 1) / 7) + 1;
case ALIGNED_WEEK_OF_YEAR: return ((getDayOfYear() - 1) / 7) + 1;
case MONTH_OF_YEAR: return month;
case PROLEPTIC_MONTH: throw new UnsupportedTemporalTypeException("Invalid field 'ProlepticMonth' for get() method, use getLong() instead");
case YEAR_OF_ERA: return (year >= 1 ? year : 1 - year);
case YEAR: return year;
case ERA: return (year >= 1 ? 1 : 0);
}
throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
}
Copy the code
-
Formatting problems:
Calling DateFomatter can cause errors, mostly due to using the wrong format or using the wrong time class
Error java.time.format.DateTimeParseException: could not be parsed, unparsed text found at index 10
The resources
Spiderman said java8 – LocalDateTime