답변:
짧은 답변
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
은 시간대 개념이 없으며 시간대에 Instant
대한 정보도 포함하지 않습니다. LocalDate
API "는 시간대가없는 일"을 말한다. 그럼 왜에서 변환 Date
에 Instant
에 LocalDate
요구 atZone(ZoneId.systemDefault())
?
LocalDate
및 LocalDateTime
없습니다 "상점 또는 시간 또는 시간대 대표"할 (참조 :의 javadoc을). 클래스는 저장하지 않지만 클래스는 Local
날짜 및 / 또는 시간을 나타내므로 현지 날짜 / 시간으로 의 변환 은 시간대를 의미합니다.
더 좋은 방법은 다음과 같습니다.
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 드라이버에 의해 오버라이드 될 수있다), 그렇지 않으면 전술 한 방법을 사용한다.
DateConvertUtils
입니다.
Date.toInstant()
.
LocalDate localDate = LocalDate.parse( new SimpleDateFormat("yyyy-MM-dd").format(date) );
SimpleDateFormat
인스턴스는 현재 스레드로 제한 됩니다. 그것은되어 사용되는 스레드 안전한 방법. 이제 SimpleDateFormat
(그것을 필요로하는 내부 데이터 구조 모든 계정) '의 인스턴스를 생성하기위한 비용'으로 알려져있다하지만 당신은 할 수 공유하고 있기 때문에, (그것에 접근을 동기화하지 않음) '싱글'로 하나 가 참으로 스레드 - 아니다 안전한. ( 이 코드의 '오염') 이 스레드의 수명주기를 담당 하는 경우ThreadLocal
해결책이 작동 할 수 있지만 거의 발생하지 않습니다. 어색한. 피가 입니다 사용하는 이유 . Thread
SimpleDateFormat
javax.time
SimpleDateFormat
이 발생 합니다. '고가' (버려짐), 중간 문자열 (버려짐) 및 파싱 비용. 그것은이다 솔루션,하지만하지 않는 것이 좋습니다.
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());
import java.sql.Date
파일에 있으면 발생 합니다 : 항상 던지는 toInstant()
방법 java.sql.Date
.
public static LocalDate Date2LocalDate(Date date) {
return LocalDate.parse(date.toString(), DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy"))
이 형식은 Date#tostring
public String toString() {
// "EEE MMM dd HH:mm:ss zzz yyyy";
BaseCalendar.Date date = normalize();
StringBuilder sb = new StringBuilder(28);
int index = date.getDayOfWeek();
if (index == BaseCalendar.SUNDAY) {
index = 8;
}
convertToAbbr(sb, wtb[index]).append(' '); // EEE
convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' '); // MMM
CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append(' '); // dd
CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':'); // HH
CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' '); // ss
TimeZone zi = date.getZone();
if (zi != null) {
sb.append(zi.getDisplayName(date.isDaylightTime(), TimeZone.SHORT, Locale.US)); // zzz
} else {
sb.append("GMT");
}
sb.append(' ').append(date.getYear()); // yyyy
return sb.toString();
}
JBoss EAP 6에서 @JodaStephen의 구현에 문제가 있었으므로 http://docs.oracle.com/javase/tutorial/datetime/iso/legacy.html 의 Oracle Java Tutorial에 따라 변환을 다시 작성했습니다 .
Date input = new Date();
GregorianCalendar gregorianCalendar = (GregorianCalendar) Calendar.getInstance();
gregorianCalendar.setTime(input);
ZonedDateTime zonedDateTime = gregorianCalendar.toZonedDateTime();
zonedDateTime.toLocalDate();
이 간단한 1 줄의 문제점은 무엇입니까?
new LocalDateTime(new Date().getTime()).toLocalDate();
아래 솔루션 으로이 질문을 해결했습니다.
import org.joda.time.LocalDate;
Date myDate = new Date();
LocalDate localDate = LocalDate.fromDateFields(myDate);
System.out.println("My date using Date" Nov 18 11:23:33 BRST 2016);
System.out.println("My date using joda.time LocalTime" 2016-11-18);
이 경우 localDate는 "yyyy-MM-dd"형식으로 날짜를 인쇄합니다
java.time
Joda Time이 아니라 JDK8 의 클래스를 사용하는 솔루션을 찾고 있습니다.
LocalDate.from(Instant.ofEpochMilli(date.getTime()))
그것이 당신과 동등하지만 더 직접적이라고 생각했습니다.