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.