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“날짜”가 아니라 타임 라인의 순간을 나타냅니다. 객체 내에 저장된 실제 데이터는 long1970-01-01T00 : 00Z (1970 GMT / UTC 시작시 자정) 이후 밀리 초 수입니다.
java.util.DateJSR-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.Date1582 년 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();
}
