Java 8에서 ZoneId를 ZoneOffset으로 변환하는 방법이 있습니까?


85

epoch second 및 zoneId, method1. 시스템 기본 zoneId를 사용하여 LocalDateTime으로 변환 할 수 있지만 method2에 의해 epoch second를 LocalDateTime으로 변환하는 방법을 찾지 못합니다 ZoneOffset.systemDefault.

import java.time.{Instant, LocalDateTime, ZoneId, ZoneOffset}

val epochSecond = System.currentTimeMillis() / 1000

LocalDateTime.ofInstant(Instant.ofEpochSecond(epochSecond), ZoneId.systemDefault())//method1
LocalDateTime.ofEpochSecond(epochSecond, 0, ZoneOffset.MAX)//method2

대량 가져 오기를 import java.time.{Instant, LocalDateTime, ZoneId, ZoneOffset}작동 하기 위해 어떤 언어 / 방언을 사용하고 있습니까? 그것은 unexpected tokenJava 11에서 나를위한 것입니다.
anddero

1
스칼라 수 있지만, 여기서는 정말 중요하지 수
donatas M

1
나는 이론 뒤에 논의한 java.time여기 길이를 : stackoverflow.com/a/56508200/145989
온 드라 Žižka

답변:


109

다음 ZoneOffset에서 얻을 수있는 방법은 다음과 같습니다 ZoneId.

Instant instant = Instant.now(); //can be LocalDateTime
ZoneId systemZone = ZoneId.systemDefault(); // my timezone
ZoneOffset currentOffsetForMyZone = systemZone.getRules().getOffset(instant);

주의 : ZoneId시점과 특정 장소의 기록에 따라 오프셋이 다를 수 있습니다. 따라서 다른 Instants를 선택하면 오프셋이 달라집니다.

NB2 : / / etc가 전달되는 경우 대신 ZoneId.of()a ZoneOffset를 반환 할 수 있습니다 . 따라서 UTC / GMT 오프셋이 전달되면의 과거 / 지리적 / 일광 절약 정보 가 고려되지 않습니다. 지정된 오프셋으로 작업하기 만하면됩니다.ZoneIdUTC+3GMT+2Africa/CairoInstant


현재 순간이 DST에 있으면 잘못된 값을 제공하지만 계산 당시에는 DST가 없었습니다
msangel

@msangel, 다시 확인할 수 있습니까? 아마도 ZoneId.systemDefault()코드에서 사용 하고 있고 다른 컴퓨터에서 다른 시간대를 반환합니까?
Stanislav Bashkyrtsev

나는 그것을 확인했고 다른 조건에 따라 작동합니다. 그것에 대한 답변을 업데이트했습니다.
msangel

43

일대일 매핑이 없습니다. ZoneId는 시간이 지남에 따라 서로 다른 ZoneOffset 집합이 사용되는 지리적 범위를 정의합니다. 시간대가 일광 절약 시간을 사용하는 경우 ZoneOffset은 여름과 겨울에 따라 다릅니다.

또한 일광 절약 시간제 규칙은 시간이 지남에 따라 변경 될 수 있으므로 ZoneOffset은 예를 들어 13/10/1980과 비교하여 2015/10/13에 대해 다를 수 있습니다.

따라서 특정 Instant에서 ZoneId에 대한 ZoneOffset 만 찾을 수 있습니다.

참조 https://en.wikipedia.org/wiki/Tz_database


10
LocaDate를 알고 있고 ZoneId가 있으면 어떻게 ZoneOffset으로 변환합니까? 내 사용 사례는 시간과 영역을 포함하는 문자열입니다. 영역 정보를 삭제하지 않고 문자열을 OffsetTime으로 구문 분석하고 싶습니다.
Kai Moritz

33

tl; dr

ZonedDateTime.now( 
    ZoneId.of( "America/Montreal" ) 
)

… 현재 기본 시간대…

ZonedDateTime.now( 
    ZoneId.systemDefault() 
)

세부

Stanislav Bshkyrtsev 의해 답변은 정확하고 직접 질문에 응답합니다.

그러나 Jon Skeet답변 에서 제안한 것처럼 더 큰 문제가 관련되어 있습니다.

LocalDateTime

에포크 초를 LocalDateTime으로 변환하는 방법을 찾지 못했습니다.

LocalDateTime의도적으로 시간대 또는 UTC로부터의 오프셋 개념이 없습니다. 당신이 원하는 것 같지 않습니다. 는 특정 지역이 아닌 모든 지역을 Local…의미 합니다 . 이 클래스는 않습니다 없는 순간 만 표현 가능성이 26 ~ 27에 대한 시간 (전 세계 시간대의 범위)의 범위에 따라 순간을.

Instant

현재 시간을 얻으려는 경우 epoch 초로 시작할 필요가 없습니다. 현재 Instant. 이 Instant클래스는 나노초 단위 (소수점의 최대 9 자리) 의 해상도로 타임 라인의 한 순간을 UTC 로 나타냅니다 .

Instant instant = Instant.now();

그 내부는 Instant의 수입니다 나노초 -from - 시대. 그러나 우리는 정말로 신경 쓰지 않습니다.

ZonedDateTime

특정 지역의 벽시계 시간의 렌즈를 통해 그 순간을보고 싶다면 a ZoneId를 적용 하여 ZonedDateTime.

ZoneId z = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdt = instant.atZone( z );

바로 가기로 ZonedDateTime.

ZonedDateTime zdt = ZonedDateTime.now( z );  

A ZonedDateTimeInstant내부에 있습니다. UTCzdt.toInstant() 의 기본 값과 동일한 시간을 가져 오려면 호출하십시오 . 에포크 이후로 동일한 수의 나노초, 또는 .ZonedDateTimeInstant

주어진 시대 이후 초

에포크 이후 초 수가 주어지고 에포크가 UTC ( 1970-01-01T00:00:00Z) 에서 1970 년의 첫 번째 순간 이면 해당 숫자를에 입력합니다 Instant.

long secondsSinceEpoch = 1_484_063_246L ;
Instant instant = Instant.ofEpochSecond( secondsSinceEpoch ) ;

최신 및 레거시 Java의 날짜-시간 유형 표입니다.


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 드라이버를 사용하십시오 . 문자열이나 클래스 가 필요하지 않습니다 .java.sql.*

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

ThreeTen - 추가 프로젝트 추가 클래스와 java.time를 확장합니다. 이 프로젝트는 java.time에 향후 추가 될 가능성을 입증하는 근거가됩니다. 당신은 여기에 몇 가지 유용한 클래스와 같은 찾을 수 있습니다 Interval, YearWeek, YearQuarter, 그리고 .


10

는 AS 설명서를 말한다 "이것은 주로 낮은 수준의 변환이 아닌 일반 응용 프로그램 사용을위한 것입니다."

통과 Instant하는 것은 나에게 완벽하게 의미가 있습니다. 에포크 초는 사실상의 다른 표현 Instant이므로로 변환 Instant한 다음 특정 시간대로 변환하십시오.


9

아래 내 솔루션의 처음 두 줄이 도움이 되었기를 바랍니다. 내 문제는 내가 LocalDateTime있고 시간대의 이름이 instant있었고 java.util.DateMongoDB가 원했던 것이기 때문에. 내 코드는 Scala이지만 여기서는 Java와 너무 가깝습니다. 이해하는 데 문제가 없다고 생각합니다.

val zid = ZoneId.of(tzName)                                // "America/Los_Angeles"
val zo: ZoneOffset = zid.getRules.getOffset(localDateTime) // ⇒ -07:00
                                         // 2017-03-16T18:03

val odt = OffsetDateTime.of(localDateTime, zo) // ⇒ 2017-03-16T18:03:00-07:00
val instant = odt.toInstant                    // ⇒ 2017-03-17T01:03:00Z
val issued = Date.from(instant)

1
이 답변은 내가 결국 알아 낸 일을 수행하는 방법을 찾을 때 나타난 페이지이기 때문에 여기에 게시했습니다.
gknauth

1

다음은이 시간대의 표준 시간을 얻기 위해 UTC에 추가 할 시간 (밀리 초)을 반환합니다.

TimeZone.getTimeZone(ZoneId.of("Europe/Amsterdam")).getRawOffset()

0

epoch second와 zoneId가 있습니다. Java 8에서 ZoneId를 ZoneOffset으로 변환하는 방법이 있습니까?

  1. 가져 ZonedDateTime시대의 두 번째와 존 ID와
  2. 가져 오기 ZoneOffset에서ZonedDateTime

데모:

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        // Get ZonedDateTime from epoch second and Zone Id
        ZonedDateTime zdt = Instant.ofEpochSecond(1597615462L).atZone(ZoneId.of("Europe/London"));

        // Get ZoneOffset from ZonedDateTime
        ZoneOffset offset = zdt.getOffset();

        System.out.println(offset);
    }
}

산출:

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