Java 8 introduced a new API for handling dates. Date operations that used Date, Calendar in the standard API have changed to LocalDate, LocalDateTime, etc.
This time, I will introduce the simple usage of LocalDate, precautions when using it, and the fact that there was such a convenient usage. The second half introduces precautions on how to handle it, so please take a look to the end.
Before Java8, I wrote the following code to get the current date.
Date currentDate1 = new Date();
Calendar currentDate2 = Calendar.getInstance();
However, this code includes not only the date but also the time, so be careful when using only the date. For example, if you want to get information during a certain date, this time will affect it, and you may get unintended data. It is necessary to cut the time part to prevent unintended movement.
final LocalDate currentDate = LocalDate.now();
System.out.println(currentDate); // 2020-01-15
If you want to use LocalDate to set the current date, use the now method. In the case of LocalDate, the date is set and it is not handled after the time.
Prior to Java8, I wrote code like the following to initialize by date.
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, 2019);
calendar.set(Calendar.MONTH, 11);
calendar.set(Calendar.DAY_OF_MONTH, 25);
In this writing style, the month starts at 0, so if you set 11, it will be December. Also, this also comes with time, so it is necessary to cut the time.
LocalDate targetDate = LocalDate.of(2019, 12, 25)
System.out.println(targetDate); // 2019-12-25
Use the of method to perform initialization by specifying a date. Compared to Date and Calendar, setting the date is more intuitive and easier.
Before Java8, I wrote the following code to get the date from a character.
DateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
Date date = formatter.parse("2019/12/25");
You can intuitively change from a character string to a date as you see it. But in fact SimpleDateFormat is not thread safe. When creating thread programming or Web applications, if you use it incorrectly, the date of another user will be rewritten.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
LocalDate targetDate = LocalDate.parse("2019/12/25", formatter);
System.out.println(targetDate); // 2019-12-25
Instantiate a LocalDate type from a date string. DateTimeFormatter You can rest assured that it is thread-safe.
LocalDate targetDate = DateTimeFormatter.ofPattern("yyyy/MM/dd")
.parse("2019/12/25", LocalDate::from);
System.out.println(targetDate); // 2019-12-25
You can also write code like this. The above code looks good at first glance, but there is a problem.
I imitated the previous code and wrote the following code.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd")
.parse("2020/02/30", LocalDate::from);
System.out.println(targetDate); // 2020-02-29
In February 2020, there was only 29 days, and even if you specified 30 days, no error occurred and it was converted to 29 days without permission. It may seem convenient at first glance, but it is not suitable for accurate date checking and conversion. Therefore, rewrite as follows.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd")
.withResolverStyle(ResolverStyle.STRICT)
.parse("2020/02/30", LocalDate::from);
System.out.println(targetDate); //Exception occurred
Setting ResolverStyle.STRICT resolves the date exactly so that an exception will be thrown if the date is incorrect.
I changed the previous program a little and made a version without slashes in the date string.
LocalDate targetDate = DateTimeFormatter.ofPattern("yyyyMMdd")
.withResolverStyle(ResolverStyle.STRICT)
.parse("20191225", LocalDate::from);
System.out.println(targetDate); // ???
This code looks correct, but I get an exception on output.
DateTimeFormatter (Java Platform SE 8)
Looking at the above document, it is written as follows.
Symbol | Meaning | Presentation | Examples |
---|---|---|---|
g | era | text | AD; Anno Domini; A |
u | year | year | 2004; 04 |
y | year-of-era | year | 2004; 04 |
The format symbol y is labeled year-of-era. era represents the calendar, and since the date was handled strictly by STRICT earlier, the calendar could not be determined and an error occurred.
LocalDate targetDate = DateTimeFormatter.ofPattern("uuuuMMdd")
.withResolverStyle(ResolverStyle.STRICT)
.parse("20191225", LocalDate::from);
System.out.println(targetDate); // 2019-12-25
I changed the symbol from y to u and the date conversion was successful.
LocalDate targetDate = DateTimeFormatter.ofPattern("GGGGyy year MM month dd day")
.withLocale(Locale.JAPAN)
.withChronology(JapaneseChronology.INSTANCE)
.withResolverStyle(ResolverStyle.STRICT)
.parse("December 25, 2018", LocalDate::from);
System.out.println(targetDate); // 2018-12-25
By the way, when dealing with the Japanese calendar, write as above.
Starting with Java 8, working with dates has become much easier. However, I also found that there are various precautions when using it. If you look it up on the net, you can see how to use it immediately, but you cannot judge whether the method is really correct without proper knowledge. We also recommend that you look at the official documentation, including the content introduced this time.
Recommended Posts