Programming

java.util.Date의 시간대를 설정하는 방법은 무엇입니까?

procodes 2020. 5. 9. 17:01
반응형

java.util.Date의 시간대를 설정하는 방법은 무엇입니까?


java.util.Date에서를 구문 분석 String했지만 로컬 시간대를 date객체 의 시간대로 설정하고 있습니다.

구문 분석 String표준 시간대가 지정되지 않았습니다 Date. date개체 의 특정 시간대를 설정하고 싶습니다 .

어떻게해야합니까?


DateFormat을 사용하십시오. 예를 들어

SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
isoFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = isoFormat.parse("2010-05-23T09:01:02");

주의하십시오 java.util.Date물체가 그 자체로 어떤 시간대 정보를 포함하지 않는다 - 당신이에 시간대를 설정할 수 없습니다 Date객체입니다. Date개체에 포함 된 유일한 것은 "epoch"이후 1970 년 1 월 1 일 00:00:00 UTC 이후의 밀리 초입니다.

ZZ 코더가 보여 주듯이, DateFormat날짜와 시간을 표시 할 시간대를 알려주기 위해 객체 의 시간대를 설정합니다 .


tl; dr

… 문자열에서 파싱… 시간대가 지정되지 않았습니다… 특정 시간대를 설정하고 싶습니다

LocalDateTime.parse( "2018-01-23T01:23:45.123456789" )  // Parse string, lacking an offset-from-UTC and lacking a time zone, as a `LocalDateTime`.
    .atZone( ZoneId.of( "Africa/Tunis" ) )              // Assign the time zone for which you are certain this date-time was intended. Instantiates a `ZonedDateTime` object.

juDate에 시간대 없음

다른 정답이 언급했듯이 java.util.Date에는 시간대 이 없습니다 . UTC / GMT (표준 시간대 오프셋 없음)를 나타냅니다 . toString메소드가 문자열 표현을 생성 할 때 JVM의 기본 시간대를 적용 하기 때문에 매우 혼란 스럽습니다 .

사법을 피하십시오

이것과 다른 많은 이유로 인해 내장 java.util.Date & .Calendar & java.text.SimpleDateFormat을 사용하지 않아야합니다. 그들은 악명 높은 문제입니다.

대신 Java 8 과 함께 제공되는 java.time 패키지를 사용하십시오 .

java.time

java.time 클래스는 타임 라인에서 세 가지 방법으로 모멘트를 나타낼 수 있습니다.

  • UTC ( Instant)
  • (오프셋 OffsetDateTime하여 ZoneOffset)
  • 시간 영역과 ( ZonedDateTimeZoneId)

Instant

에서 java.time , 기본 빌딩 블록은 InstantUTC의 타임 라인에 순간. Instant많은 비즈니스 로직에 객체를 사용하십시오 .

Instant instant = Instant.now();

OffsetDateTime

UTC오프셋을 적용하여 일부 지역의 벽시계 시간 을 조정하십시오 .

를 적용 ZoneOffset하려면을 적용하십시오 OffsetDateTime.

ZoneOffset zoneOffset = ZoneOffset.of( "-04:00" );
OffsetDateTime odt = OffsetDateTime.ofInstant( instant , zoneOffset );

ZonedDateTime

표준 시간대 , 오프셋 일광 절약 시간 (DST) 과 같은 예외 처리 규칙 을 적용하는 것이 좋습니다 .

에 a ZoneId적용하여 a Instant얻습니다 ZonedDateTime. 항상 올바른 시간대 이름을 지정하십시오 . 안 등 3 ~ 4 약어를 사용하지 EST또는 IST도 독특한도 표준화됩니다.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

LocalDateTime

입력 문자열에 오프셋 또는 영역 표시기가없는 경우 a로 구문 분석하십시오 LocalDateTime.

원하는 시간대를 확신 할 수있는 경우 a ZoneId지정하여을 생성하십시오 ZonedDateTime. 위의 tl; dr 섹션에서 위의 코드 예제를 참조하십시오 .

형식화 된 문자열

toString이 세 클래스 중 하나 에서 메소드를 호출하여 표준 ISO 8601 형식 의 날짜-시간 값을 나타내는 문자열을 생성하십시오 . ZonedDateTime클래스는 표준 시간대 이름을 괄호 안에 추가하여 표준 형식을 확장합니다.

String outputInstant = instant.toString(); // Ex: 2011-12-03T10:15:30Z
String outputOdt = odt.toString(); // Ex: 2007-12-03T10:15:30+01:00
String outputZdt = zdt.toString(); // Ex: 2007-12-03T10:15:30+01:00[Europe/Paris]

다른 형식의 경우 DateTimeFormatter클래스를 사용하십시오 . 일반적으로 해당 클래스가 사용자의 예상되는 언어 및 문화적 규범을 사용하여 현지화 된 형식을 생성하도록하는 것이 가장 좋습니다. 또는 특정 형식을 지정할 수 있습니다.


java.time에 대하여

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

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

자세한 내용은 Oracle Tutorial을 참조하십시오 . 많은 예제와 설명을 보려면 스택 오버플로를 검색하십시오. 사양은 JSR 310 입니다.

java.time 객체를 데이터베이스와 직접 교환 할 수 있습니다 . JDBC 4.2 이상을 준수 하는 JDBC 드라이버를 사용하십시오 . 문자열이 필요없고 수업이 필요 없습니다 .java.sql.*

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

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.


Joda-Time

While Joda-Time is still actively maintained, its makers have told us to migrate to java.time as soon as is convenient. I leave this section intact as a reference, but I suggest using the java.time section above instead.

In Joda-Time, a date-time object (DateTime) truly does know its assigned time zone. That means an offset from UTC and the rules and history of that time zone’s Daylight Saving Time (DST) and other such anomalies.

String input = "2014-01-02T03:04:05";
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" );
DateTime dateTimeIndia = new DateTime( input, timeZone );
DateTime dateTimeUtcGmt = dateTimeIndia.withZone( DateTimeZone.UTC );

Call the toString method to generate a String in ISO 8601 format.

String output = dateTimeIndia.toString();

Joda-Time also offers rich capabilities for generating all kinds of other String formats.

If required, you can convert from Joda-Time DateTime to a java.util.Date.

Java.util.Date date = dateTimeIndia.toDate();

Search StackOverflow for "joda date" to find many more examples, some quite detailed.


Actually there is a time zone embedded in a java.util.Date, used for some internal functions (see comments on this Answer). But this internal time zone is not exposed as a property, and cannot be set. This internal time zone is not the one used by the toString method in generating a string representation of the date-time value; instead the JVM’s current default time zone is applied on-the-fly. So, as shorthand, we often say “j.u.Date has no time zone”. Confusing? Yes. Yet another reason to avoid these tired old classes.


You could also set the timezone at the JVM level

Date date1 = new Date();
System.out.println(date1);

TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
// or pass in a command line arg: -Duser.timezone="UTC"

Date date2 = new Date();
System.out.println(date2);

output:

Thu Sep 05 10:11:12 EDT 2013
Thu Sep 05 14:11:12 UTC 2013

If you must work with only standard JDK classes you can use this:

/**
 * Converts the given <code>date</code> from the <code>fromTimeZone</code> to the
 * <code>toTimeZone</code>.  Since java.util.Date has does not really store time zome
 * information, this actually converts the date to the date that it would be in the
 * other time zone.
 * @param date
 * @param fromTimeZone
 * @param toTimeZone
 * @return
 */
public static Date convertTimeZone(Date date, TimeZone fromTimeZone, TimeZone toTimeZone)
{
    long fromTimeZoneOffset = getTimeZoneUTCAndDSTOffset(date, fromTimeZone);
    long toTimeZoneOffset = getTimeZoneUTCAndDSTOffset(date, toTimeZone);

    return new Date(date.getTime() + (toTimeZoneOffset - fromTimeZoneOffset));
}

/**
 * Calculates the offset of the <code>timeZone</code> from UTC, factoring in any
 * additional offset due to the time zone being in daylight savings time as of
 * the given <code>date</code>.
 * @param date
 * @param timeZone
 * @return
 */
private static long getTimeZoneUTCAndDSTOffset(Date date, TimeZone timeZone)
{
    long timeZoneDSTOffset = 0;
    if(timeZone.inDaylightTime(date))
    {
        timeZoneDSTOffset = timeZone.getDSTSavings();
    }

    return timeZone.getRawOffset() + timeZoneDSTOffset;
}

Credit goes to this post.


java.util.Calendar is the usual way to handle time zones using just JDK classes. Apache Commons has some further alternatives/utilities that may be helpful. Edit Spong's note reminded me that I've heard really good things about Joda-Time (though I haven't used it myself).


Convert the Date to String and do it with SimpleDateFormat.

    SimpleDateFormat readFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    readFormat.setTimeZone(TimeZone.getTimeZone("GMT" + timezoneOffset));
    String dateStr = readFormat.format(date);
    SimpleDateFormat writeFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    Date date = writeFormat.parse(dateStr);

If anyone ever needs this, if you need to convert an XMLGregorianCalendar timezone to your current timezone from UTC, then all you need to do is set the timezone to 0, then call toGregorianCalendar() - it will stay the same timezone, but the Date knows how to convert it to yours, so you can get the data from there.

XMLGregorianCalendar xmlStartTime = DatatypeFactory.newInstance()
    .newXMLGregorianCalendar(
        ((GregorianCalendar)GregorianCalendar.getInstance());
xmlStartTime.setTimezone(0);
GregorianCalendar startCalendar = xmlStartTime.toGregorianCalendar();
Date startDate = startCalendar.getTime();
XMLGregorianCalendar xmlStartTime = DatatypeFactory.newInstance()
    .newXMLGregorianCalendar(startCalendar);
xmlStartTime.setHour(startDate.getHours());
xmlStartTime.setDay(startDate.getDate());
xmlStartTime.setMinute(startDate.getMinutes());
xmlStartTime.setMonth(startDate.getMonth()+1);
xmlStartTime.setTimezone(-startDate.getTimezoneOffset());
xmlStartTime.setSecond(startDate.getSeconds());
xmlStartTime.setYear(startDate.getYear() + 1900);
System.out.println(xmlStartTime.toString());

Result:

2015-08-26T12:02:27.183Z
2015-08-26T14:02:27.183+02:00

This code was helpful in an app I'm working on:

    Instant date = null;
    Date sdf = null;
    String formatTemplate = "EEE MMM dd yyyy HH:mm:ss";
    try {
        SimpleDateFormat isoFormat = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss");
        isoFormat.setTimeZone(TimeZone.getTimeZone(ZoneId.of("US/Pacific")));
        sdf = isoFormat.parse(timeAtWhichToMakeAvailable);
        date = sdf.toInstant();

    } catch (Exception e) {
        System.out.println("did not parse: " + timeAtWhichToMakeAvailable);
    }

    LOGGER.info("timeAtWhichToMakeAvailable: " + timeAtWhichToMakeAvailable);
    LOGGER.info("sdf: " + sdf);
    LOGGER.info("parsed to: " + date);

참고URL : https://stackoverflow.com/questions/2891361/how-to-set-time-zone-of-a-java-util-date

반응형