- I converted LocalDate and LocalDateTime in Java8.
- Convert from LocalDateTime to LocalDate
- Addition and subtraction of LocalDate
- Compare LocalDate with LocalDate
- Date formatting
- Date formatting using the parse method
- Difference between hh and HH in DateTimeFormatter
- LocalDate vs.
- Period Class
- Duration class
- atStartOfDay method to find 00:00 of LocalDateTime for LocalDate
- OffsetDateTime class
- Convert a string date with time zone to LocalDateTime
- String date validity check
- Converts LocalDateTime to java.util.
- Determination of multiple past-future conditions for dates
- Related
I converted LocalDate and LocalDateTime in Java8.
I have been looking into the addition of a LocalDate class since Java 8.
LocalDate date = new LocalDate(2019,1,1); // NG because the constructor is private. LocalDate date = LocalDate.of(2019,2,28); // Instantiation using the static method of LocalDate date = LocalDate.of(2019,Month.APRIL,1); // Month can also be used
The instance creation method is generated using LocalDate.of.
The default format is yyyy-MM-dd, and the of method also determines the leap year, so new LocalDate(2019,2,29);
will cause an error.
To generate a LocalDate with the current time, use the now()
method.
LocalDate date = LocalDate.now();// 2019-03-23
Neither LocalDate nor LocalDateTime has a time zone, so if the OS date/time is changed, that time will be displayed.
Convert from LocalDateTime to LocalDate
LocalDateTime dateTime = LocalDateTime.now(); LocalDate date = LocalDate.of(dateTime.getYear(), dateTime.getMonth(), dateTime.getDayOfMonth());
Added on 2022/05/15 It appears that the java.time.temporal.TemporalAccessor interface can be used to convert from LocalDateTime to LocalDate.
TemporalAccessor temporalAccessor = LocalDateTime.now(); LocalDate date = LocalDate.from(temporalAccessor);
Addition and subtraction of LocalDate
There will be cases where you want to add or subtract days to or from the LocalDate. In such cases, plusDays(int) and minusDays(int) can be used to add and subtract. The methods provided are basically the same: LocalDateTime has methods for adding and subtracting hours, minutes, and seconds.
LocalDate date = LocalDate.now(); date = date.plusDays(2); // Add 2 days System.out.println(date);
Compare LocalDate with LocalDate
There may be times when you need to compare two LocalDates, such as when you want to “get data for dates that are no earlier than January 1, 2000. In such cases, the isAfter and isBefore methods are used.
LocalDate today = LocalDate.now(); LocalDate tomorrow = LocalDate.now().plusDays(1); today.isAfter(today); // == Note that this will be false (false on the same day). today.isAfter(tomorrow); // == false tomorrow.isAfter(today); // == true today.isBefore(today); // == Note that this will be false (false on the same day). today.isBefore(tomorrow); // == true tomorrow.isBefore(today); // == false
The isAfter and isBefore methods do not include the same date, so if you want to “get data for a future date that includes January 1, 2000,” you must use the equals method together to achieve the expected behavior.
LocalDate today = LocalDate.of(2000,1,1); LocalDate date = LocalDate.of(2000,1,1); today.isBefore(date) || today.equals(date); // == true
Date formatting
To format both LocalDate and LocalDateTime as dates, use the DateTimeFormatter class. The return value will be of type String.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd"); LocalDate date = LocalDate.of(2019,3,23); System.out.println(date.format(formatter)); // 2019/03/23
Date formatting using the parse method
Since the format method will convert the date to a String type, use the LocalDate.parse method to format the date. In this case, the return value will be of type LocalDate.
LocalDate.parse("2019/02/29",DateTimeFormatter.ofPattern("yyyy/MM/dd")); // Instance created as 2019/02/28.
It seems to be a good idea, but considering that the first argument comes dynamically as a string, you may want to make an error. In that case, change yyyy to uuuuuu and specify the withResolverStyle(ResolverStyle.STRICT) method.
LocalDate.parse("2019/11/31", DateTimeFormatter .ofPattern("uuuu/MM/dd") .withResolverStyle(ResolverStyle.STRICT)); // java.time.DateTimeException: Invalid date 'NOVEMBER 31'
Difference between hh and HH in DateTimeFormatter
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd hh:mm:ss"); LocalDateTime dateTime = LocalDateTime.of(LocalDate.of(2019, 3, 23), LocalTime.of(23, 50, 1, 1)); System.out.println(dateTime.format(formatter)); // 03/23/2019 11:50:01 pm.
If you specify 23, it will be 11 instead of an error.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"); LocalDateTime dateTime = LocalDateTime.of(LocalDate.of(2019, 3, 23), LocalTime.of(23, 50, 1, 1)); System.out.println(dateTime.format(formatter)); // Displayed as intended at 23:50:01 on 23/03/2019
If you specify it in HH, 23 will be displayed as 23. Incidentally, if this is done with the LocalDateTime.parse method, an error will occur.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd hh:mm:ss"); LocalDateTime dateTime = LocalDateTime.parse("2019/03/23 23:50:01",formatter); System.out.println(dateTime.format(formatter)); // DateTimeParseException: Text '2019/03/23 23:50:01' could not be parsed: Invalid value for ClockHourOfAmPm (valid values 1 - 12): 23
LocalDate vs.
Use the equals method to compare LocalDate with LocalDate. (The isEqual method can also be used.)
LocalDate ld1 = LocalDate.of(2010, 1, 1); LocalDate ld2 = LocalDate.parse("2010-01-01"); System.out.println(ld1.equals(ld2)); // True is displayed LocalDate ld3 = LocalDate.parse("2019/01/01",DateTimeFormatter.ofPattern("yyyy/MM/dd")); System.out.println(ld1.isEqual(ld3)); // False is displayed
Period Class
If you are dealing with days, you will also see the java.time.Period class. The Period class is a class that represents the amount of days and is instantiated with the between and of methods. The following uses the between method.
LocalDate ld1 = LocalDate.of(2010, 1, 1); LocalDate ld2 = LocalDate.parse("2019/02/03",DateTimeFormatter.ofPattern("yyyy/MM/dd")); Period period = Period.between(ld1, ld2); System.out.println(period); // P9Y1M2D 9 years, 1 month, 2 days difference. System.out.println(period.getYears()); // 9 System.out.println(period.getMonths()); // 1 System.out.println(period.getDays()); // 2 System.out.println(period.toTotalMonths()); // 109
The toTotalMonths method returns 9 years and 1 month = 109 months. The others are as in the method names. The following uses the of method.
Period period = Period.of(10, 9, 8); System.out.println(period); // P10Y9M8D 10 years, 9 months, 8 days difference. System.out.println(period.getYears()); // 10 System.out.println(period.getMonths()); // 9 System.out.println(period.getDays()); // 8 System.out.println(period.toTotalMonths()); // 129
Duration class
In contrast to the Period class, the Duration class represents an amount of time. The following uses the between method.
LocalDateTime ld1 = LocalDateTime.of(2010, 1, 1, 0, 0); LocalDateTime ld2 = LocalDateTime.parse("2010/01/02 112040",DateTimeFormatter.ofPattern("yyyy/MM/dd HHmmss")); Duration duration = Duration.between(ld1, ld2); System.out.println(duration); //PT35H20M40S -> 35 hours, 20 minutes and 40 seconds difference. System.out.println(duration.toDays()); // one day System.out.println(duration.toHours()); // 35 hours System.out.println(duration.toMinutes()); // 2120 min. System.out.println(duration.getSeconds()); // 127240 sec.
atStartOfDay method to find 00:00 of LocalDateTime for LocalDate
To convert from LocalDate to LocalDateTime, if you want to set 00:00, you can use the atStartOfDay method to convert to LocalDateTime at 00:00 of that day.
LocalDate ld = LocalDate.of(2019, Month.APRIL, 1); System.out.println((ld.atStartOfDay())); // 2019-04-01T00:00
OffsetDateTime class
The OffsetDateTime class represents a date with a time difference. For example, 2020-09-15T19:16:39.265866700+09:00 for JST, or 2020-09-15T10:16:39.265866700Z for UTC, with a Z at the end. It is also possible to convert a LocalDateTime instance to an instance of the OffsetDateTime class.
package jp.co.offsetdatetimes; import java.time.LocalDateTime; import java.time.OffsetDateTime; import java.time.ZoneId; import java.time.ZoneOffset; public class OffsetDateTimeSample { public static void main(String[] args) { // JST Display OffsetDateTime odtjst = OffsetDateTime.now(ZoneId.of("Asia/Tokyo")); // JST System.out.println(odtjst); // 2020-09-15T19:16:39.265866700+09:00 // Convert JST to UTC OffsetDateTime odtutc = OffsetDateTime.ofInstant(odtjst.toInstant(), ZoneId.of("UTC")); // UTC System.out.println(odtutc); // 2020-09-15T10:16:39.265866700Z // Convert LocalDateTime to OffsetDateTime LocalDateTime ldt = LocalDateTime.now(); ZoneOffset offset = ZoneId.of("UTC").getRules().getOffset(odtjst.toInstant()); OffsetDateTime odt = OffsetDateTime.of(ldt, offset); System.out.println(odt); // 2020-09-15T19:16:39.265866700Z } }
Convert a string date with time zone to LocalDateTime
This is an example of converting a string date with time zone to LocalDateTime using the ZonedDateTime,ZoneId class.
package jp.co.confrage; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.chrono.IsoChronology; import java.time.format.DateTimeFormatter; import java.time.format.ResolverStyle; public class DateTest { public static void main(String[] args) throws InterruptedException { String inputValue = "20201230T000000+0800"; ZonedDateTime value = ZonedDateTime.parse( inputValue, DateTimeFormatter.ofPattern("uuuuMMdd'T'HHmmssZ") .withChronology(IsoChronology.INSTANCE) .withResolverStyle(ResolverStyle.STRICT)); ZonedDateTime jst = value.withZoneSameInstant(ZoneId.of("Asia/Tokyo")); System.out.println(jst); // 2020-12-30T01:00+09:00[Asia/Tokyo] var dt = jst.toLocalDateTime(); System.out.println(dt); // 2020-12-30T01:00 } }
Once converted to UTC, the time would be easier to understand.
|JST|UTC|Results|
|:–|:–|:–|:–|
|2020/12/30 09:00:00+0900|202020/12/30 00:00:00Z|Different time|
|202020/12/30 10:00:00+0900|202020/12/30 01:00:00Z|Same time|
|202020/12/30 09:00:00+0800|202020/12/30 01:00:00Z|same time|
Convert to UTC and you will see that it is the same time.
String date validity check
A method to check if a date in a string is strictly valid using the parse method.
private boolean validateLocalDateTime(final String inputDateValue) { // "20200229T124440+0900" try { final LocalDateTime value = LocalDateTime.parse( inputDateValue, DateTimeFormatter.ofPattern("uuuuMMdd'T'HHmmssZ") .withChronology(IsoChronology.INSTANCE) .withResolverStyle(ResolverStyle.STRICT)); return true; } catch (final DateTimeParseException e) { e.printStackTrace(); return false; } }
Converts LocalDateTime to java.util.
Although there are not many cases where this conversion is done, it can be done using the toDate method as follows.
LocalDateTime ldt = LocalDateTime.now(); ZonedDateTime zdt = ldt.atZone(ZoneId.systemDefault()); Date dt = Date.from(zdt.toInstant()); // Fri Oct 30 11:30:15 GMT+09:00 2020
Determination of multiple past-future conditions for dates
Use isAfter or isBefore when writing a date determination for multiple conditions.
This is a confirmation that “father’s birthday > mother’s birthday > brother’s birthday > brother’s birthday” is consistent. It is written using the stream and allMatch methods.
import java.time.LocalDateTime; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; public class Main { public static void main(String[] args) { final LocalDateTime dt1 = LocalDateTime.of(1970, 1, 1, 0, 0); // father most recent day final LocalDateTime dt2 = LocalDateTime.of(1975, 1, 1, 0, 0); // mother final LocalDateTime dt3 = LocalDateTime.of(2000, 1, 1, 0, 0); // used after the name of someone who is an older brother figure final LocalDateTime dt4 = LocalDateTime.of(2003, 1, 1, 0, 0); // younger brother most recent (future) day final List<LocalDateTime> lists = new LinkedList<>(); lists.add(dt1); lists.add(dt2); lists.add(dt3); lists.add(dt4); if (lists.size() == 1) { return; } // father < mother < used after the name of someone who is an older brother figure < Check for being a brother final List<Boolean> checkResults = new ArrayList<>(); for (int i = 0; i < lists.size() - 1; i++) { System.out.println(lists.get(i).isBefore(lists.get(i + 1))); checkResults.add(lists.get(i).isBefore(lists.get(i + 1))); // true,true,true } final boolean result = checkResults.stream().allMatch(e -> e.equals(Boolean.TRUE)); System.out.println(result); // true } }
コメント