Java 8에서 UTC + 0 날짜를 얻는 방법은 무엇입니까?


108

Java의 Date 클래스에 문제가 있습니다. 날짜 클래스는 로컬 컴퓨터 날짜를 반환하지만 UTC-0이 필요합니다.

나는 봤는데 JavaScript에 대한 훌륭한 솔루션을 찾았지만 Java에는 유용하지 않습니다.

Java 8에서 UTC + 0 날짜를 얻는 방법은 무엇입니까?


12
java.util.Date로컬 시스템 날짜가 아닙니다. 항상 UTC + 00 : 00을 기준으로 1970-01-01 이후 경과 된 밀리 초로 정의됩니다. 메서드의 동작 toString()이 실제로 현지 시간대의 표현을 사용하는 데 혼란을 줄 수 있습니다.
Meno Hochschild

한 가지 가능한 대답은 질문에서 찾을 수 있습니다 stackoverflow.com/questions/45350095/...을
프리 야 자이나교을

답변:


146

Java 8을 사용하면 다음을 작성할 수 있습니다.

OffsetDateTime utc = OffsetDateTime.now(ZoneOffset.UTC);

귀하의 의견에 답하려면 날짜를 날짜로 변환하거나 (레거시 코드에 의존하지 않는 한 이유를 알 수 없습니다) epoch 이후 밀리 초로 변환 할 수 있습니다.

Date date = Date.from(utc.toInstant());
long epochMillis = utc.toEpochSecond() * 1000;

1
감사. ZonedDateTime을 Date 또는 long (ms)으로 변환 할 수 있습니까?
Mark

7
이 답변의 코드는 기술적으로 작동하지만 전체 시간대가 아닌 단순한 UTC 오프셋으로 작업 하는 OffsetDateTime것보다 사용하는 것이 더 적절 하지 ZonedDateTime않습니까?
Basil Bourque

179

tl; dr

Instant.now()

java.time

Java의 초기 버전에 번들로 제공되는 귀찮은 이전 날짜-시간 클래스는 Java 8 이상에 빌드 된 java.time 클래스 로 대체되었습니다 . 보다Oracle Tutorial을 . 대부분의 기능은 자바 6 7 백 포팅 된 ThreeTen - 백 포트 및 상기 안드로이드 적응 ThreeTenABP .

Instant

Instant 있는 타임 라인에 잠시 나타냅니다 UTC 까지의 해상도를 가진 나노초 .

Instant instant = Instant.now();

그만큼 toString 메서드는 표준 ISO 8601 형식 중 하나를 사용하여 날짜-시간 값을 나타내는 텍스트가있는 String 개체를 생성합니다 .

String output = instant.toString();  

2016-06-27T19 : 15 : 25.864Z

Instant클래스는 java.time의 기본 빌딩 블록 클래스입니다. 일반적으로 가장 좋은 방법은 UTC로 날짜-시간 값을 추적, 저장 및 교환하는 것이므로 날짜-시간을 처리 할 때이 클래스를 사용해야합니다.

OffsetDateTime

그러나 Instant대체 형식으로 문자열을 생성하기위한 형식 지정 옵션이없는 등의 제한이 있습니다. 유연성을 높이 Instant려면에서 OffsetDateTime. offset-from-UTC를 지정하십시오 . java.time에서는 객체를 의미 ZoneOffset합니다. 여기에서는 편리한 상수를 사용할 수 있도록 UTC (+00)를 고수하고 싶습니다.ZoneOffset.UTC .

OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC );

2016-06-27T19 : 15 : 25.864Z

또는 Instant 수업을 .

OffsetDateTime.now( ZoneOffset.UTC )

이제 OffsetDateTime손에 물건을 들고 다음을 사용할 수 있습니다.DateTimeFormatter 하여 대체 형식의 텍스트로 String 개체를 만들 있습니다. .NET을 사용하는 많은 예제를 보려면 Stack Overflow를 검색하세요 DateTimeFormatter.

ZonedDateTime

특정 시간대의 벽시계 시간 을 표시 하려면ZoneId 를 하여 ZonedDateTime.

이 예에서는 몬트리올 시간대를 적용합니다. 여름에는 DST (일광 절약 시간제) 말도 안되는 상황에서 영역의 오프셋이 -04:00. 참고 어떻게 시간의 하루는 4 시간 이전에 출력에 15대신 19시간. Instant그리고 ZonedDateTime둘 다 두 개의 다른 렌즈를 통해 본 매우 동일한 동시 적 순간을 나타냅니다.

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );

2016-06-27T15 : 15 : 25.864-04 : 00 [미주 / 몬트리올]

변환

이전 날짜-시간 클래스를 피해야하지만 필요한 경우 이전 클래스에 추가 된 새 메서드를 사용하여 변환 할 수 있습니다. 여기서 우리는 java.util.Date.from( Instant )java.util.Date::toInstant.

java.util.Date utilDate = java.util.Date.from( instant );

그리고 다른 방향으로갑니다.

Instant instant= utilDate.toInstant();

마찬가지로 GregorianCalendar(의 하위 클래스 Calendar)에 추가 된 새 메서드를 찾아 java.time.ZonedDateTime.

최신 java.time과 레거시의 날짜-시간 클래스 유형 표.

java.time 정보

java.time의 프레임 워크는 나중에 자바 8에 내장되어 있습니다. 이 클래스는 까다로운 기존에 대신 기존 과 같은 날짜 - 시간의 수업을 java.util.Date, Calendar, SimpleDateFormat.

자세한 내용은 Oracle Tutorial을 참조하십시오 . 그리고 많은 예제와 설명을 위해 Stack Overflow를 검색하십시오. 사양은 JSR 310 입니다.

Joda 타임 프로젝트는 지금에 유지 관리 모드 의로 마이그레이션을 조언 java.time의 클래스.

java.time 객체를 데이터베이스와 직접 교환 할 수 있습니다 . JDBC 4.2 이상을 준수 하는 JDBC 드라이버를 사용하십시오 . 문자열이나 클래스 가 필요하지 않습니다 . Hibernate 5 및 JPA 2.2는 java.time을 지원 합니다 .java.sql.*

java.time 클래스는 어디서 구할 수 있습니까?


3
DST가 말도 안된다고 말해 주셔서 감사합니다 :-)
prash

그래서 DST가 존재하지 않았다면 ZonedDateTime모든 ZoneId것이 하나에 매핑 되므로 ZoneOffset우리는 그냥 사용할 수 OffsetDateTime있습니까?
wilmol

1
@wilmol 아니요. 일광 절약 시간 (DST)은 정치인들이 시간대 경계와 해당 구역 내 오프셋을 재정의하기로 선택한 여러 이유 중 하나 일뿐입니다. 최근 북한은 외교적 이유로 한국과 동기화하기 위해 시계를 30 분으로 변경했습니다. 전쟁에서 침입자 / 점유자는 오프셋을 모국의 오프셋과 일치하도록 변경할 수 있습니다. 현재 정부가 DST 변경을 중지하기로 선택했지만 이전 표준 시간으로 되 돌리지 않고 DST 에 영구적 으로 머무르는 새로운 유행이 있습니다. 항상 모든 영역 변경의 오프셋에 대해 계획하십시오. 그렇지 않으면 앱이 결국 중단됩니다.
Basil Bourque

1
환상적인 대답! 시간을 내 주셔서 정말 감사합니다. :)
drognisep 19 년

ZoneId.of ( "미국 / 몬트리올"); 왜 누군가가 jdk에서 그런 것을 발명했을까요? 추악하고 역겨운 일이며 런타임까지 잘못된 것이 있는지 말하지 않습니다. 누가 그 모든 하드 코드를 기억할 수 있습니까? ENUM 클래스에서 단순화하지 않는 이유는 무엇입니까?
workplaylifecycle

4

java8에서는 Instant 이미 UTC에 있고 작업하기 편리한 클래스를 .

import java.time.Instant;

Instant ins = Instant.now();
long ts = ins.toEpochMilli();

Instant ins2 = Instant.ofEpochMilli(ts)

또는 다음을 사용할 수 있습니다.

import java.time.*;

Instant ins = Instant.now(); 

OffsetDateTime odt = ins.atOffset(ZoneOffset.UTC);
ZonedDateTime zdt = ins.atZone(ZoneId.of("UTC"));

돌아가다 Instant

Instant ins4 = Instant.from(odt);

3
아니요, 현지 시간 Instant아닙니다 . Instant에 의해 정의는 UTC입니다. 따라서 UTC에 들어 가려고이 답변에서 볼 수있는 기계 작업이 필요하지 않습니다. 은 Instant이미 입니다 UTC에. 자세한 정보와 훨씬 간단한 코드는 내 답변 을 참조하십시오 .
Basil Bourque

댓글 주셔서 감사합니다.
Abel Terefe


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.