Преобразуване на дата в LocalDate или LocalDateTime и обратно

1. Общ преглед

Започвайки с Java 8, имаме нов API за дата: java.time .

Понякога обаче все пак трябва да извършим преобразувания между новия и стария API и да работим с представяне на дати и от двете.

2. Преобразуване на java.util.Date в java.time.LocalDate

Нека започнем с преобразуване на старото представяне на дата в новото.

Тук можем да се възползваме от нов метод toInstant () , който е добавен към java.util.Date в Java 8.

Когато преобразуваме незабавен обект, се изисква да се използва ZoneId, защотоНезабавните обекти са агностични за часовата зона - само точки на времевата линия.

В atZone (ZoneId зона) API от незабавен обект връща ZonedDateTime , така че ние просто трябва да се извлече LOCALDATE от него с помощта на toLocalDate () метод.

Първо, използваме системата по подразбиране ZoneId :

public LocalDate convertToLocalDateViaInstant(Date dateToConvert) { return dateToConvert.toInstant() .atZone(ZoneId.systemDefault()) .toLocalDate(); }

И подобно решение, но с различен начин за създаване на незабавен обект - използвайки метода ofEpochMilli () :

public LocalDate convertToLocalDateViaMilisecond(Date dateToConvert) { return Instant.ofEpochMilli(dateToConvert.getTime()) .atZone(ZoneId.systemDefault()) .toLocalDate(); }

Преди да продължим, нека също така да разгледаме набързо стария клас java.sql.Date и как това също може да бъде преобразувано в LocalDate .

Започвайки с Java 8, можем да намерим допълнителен метод toLocalDate () в java.sql.Date , който също ни дава лесен начин да го преобразуваме в java.time.LocalDate .

В този случай не е нужно да се притесняваме за часовата зона:

public LocalDate convertToLocalDateViaSqlDate(Date dateToConvert) { return new java.sql.Date(dateToConvert.getTime()).toLocalDate(); }

По същия начин можем да конвертираме и стар обект Date в обект LocalDateTime . Нека да разгледаме това по-нататък.

3. Преобразуване на java.util.Date в java.time.LocalDateTime

За да получим екземпляр LocalDateTime , можем по подобен начин да използваме посредник ZonedDateTime и след това да използваме API на toLocalDateTime () .

Точно както преди, можем да използваме две възможни решения, за да получим незабавен обект от java.util.Date :

public LocalDateTime convertToLocalDateTimeViaInstant(Date dateToConvert) { return dateToConvert.toInstant() .atZone(ZoneId.systemDefault()) .toLocalDateTime(); } public LocalDateTime convertToLocalDateTimeViaMilisecond(Date dateToConvert) { return Instant.ofEpochMilli(dateToConvert.getTime()) .atZone(ZoneId.systemDefault()) .toLocalDateTime(); }

И като започнем с Java 8, можем също да използваме java.sql.Timestamp, за да получим LocalDateTime :

ocalDateTime convertToLocalDateTimeViaSqlTimestamp(Date dateToConvert) { return new java.sql.Timestamp( dateToConvert.getTime()).toLocalDateTime(); }

4. Преобразувайте java.time.LocalDate в java.util.Date

Сега, когато имаме добро разбиране за това как да конвертираме от старото представяне на данни в ново, нека да разгледаме преобразуването в другата посока.

Ще обсъдим два възможни начина за конвертиране на LocalDate в Date .

В първата използваме нов метод valueOf (дата на LocalDate) , предоставен в обект java.sql.Date , който приема LocalDate като параметър:

public Date convertToDateViaSqlDate(LocalDate dateToConvert) { return java.sql.Date.valueOf(dateToConvert); }

Както виждаме, той е без усилие и интуитивен. Той използва местна часова зона за преобразуване (всичко се извършва под капака, така че няма нужда да се притеснявате).

В друг пример за Java 8 използваме незабавен обект, който предаваме на метода from (Instant instant) на обекта java.util.Date :

public Date convertToDateViaInstant(LocalDate dateToConvert) { return java.util.Date.from(dateToConvert.atStartOfDay() .atZone(ZoneId.systemDefault()) .toInstant()); }

Забележете, че използваме незабавен обект тук и че също трябва да се грижим за часовите зони, когато правим това преобразуване.

След това нека използваме много подобно решение за конвертиране на LocalDateTime в обект Date .

5. Преобразувайте java.time.LocalDateTime в java.util.Date

Най-лесният начин да получите java.util.Date от LocalDateTime е да използвате разширение за java.sql.Timestamp - налично с Java 8:

public Date convertToDateViaSqlTimestamp(LocalDateTime dateToConvert) { return java.sql.Timestamp.valueOf(dateToConvert); }

Но разбира се, алтернативно решение е използването на незабавен обект, който получаваме от ZonedDateTime :

Date convertToDateViaInstant(LocalDateTime dateToConvert) { return java.util.Date .from(dateToConvert.atZone(ZoneId.systemDefault()) .toInstant()); }

6. Java 9 Допълнения

В Java 9 има нови методи, които опростяват преобразуването между java.util.Date и java.time.LocalDate или java.time.LocalDateTime .

LocalDate.ofInstant (незабавен миг, зона ZoneId) и LocalDateTime.ofInstant (незабавен миг, зона ZoneId) предоставят удобни преки пътища:

public LocalDate convertToLocalDate(Date dateToConvert) { return LocalDate.ofInstant( dateToConvert.toInstant(), ZoneId.systemDefault()); } public LocalDateTime convertToLocalDateTime(Date dateToConvert) { return LocalDateTime.ofInstant( dateToConvert.toInstant(), ZoneId.systemDefault()); }

7. Заключение

В тази статия разгледахме възможните начини за конвертиране на стари java.util.Date в нови java.time.LocalDate и java.time.LocalDateTime , както и обратното.

Пълното изпълнение на тази статия е достъпно в GitHub.