[java] Java 시간대를 GMT / UTC로 강제 적용

컴퓨터에 설정된 시간대에 관계없이 시간 관련 작업을 GMT / UTC로 강제 적용해야합니다. 코드에서 편리한 방법이 있습니까?

명확히하기 위해 모든 작업에 DB 서버 시간을 사용하고 있지만 현지 시간대에 따라 형식이 나옵니다.

감사!



답변

OP는이 질문에 응답하여 실행중인 JVM의 단일 인스턴스에 대한 기본 시간대를 변경하고 user.timezone시스템 속성을 설정합니다 .

java -Duser.timezone=GMT ... <main-class>

데이터베이스에서 Date / Time / Timestamp 객체를 검색 할 때 특정 시간대를 설정해야하는 경우 객체를받는 ResultSet두 번째 형식의 getXXX메서드를 사용 Calendar합니다.

Calendar tzCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
ResultSet rs = ...;
while (rs.next()) {
    Date dateValue = rs.getDate("DateColumn", tzCal);
    // Other fields and calculations
}

또는 PreparedStatement에서 날짜 설정 :

Calendar tzCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
PreparedStatement ps = conn.createPreparedStatement("update ...");
ps.setDate("DateColumn", dateValue, tzCal);
// Other assignments
ps.executeUpdate();

이렇게하면 데이터베이스 열이 시간대 정보를 유지하지 않을 때 데이터베이스에 저장된 값이 일관되게 유지됩니다.

java.util.Datejava.sql.Date클래스는 UTC의 실제 시간 (밀리 초)을 저장합니다. 출력시 다른 시간대로 형식을 지정하려면 SimpleDateFormat. Calendar 개체를 사용하여 시간대를 값과 연결할 수도 있습니다.

TimeZone tz = TimeZone.getTimeZone("<local-time-zone>");
//...
Date dateValue = rs.getDate("DateColumn");
Calendar calValue = Calendar.getInstance(tz);
calValue.setTime(dateValue);

유용한 참조

https://docs.oracle.com/javase/9/troubleshoot/time-zone-settings-jre.htm#JSTGD377

https://confluence.atlassian.com/kb/setting-the-timezone-for-the-java-environment-841187402.html


답변

또한 이런 식으로 JVM 시간대를 설정할 수 있다면

System.setProperty("user.timezone", "EST");

또는 -Duser.timezone=GMTJVM 인수에서.


답변

Windows 2003 Server의 JVM 시간대는 항상 new Date ()에 대해 GMT를 반환하기 때문에 설정해야했습니다.

-Duser.timezone=America/Los_Angeles

또는 적절한 시간대. 시간대 목록을 찾는 것도 약간 어려웠습니다.

다음은 두 가지 목록입니다.

http://wrapper.tanukisoftware.com/doc/english/prop-timezone.html

http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=%2Frzatz%2F51%2Fadmin%2Freftz.htm


답변

TimeZone.setDefault () 사용하여 시간대를 변경할 수 있습니다 .

TimeZone.setDefault(TimeZone.getTimeZone("GMT"))


답변

저에게는 빠른 SimpleDateFormat,

  private static final SimpleDateFormat GMT = new SimpleDateFormat("yyyy-MM-dd");
  private static final SimpleDateFormat SYD = new SimpleDateFormat("yyyy-MM-dd");
  static {
      GMT.setTimeZone(TimeZone.getTimeZone("GMT"));
    SYD.setTimeZone(TimeZone.getTimeZone("Australia/Sydney"));
  }

그런 다음 다른 시간대로 날짜 형식을 지정하십시오.


답변

DB에서 원시 형식 (긴 타임 스탬프 또는 자바의 날짜)으로 시간을 검색 한 다음 SimpleDateFormat을 사용하여 형식을 지정하거나 Calendar를 사용하여 조작합니다. 두 경우 모두 사용하기 전에 객체의 시간대를 설정해야합니다.

자세한 내용은 SimpleDateFormat.setTimeZone(..)Calendar.setTimeZone(..)참조


답변

tl; dr

String sql = "SELECT CURRENT_TIMESTAMP ;

OffsetDateTime odt = myResultSet.getObject( 1 , OffsetDateTime.class ) ;

기본 시간대에 대해 호스트 OS 또는 JVM에 의존하지 마십시오.

원하는 / 예상 시간대를 명시 적으로 나타내는 모든 코드를 작성하는 것이 좋습니다. JVM의 현재 기본 시간대에 의존 할 필요가 없습니다. JVM의 현재 기본 시간대는 .을 호출하는 모든 스레드의 모든 코드로 런타임 중에 언제든지 변경 될 수 있습니다 TimeZone.setDefault. 이러한 호출은 해당 JVM 내의 모든 앱에 즉시 영향을 미칩니다.

java.time

다른 답변 중 일부는 정확했지만 이제는 구식입니다. Java의 초기 버전과 함께 번들로 제공되는 끔찍한 날짜-시간 클래스는 날짜-시간 처리의 복잡성과 미묘함을 이해하지 못한 사람들이 작성한 결함이있었습니다.

레거시 날짜-시간 클래스는 JSR 310에 정의 된 java.time 클래스 로 대체되었습니다 .

시간대를 나타내려면을 사용하십시오 ZoneId. UTC로부터의 오프셋을 나타내려면 ZoneOffset. 오프셋은 단지 본초 자오선보다 몇 시간-분-초 앞이나 뒤에 있습니다. 시간대는 훨씬 더 많습니다. 시간대는 특정 지역의 사람들이 사용하는 오프셋에 대한 과거, 현재 및 미래 변경 내역입니다.

GMT / UTC에 대한 모든 시간 관련 작업을 강제해야합니다.

0 시간-분-초 오프셋의 경우 상수를 사용하십시오 ZoneOffset.UTC.

Instant

UTC로 현재 순간을 캡처하려면 Instant. 이 클래스는 정의에 따라 항상 UTC로 순간을 나타냅니다.

Instant instant = Instant.now() ;  // Capture current moment in UTC.

ZonedDateTime

특정 지역의 사람들이 사용하는 벽시계 시간을 통해 같은 순간을 보려면 시간대를 조정하십시오. 같은 순간, 타임 라인의 같은 지점, 다른 벽시계 시간.

ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

데이터 베이스

데이터베이스를 언급합니다.

데이터베이스에서 순간을 검색하려면 열이 SQL 표준과 유사한 데이터 유형이어야합니다 TIMESTAMP WITH TIME ZONE. 문자열이 아닌 객체를 검색합니다. JDBC 4.2 이상에서는 데이터베이스와 java.time 객체를 교환 할 수 있습니다 . 는 OffsetDateTime동안, JDBC에 필요한 InstantZonedDateTime선택 사항입니다.

OffsetDateTime odt = myResultSet.getObject(  , OffsetDateTime.class ) ;

대부분의 데이터베이스와 드라이버에서 UTC에서 볼 수있는 순간을 얻게 될 것입니다. 그러나 그렇지 않은 경우 다음 두 가지 방법 중 하나로 조정할 수 있습니다.

  • 추출 Instant: odt.toInstant()
  • 주어진 오프셋에서 0의 오프셋으로 조정합니다. OffsetDateTime odtUtc = odt.withOffsetSameInstant (ZoneOffset.UTC);`.

Java (레거시 및 최신 모두) 및 표준 SQL의 날짜-시간 유형 표


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 클래스는 어디서 구할 수 있습니까?