Java 8에는 날짜 및 시간에 대한 완전히 새로운 API가 있습니다. 이 API에서 가장 유용한 클래스 중 하나는 LocalDateTime
시간대 독립적 날짜-시간 값을 보유하기위한입니다.
java.util.Date
이 목적으로 레거시 클래스 를 사용하는 수백만 줄의 코드가있을 것입니다 . 따라서 이전 코드와 새 코드를 인터페이스 할 때 두 코드 사이를 변환해야합니다. 이를 달성하기위한 직접적인 방법이없는 것처럼 보이면 어떻게 할 수 있습니까?
답변
짧은 답변:
Date in = new Date();
LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault());
Date out = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
설명 : (에 따라 이 문제 에 대한 LocalDate
)
이름에도 불구하고 java.util.Date
“날짜”가 아니라 타임 라인의 순간을 나타냅니다. 객체 내에 저장된 실제 데이터는 long
1970-01-01T00 : 00Z (1970 GMT / UTC 시작시 자정) 이후 밀리 초 수입니다.
java.util.Date
JSR-310 과 동등한 클래스 는 다음 Instant
과 같이 변환을 제공하는 편리한 방법이 있습니다.
Date input = new Date();
Instant instant = input.toInstant();
Date output = Date.from(instant);
java.util.Date
인스턴스는 시간대의 개념이 없습니다. 당신이 호출하면이 이상하게 보일 수도 toString()
A의 java.util.Date
(가) 때문에, toString
시간 영역에 상대적입니다. 그러나이 메소드는 실제로 Java의 기본 시간대를 사용하여 문자열을 제공합니다. 시간대는의 실제 상태의 일부가 아닙니다 java.util.Date
.
은 Instant
또한 시간대에 대한 정보가 포함되어 있지 않습니다. 따라서에서 Instant
날짜를 현지 날짜 로 변환하려면 시간대를 지정해야합니다. 기본 영역 ZoneId.systemDefault()
일 수도 있고 사용자 기본 설정의 시간대와 같이 응용 프로그램이 제어하는 시간대 일 수도 있습니다. LocalDateTime
인스턴트 및 시간대를 모두 사용하는 편리한 팩토리 방법이 있습니다.
Date in = new Date();
LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault());
반대로 LocalDateTime
시간대는 atZone(ZoneId)
메소드 를 호출하여 지정됩니다 . 그런 ZonedDateTime
다음를 다음으로 직접 변환 할 수 있습니다 Instant
.
LocalDateTime ldt = ...
ZonedDateTime zdt = ldt.atZone(ZoneId.systemDefault());
Date output = Date.from(zdt.toInstant());
에서 LocalDateTime
로 변환 ZonedDateTime
하면 예기치 않은 동작이 발생할 가능성이 있습니다. 일광 절약 시간 제로 인해 모든 현지 날짜-시간이 존재하지 않기 때문입니다. 가을 / 가을에는 동일한 현지 날짜-시간이 두 번 발생하는 현지 타임 라인이 겹칩니다. 봄에는 한 시간이 사라지는 간격이 있습니다. atZone(ZoneId)
변환이 수행 할 작업 에 대한 자세한 정의 는 Javadoc을 참조하십시오 .
요약하면 a java.util.Date
를 a 로 왕복 LocalDateTime
하고 다시 a 로 왕복하면 java.util.Date
일광 절약 시간 제로 인해 다른 순간으로 끝날 수 있습니다.
추가 정보 : 아주 오래된 날짜에 영향을 줄 또 다른 차이점이 있습니다. java.util.Date
1582 년 10 월 15 일에 변경되는 달력을 사용하며, 그 이전의 날짜는 그레고리력 대신 Julian 달력을 사용합니다. 반대로 java.time.*
ISO 캘린더 시스템 (Gregorian과 동일)을 항상 사용합니다. 대부분의 경우 ISO 캘린더 시스템이 원하는 것이지만 1582 년 이전의 날짜를 비교할 때 이상한 효과가 나타날 수 있습니다.
답변
여기에 내가 생각해 낸 것이 있습니다 (그리고 모든 Date Time 수수께끼와 마찬가지로 이상한 시간대-윤년-일광 조정에 따라 반박 될 것입니다 : D)
라운드 트립 : Date
<<->>LocalDateTime
주어진: Date date = [some date]
(1) LocalDateTime
<< Instant
<<Date
Instant instant = Instant.ofEpochMilli(date.getTime());
LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
(2) Date
<< Instant
<<LocalDateTime
Instant instant = ldt.toInstant(ZoneOffset.UTC);
Date date = Date.from(instant);
예:
주어진:
Date date = new Date();
System.out.println(date + " long: " + date.getTime());
(1) LocalDateTime
<< Instant
<< Date
:
만들기 Instant
에서 Date
:
Instant instant = Instant.ofEpochMilli(date.getTime());
System.out.println("Instant from Date:\n" + instant);
만들기 Date
에서 Instant
(필요는 없습니다 만, 그림) :
date = Date.from(instant);
System.out.println("Date from Instant:\n" + date + " long: " + date.getTime());
만들기 LocalDateTime
에서Instant
LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
System.out.println("LocalDateTime from Instant:\n" + ldt);
(2) Date
<< Instant
<<LocalDateTime
만들기 Instant
에서 LocalDateTime
:
instant = ldt.toInstant(ZoneOffset.UTC);
System.out.println("Instant from LocalDateTime:\n" + instant);
만들기 Date
에서 Instant
:
date = Date.from(instant);
System.out.println("Date from Instant:\n" + date + " long: " + date.getTime());
출력은 다음과 같습니다.
Fri Nov 01 07:13:04 PDT 2013 long: 1383315184574
Instant from Date:
2013-11-01T14:13:04.574Z
Date from Instant:
Fri Nov 01 07:13:04 PDT 2013 long: 1383315184574
LocalDateTime from Instant:
2013-11-01T14:13:04.574
Instant from LocalDateTime:
2013-11-01T14:13:04.574Z
Date from Instant:
Fri Nov 01 07:13:04 PDT 2013 long: 1383315184574
답변
기본 시간대가 필요한 경우 훨씬 편리한 방법입니다.
Date d = java.sql.Timestamp.valueOf( myLocalDateTime );
답변
다음은 새 API LocalDateTime에서 java.util.date로 변환 할 때 작동하는 것 같습니다.
Date.from(ZonedDateTime.of({time as LocalDateTime}, ZoneId.systemDefault()).toInstant());
역변환은 (희망적으로) 비슷한 방식으로 달성 될 수 있습니다 …
그것이 도움이되기를 바랍니다 …
답변
모든 것이 여기에 있습니다 : http://blog.progs.be/542/date-to-java-time
“라운드 트리핑”의 대답은 정확하지 않습니다.
LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
시스템 시간대가 UTC / GMT가 아닌 경우 시간을 변경하십시오!
답변
가장 빠른 방법은 LocalDateTime
-> Date
입니다 :
Date.from(ldt.toInstant(ZoneOffset.UTC))
답변
이것이 가장 간단한 방법인지 또는 가장 좋은 방법인지 또는 함정이 있는지 확실하지 않지만 작동합니다.
static public LocalDateTime toLdt(Date date) {
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(date);
ZonedDateTime zdt = cal.toZonedDateTime();
return zdt.toLocalDateTime();
}
static public Date fromLdt(LocalDateTime ldt) {
ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.systemDefault());
GregorianCalendar cal = GregorianCalendar.from(zdt);
return cal.getTime();
}