java.util.Date
객체를 새로운 JDK 8 / JSR-310 으로 변환하는 가장 좋은 방법은 무엇입니까 java.time.LocalDate
?
Date input = new Date();
LocalDate date = ???
답변
짧은 답변
Date input = new Date();
LocalDate date = input.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
설명
이름에도 불구하고 java.util.Date
“날짜”가 아니라 타임 라인의 순간을 나타냅니다. 객체 내에 저장된 실제 데이터는 long
1970-01-01T00 : 00Z (1970 GMT / UTC 시작시 자정) 이후 밀리 초 수입니다.
java.util.Date
JSR-310 과 동등한 클래스 는 다음 Instant
과 같이 toInstant()
변환을 제공 하는 편리한 방법 이 있습니다.
Date input = new Date();
Instant instant = input.toInstant();
java.util.Date
인스턴스는 시간대의 개념이 없습니다. 당신이 호출하면이 이상하게 보일 수도 toString()
A의 java.util.Date
(가) 때문에, toString
시간 영역에 상대적입니다. 그러나이 메소드는 실제로 Java의 기본 시간대를 사용하여 문자열을 제공합니다. 시간대는의 실제 상태의 일부가 아닙니다 java.util.Date
.
은 Instant
또한 시간대에 대한 정보가 포함되어 있지 않습니다. 따라서에서 Instant
날짜를 현지 날짜 로 변환하려면 시간대를 지정해야합니다. 기본 영역 ZoneId.systemDefault()
일 수도 있고 사용자 기본 설정의 시간대와 같이 응용 프로그램이 제어하는 시간대 일 수도 있습니다. atZone()
시간대를 적용 하는 방법을 사용하십시오 .
Date input = new Date();
Instant instant = input.toInstant();
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
A ZonedDateTime
에는 현지 날짜 및 시간, 시간대 및 GMT / UTC의 오프셋으로 구성된 상태가 포함됩니다. 따라서 다음과 같이 날짜를 LocalDate
쉽게 추출 할 수 있습니다 toLocalDate()
.
Date input = new Date();
Instant instant = input.toInstant();
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
LocalDate date = zdt.toLocalDate();
자바 9 답변
Java SE 9 에는이 작업을 약간 단순화 하는 새로운 방법 이 추가되었습니다.
Date input = new Date();
LocalDate date = LocalDate.ofInstant(input.toInstant(), ZoneId.systemDefault());
이 새로운 대안은 더 직접적이고 가비지가 적으므로 더 나은 성능을 발휘해야합니다.
답변
더 좋은 방법은 다음과 같습니다.
Date date = ...;
Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate()
이 버전의 장점 :
-
입력이 인스턴스
java.util.Date
이거나java.sql.Date
(@JodaStephen의 방식과 달리) 하위 클래스에 관계없이 작동합니다 . 이는 JDBC에서 시작된 데이터와 공통입니다.java.sql.Date.toInstant()
항상 예외가 발생합니다. -
JSR-310 백 포트가있는 JDK8 및 JDK7과 동일
개인적으로 유틸리티 클래스를 사용하지만 백 포트와 호환되지는 않습니다.
/**
* Utilities for conversion between the old and new JDK date types
* (between {@code java.util.Date} and {@code java.time.*}).
*
* <p>
* All methods are null-safe.
*/
public class DateConvertUtils {
/**
* Calls {@link #asLocalDate(Date, ZoneId)} with the system default time zone.
*/
public static LocalDate asLocalDate(java.util.Date date) {
return asLocalDate(date, ZoneId.systemDefault());
}
/**
* Creates {@link LocalDate} from {@code java.util.Date} or it's subclasses. Null-safe.
*/
public static LocalDate asLocalDate(java.util.Date date, ZoneId zone) {
if (date == null)
return null;
if (date instanceof java.sql.Date)
return ((java.sql.Date) date).toLocalDate();
else
return Instant.ofEpochMilli(date.getTime()).atZone(zone).toLocalDate();
}
/**
* Calls {@link #asLocalDateTime(Date, ZoneId)} with the system default time zone.
*/
public static LocalDateTime asLocalDateTime(java.util.Date date) {
return asLocalDateTime(date, ZoneId.systemDefault());
}
/**
* Creates {@link LocalDateTime} from {@code java.util.Date} or it's subclasses. Null-safe.
*/
public static LocalDateTime asLocalDateTime(java.util.Date date, ZoneId zone) {
if (date == null)
return null;
if (date instanceof java.sql.Timestamp)
return ((java.sql.Timestamp) date).toLocalDateTime();
else
return Instant.ofEpochMilli(date.getTime()).atZone(zone).toLocalDateTime();
}
/**
* Calls {@link #asUtilDate(Object, ZoneId)} with the system default time zone.
*/
public static java.util.Date asUtilDate(Object date) {
return asUtilDate(date, ZoneId.systemDefault());
}
/**
* Creates a {@link java.util.Date} from various date objects. Is null-safe. Currently supports:<ul>
* <li>{@link java.util.Date}
* <li>{@link java.sql.Date}
* <li>{@link java.sql.Timestamp}
* <li>{@link java.time.LocalDate}
* <li>{@link java.time.LocalDateTime}
* <li>{@link java.time.ZonedDateTime}
* <li>{@link java.time.Instant}
* </ul>
*
* @param zone Time zone, used only if the input object is LocalDate or LocalDateTime.
*
* @return {@link java.util.Date} (exactly this class, not a subclass, such as java.sql.Date)
*/
public static java.util.Date asUtilDate(Object date, ZoneId zone) {
if (date == null)
return null;
if (date instanceof java.sql.Date || date instanceof java.sql.Timestamp)
return new java.util.Date(((java.util.Date) date).getTime());
if (date instanceof java.util.Date)
return (java.util.Date) date;
if (date instanceof LocalDate)
return java.util.Date.from(((LocalDate) date).atStartOfDay(zone).toInstant());
if (date instanceof LocalDateTime)
return java.util.Date.from(((LocalDateTime) date).atZone(zone).toInstant());
if (date instanceof ZonedDateTime)
return java.util.Date.from(((ZonedDateTime) date).toInstant());
if (date instanceof Instant)
return java.util.Date.from((Instant) date);
throw new UnsupportedOperationException("Don't know hot to convert " + date.getClass().getName() + " to java.util.Date");
}
/**
* Creates an {@link Instant} from {@code java.util.Date} or it's subclasses. Null-safe.
*/
public static Instant asInstant(Date date) {
if (date == null)
return null;
else
return Instant.ofEpochMilli(date.getTime());
}
/**
* Calls {@link #asZonedDateTime(Date, ZoneId)} with the system default time zone.
*/
public static ZonedDateTime asZonedDateTime(Date date) {
return asZonedDateTime(date, ZoneId.systemDefault());
}
/**
* Creates {@link ZonedDateTime} from {@code java.util.Date} or it's subclasses. Null-safe.
*/
public static ZonedDateTime asZonedDateTime(Date date, ZoneId zone) {
if (date == null)
return null;
else
return asInstant(date).atZone(zone);
}
}
asLocalDate()
여기 방법은 널 안전한 사용이다 toLocalDate()
입력되면 java.sql.Date
(이것은 않도록 시간대 문제 나 불필요한 계산에 JDBC 드라이버에 의해 오버라이드 될 수있다), 그렇지 않으면 전술 한 방법을 사용한다.
답변
LocalDate localDate = LocalDate.parse( new SimpleDateFormat("yyyy-MM-dd").format(date) );
답변
Java 8을 사용하는 경우 @JodaStephen의 답변이 가장 좋습니다. 그러나 JSR-310 백 포트로 작업하는 경우 불행히도 다음과 같은 작업을 수행해야합니다.
Date input = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(input);
LocalDate date = LocalDate.of(cal.get(Calendar.YEAR),
cal.get(Calendar.MONTH) + 1,
cal.get(Calendar.DAY_OF_MONTH));
답변
LocalDate ld = new java.sql.Date( new java.util.Date().getTime() ).toLocalDate();
답변
한 줄로 변환 할 수 있습니다.
public static LocalDate getLocalDateFromDate(Date date){
return LocalDate.from(Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()));
}
답변
먼저, 날짜를 인스턴트로 쉽게 변환 할 수 있습니다
Instant timestamp = new Date().toInstant();
그런 다음 ofInstant () 메소드를 사용하여 jdk 8에서 Instant를 임의의 날짜 API로 변환 할 수 있습니다.
LocalDateTime date = LocalDateTime.ofInstant(timestamp, ZoneId.systemDefault());