[java] LocalDateTime을 UTC의 LocalDateTime으로 변환

LocalDateTime을 UTC의 LocalDateTime으로 변환합니다.

LocalDateTime convertToUtc(LocalDateTime date) {

    //do conversion

}

나는 인터넷을 통해 검색했다. 그러나 해결책을 얻지 못했습니다.



답변

나는 개인적으로 선호한다

LocalDateTime.now(ZoneOffset.UTC);

가장 읽기 쉬운 옵션이기 때문입니다.


답변

더 간단한 방법이 있습니다

LocalDateTime.now(Clock.systemUTC())


답변

LocalDateTime은 영역 정보를 포함하지 않습니다. ZonedDatetime은 그렇습니다.

LocalDateTime을 UTC로 변환하려면 먼저 ZonedDateTime으로 래핑해야합니다.

아래와 같이 변환 할 수 있습니다.

LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt.toLocalTime());

ZonedDateTime ldtZoned = ldt.atZone(ZoneId.systemDefault());

ZonedDateTime utcZoned = ldtZoned.withZoneSameInstant(ZoneId.of("UTC"));

System.out.println(utcZoned.toLocalTime());


답변

아래를 사용하십시오. 현지 날짜 시간을 취하고 시간대를 사용하여 UTC로 변환합니다. 당신은 그것을 기능을 만들 필요가 없습니다.

ZonedDateTime nowUTC = ZonedDateTime.now(ZoneOffset.UTC);
System.out.println(nowUTC.toString());

ZonedDateTime의 LocalDateTime 부분을 가져와야하는 경우 다음을 사용할 수 있습니다.

nowUTC.toLocalDateTime();

다음은 datetime 열에 기본값 UTC_TIMESTAMP 를 추가 할 수 없기 때문에 내 응용 프로그램에서 UTC 시간을 삽입하기 위해 사용하는 정적 메서드 입니다.

public static LocalDateTime getLocalDateTimeInUTC(){
    ZonedDateTime nowUTC = ZonedDateTime.now(ZoneOffset.UTC);

    return nowUTC.toLocalDateTime();
}


답변

다음은 현재 영역에서 UTC로 로컬 날짜 시간을 직접 변환하는 유틸리티 메서드를 포함하여 로컬 날짜 시간을 영역에서 영역으로 변환하는 데 사용할 수있는 간단한 유틸리티 클래스입니다 (기본 방법을 사용하여 실행하고 결과를 볼 수 있음). 간단한 테스트) :

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

public final class DateTimeUtil {
    private DateTimeUtil() {
        super();
    }

    public static void main(final String... args) {
        final LocalDateTime now = LocalDateTime.now();
        final LocalDateTime utc = DateTimeUtil.toUtc(now);

        System.out.println("Now: " + now);
        System.out.println("UTC: " + utc);
    }

    public static LocalDateTime toZone(final LocalDateTime time, final ZoneId fromZone, final ZoneId toZone) {
        final ZonedDateTime zonedtime = time.atZone(fromZone);
        final ZonedDateTime converted = zonedtime.withZoneSameInstant(toZone);
        return converted.toLocalDateTime();
    }

    public static LocalDateTime toZone(final LocalDateTime time, final ZoneId toZone) {
        return DateTimeUtil.toZone(time, ZoneId.systemDefault(), toZone);
    }

    public static LocalDateTime toUtc(final LocalDateTime time, final ZoneId fromZone) {
        return DateTimeUtil.toZone(time, fromZone, ZoneOffset.UTC);
    }

    public static LocalDateTime toUtc(final LocalDateTime time) {
        return DateTimeUtil.toUtc(time, ZoneId.systemDefault());
    }
}


답변

질문?

답변과 질문을 살펴보면 질문이 크게 수정 된 것 같습니다. 따라서 현재 질문에 답하려면 :

LocalDateTime을 UTC의 LocalDateTime으로 변환합니다.

시간대?

LocalDateTime시간대에 대한 정보를 저장하지 않으며 기본적으로 연, 월, 일,시, 분, 초 및 더 작은 단위의 값을 보유합니다. 그래서 중요한 질문은 : 원본의 시간대는 무엇입니까 LocalDateTime?이미 UTC 일 수도 있으므로 변환 할 필요가 없습니다.

시스템 기본 시간대

어쨌든 질문을 한 것을 고려할 때 원래 시간이 시스템 기본 시간대에 있고 UTC로 변환하고 싶다는 의미 일 것입니다. 일반적으로 LocalDateTime객체는 LocalDateTime.now()시스템 기본 시간대의 현재 시간을 반환하는 을 사용하여 생성되기 때문 입니다. 이 경우 변환은 다음과 같습니다.

LocalDateTime convertToUtc(LocalDateTime time) {
    return time.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
}

변환 프로세스의 예 :

2019-02-25 11:39 // [time] original LocalDateTime without a timezone
2019-02-25 11:39 GMT+1 // [atZone] converted to ZonedDateTime (system timezone is Madrid)
2019-02-25 10:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime
2019-02-25 10:39 // [toLocalDateTime] losing the timezone information

명시 적 시간대

다른 경우에는 변환 할 시간의 시간대를 명시 적으로 지정하면 변환은 다음과 같습니다.

LocalDateTime convertToUtc(LocalDateTime time, ZoneId zone) {
    return time.atZone(zone).withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
}

변환 프로세스의 예 :

2019-02-25 11:39 // [time] original LocalDateTime without a timezone
2019-02-25 11:39 GMT+2 // [atZone] converted to ZonedDateTime (zone is Europe/Tallinn)
2019-02-25 09:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime
2019-02-25 09:39 // [toLocalDateTime] losing the timezone information

atZone()방법

atZone()메서드 의 결과는 DST (일광 절약 시간)를 포함하여 시간대의 모든 규칙을 고려하므로 인수로 전달 된 시간에 따라 다릅니다. 예에서 시간은 2 월 25 일이고 유럽에서는 겨울철 (DST 없음)을 의미합니다.

작년과 8 월 25 일과 같이 다른 날짜를 사용한다면 DST를 고려하면 결과가 달라집니다.

2018-08-25 11:39 // [time] original LocalDateTime without a timezone
2018-08-25 11:39 GMT+3 // [atZone] converted to ZonedDateTime (zone is Europe/Tallinn)
2018-08-25 08:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime
2018-08-25 08:39 // [toLocalDateTime] losing the timezone information

GMT 시간은 변경되지 않습니다. 따라서 다른 시간대의 오프셋이 조정됩니다. 이 예에서 에스토니아의 여름 시간은 GMT + 3이고 겨울 시간은 GMT + 2입니다.

또한 시간을 지정하면 시계를 한 시간 뒤로 전환하는 전환이 가능합니다. 예 : 에스토니아의 경우 2018 년 10 월 28 일 03:30은 두 가지 다른 시간을 의미 할 수 있습니다.

2018-10-28 03:30 GMT+3 // summer time [UTC 2018-10-28 00:30]
2018-10-28 04:00 GMT+3 // clocks are turned back 1 hour [UTC 2018-10-28 01:00]
2018-10-28 03:00 GMT+2 // same as above [UTC 2018-10-28 01:00]
2018-10-28 03:30 GMT+2 // winter time [UTC 2018-10-28 01:30]

오프셋을 수동으로 지정하지 않으면 (GMT + 2 또는 GMT + 3) 03:30시간대 의 시간 Europe/Tallinn은 두 개의 다른 UTC 시간과 두 개의 다른 오프셋을 의미 할 수 있습니다.

요약

보시다시피 최종 결과는 인수로 전달 된 시간의 시간대에 따라 다릅니다. 시간대는 LocalDateTime객체 에서 추출 할 수 없기 때문에 UTC로 변환하려면 어떤 시간대인지 알아야합니다.


답변

tldr : 그렇게 할 수있는 방법이 없습니다. 그렇게하려고하면 LocalDateTime이 잘못됩니다.

그 이유는 인스턴스가 생성 된 후 LocalDateTime 이 시간대를 기록하지 않기 때문입니다 . 시간대가없는 날짜 시간을 특정 시간대를 기반으로하는 다른 날짜 시간으로 변환 할 수 없습니다.

실제로 목적이 임의의 결과를 얻는 것이 아니라면 프로덕션 코드에서 LocalDateTime.now () 를 호출해서는 안됩니다. 이와 같이 LocalDateTime 인스턴스 를 구성 할 때이 인스턴스에는 현재 서버의 시간대를 기준으로 만 날짜 시간이 포함됩니다. 즉,이 코드는 다른 시간대 구성으로 서버를 실행하는 경우 다른 결과를 생성합니다.

LocalDateTime 은 날짜 계산을 단순화 할 수 있습니다. 보편적으로 사용할 수있는 실제 데이터 시간을 원한다면 ZonedDateTime 또는 OffsetDateTime을 사용 하십시오 : https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html .