2017-02-22 5 views
1

내가 "2016-03-28T02:00:00+0200"으로 테스트하고 사용 날짜에서 하루를 빼면 후 잘못된 결과를 얻기LocalDateTIme 및 ZonedDateTime

일일를 뺀 후, DST를 적용하고 출력해야한다 :

: "2016-03-27T03 : 00 : 00 + 0200은"

는하지만이 무엇입니까

2016-03-26T01 : 00 + 01 : 00 [유럽/스톡홀름]

CODE :

public class DateFormatSampleCode { 
    public static void main(String[] args) 
    { 
     LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(1459123200, 0, ZoneOffset.UTC); 

     System.out.println(localDateTime); 
     localDateTime = localDateTime.minusDays(1); 
     System.out.println(localDateTime); 

     ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, ZoneId.of("Europe/Stockholm")); 

     System.out.println(zonedDateTime); 
    } 
} 

확인하고 내가 잘못 가고있는 곳을 지적 해주십시오.

+1

일광 절약 시간 개념이없는 * local * 날짜/시간에서 일을 뺄 수 없으며 일광 절약 시간제 적용을 기대합니다. – RealSkeptic

+0

@RealSkeptic 끝내는 법을 제안 해주세요. –

+0

구역화 된 날짜/시간을 원하면 ZonedDateTime을 사용하십시오. 'LocalDateTime'을 사용하지 마십시오. – RealSkeptic

답변

1

나는 내 질문에 대답 할 수 있다고 생각한다.

다음은 코드입니다.

public ZonedDateTime addDays(long myUTCTimeInSeconds, int days) { 
    Instant instant = Instant.ofEpochSecond(myUTCTimeInSeconds); 
    ZonedDateTime dateTimeWithOffSet = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault()); 
    if (localDays >= 0) { 
     dateTimeWithOffSet = dateTimeWithOffSet.plusDays(localDays); 
    } else { 
     dateTimeWithOffSet = dateTimeWithOffSet.minusDays(abs(localDays)); 
    } 
    return dateTimeWithOffSet; 
} 

시간대가 시스템의 다른 경우, 우리는 기본 시간대를 설정하고 같은 방법 위에 호출 한 후 시간대를 재설정 할 수 있습니다 : 당신이 해결책을 발견

TimeZone systemDefaultTimeZone = TimeZone.getDefault(); 
TimeZone.setDefault(TimeZone.getTimeZone(timezone)); 

addDays(1459123200, 1); 
TimeZone.setDefault(systemDefaultTimeZone); 
0

좋은, 난 그냥 좋겠 일부 통찰력을 추가하고 조금 개선하면 your answer을 제안합니다.

TimeZone.setDefault을 사용하여 JVM 기본 시간대를 설정하는 것이 최선의 방법은 아닙니다. 대부분의 시간 동안 작동 할 수도 있지만,이 코드가 좀 더 복잡한 환경에서 실행되는 것으로 간주하면 약간 위험하고 오류가 발생하기 쉽습니다.

TimeZone.setDefault전체 JVM의 기본 시간대를 변경하기 때문입니다. 동일한 JVM에서 실행중인 다른 응용 프로그램은 해당 응용 프로그램의 영향을받습니다. 동일한 응용 프로그램의 다른 부분에도 영향을 미치며 여러 스레드에서 실행되는 동일한 코드조차도 잘못된 결과를 줄 수 있습니다 (및 race conditions are hard to debug).

나는 TimeZone.setDefault(TimeZone.getTimeZone(timezone));을 사용하고있는 것으로 나타났습니다. 즉, 이미 특정 시간대로 작업하고 있으므로 JVM의 기본값에 의존 할 필요가 없습니다. 특정 시간대 이름이있는 경우 기본값 대신 사용하십시오. 그래서 addDays 방법은 다음과 같이해야 함을 제안한다 만든

public ZonedDateTime addDays(long myUTCTimeInSeconds, int days, String timezone) { 
    // get the instant from the UTC seconds 
    Instant instant = Instant.ofEpochSecond(myUTCTimeInSeconds); 
    // get the instant at the specified timezone 
    ZonedDateTime z = instant.atZone(ZoneId.of(timezone)); 

    // add days 
    return z.plusDays(days); 
} 

개선점 : 당신이 그것에 -1를 전달하는 경우

  • plusDays 이미 일일 차감

    을. 값을 확인하고 abs 메소드를 사용할 필요가 없습니다.
  • 는 JVM의 기본 시간대를 사용하지 않는 대신 ZoneId.systemDefault(), 당신이 이미 가지고있는 timezone
  • instant.atZoneZonedDateTime.ofInstant에 해당합니다 (당신이 setDefault 방법으로 사용했던 하나)를 사용합니다.IMO, atZone은 더 읽기 쉽지만이 경우 선택 및 코드 스타일의 문제입니다. 최종 결과에는 차이가 없습니다. 이와

, 당신은 할 수 :

// call directly, no need to change the default timezone 
System.out.println(addDays(1459123200, -1, "Europe/Stockholm")); 

이 인쇄됩니다

2016-03-27T03 : 00 + 02 : 00 [유럽/스톡홀름]

관련 문제