2017-10-04 2 views
7

출발 공항과 도착 공항 사이의 총 비행 시간 (분)을 계산해야합니다.시차 계산 오류

이 작업이 코드에 의해 수행됩니다 여기

public int calculateFlightDuration(String departureDateTime, String depAirportCode, String arrivalDateTime, 
     String arrAirportCode) { 
    try { 
     LocalDateTime depLocalTime = LocalDateTime.parse(departureDateTime, formatter); 
     LocalDateTime arrLocalTime = LocalDateTime.parse(arrivalDateTime, formatter); 

     ZoneOffset depZoneOffset = getTimeZoneOffset(depAirportCode); 
     ZoneOffset arrZoneOffset = getTimeZoneOffset(arrAirportCode); 

     if (depZoneOffset != null && arrZoneOffset != null) { 

      OffsetDateTime offsetDepTime = OffsetDateTime.of(depLocalTime, depZoneOffset); 
      OffsetDateTime offsetArrTime = OffsetDateTime.of(arrLocalTime, arrZoneOffset); 

      Duration flightDuration = Duration.between(offsetArrTime, offsetDepTime).abs(); 

      return (int) flightDuration.toMinutes(); 

     } 

    } catch (Exception e) { 
     LOG.warn("::calculateFlightDuration depTime:{} dep.code:{} arrTime:{} arr.code:{}", departureDateTime, 
       depAirportCode, arrivalDateTime, arrAirportCode); 
    } 

    return 0; 
} 

문제는 다음과 같은

depLocalTime = 2017-11-06T14:50 
arrLocalTime = 2017-11-06T16:45 
depZoneOffset = +03:00 
arrZoneOffset = +02:00 

: 그 매개 변수와 함께 미래 비행의 기간을 계산하려는

이러한 매개 변수의 결과, flightDuration 객체는 다음과 같습니다.

flightDuration = PT2H55M 

모든 것이 정상인 것 같습니다. 맞습니까? 그러나 실제로는 괜찮지 않습니다. 설명해 드리겠습니다.

출발 공항 코드 IST (터키) 도착 공항 코드는 AMS (네덜란드)이며, 여기에 중요한 것은 :

2017년 10월 29일 후 (I 계산 시간 전에), AMS 시간이 될 것입니다 1시 간이 뒷받침되며 오프셋은 +01 : 00이고 IST 오프셋은 여전히 ​​+03 : 00입니다.

flightDuration = PT3H55M 

가 어떻게이 문제를 해결할 수 : 그래서 정확한 시간 객체는해야? 정말 짜증나. 도움 주셔서 감사합니다. ZonedDateTime 코멘트 후

편집 : 이

얘들 아, 나 또한 계산에 ZonedDateTime 객체와 시도

. 다음은 ZonedDateTime 객체가 사용 된 코드입니다. 결과에는 아무런 차이가 없습니다.
public int calculateFlightDuration(String departureDateTime, String depAirportCode, String arrivalDateTime, 
     String arrAirportCode) { 
    try { 
     LocalDateTime depLocalTime = LocalDateTime.parse(departureDateTime, formatter); 
     LocalDateTime arrLocalTime = LocalDateTime.parse(arrivalDateTime, formatter); 

     ZoneOffset depZoneOffset = getTimeZoneOffset(depAirportCode); 
     ZoneOffset arrZoneOffset = getTimeZoneOffset(arrAirportCode); 

     if (depZoneOffset != null && arrZoneOffset != null) { 

      ZonedDateTime zonedDepTime = ZonedDateTime.of(depLocalTime, depZoneOffset); 
      ZonedDateTime zonedArrTime = ZonedDateTime.of(arrLocalTime, arrZoneOffset); 

//    OffsetDateTime offsetDepTime = OffsetDateTime.of(depLocalTime, depZoneOffset); 
//    OffsetDateTime offsetArrTime = OffsetDateTime.of(arrLocalTime, arrZoneOffset); 

      Duration flightDuration = Duration.between(zonedDepTime, zonedArrTime).abs(); 

      return (int) flightDuration.toMinutes(); 

     } 

    } catch (Exception e) { 
     LOG.warn("::calculateFlightDuration depTime:{} dep.code:{} arrTime:{} arr.code:{}", departureDateTime, 
       depAirportCode, arrivalDateTime, arrAirportCode); 
    } 

    return 0; 
} 

는 @Joe C의 대답 후, 나는 다시 코드를 변경하고 나는 이것이 내가 가야 방법이라고 생각 :

public int calculateFlightDuration(String departureDateTime, String depAirportCode, String arrivalDateTime, 
     String arrAirportCode) { 
    try { 
     LocalDateTime depLocalTime = LocalDateTime.parse(departureDateTime, formatter); 
     LocalDateTime arrLocalTime = LocalDateTime.parse(arrivalDateTime, formatter); 

     ZoneId depZoneId = getTimeZoneId(depAirportCode); 
     ZoneId arrZoneId = getTimeZoneId(arrAirportCode); 

     if (depZoneId != null && arrZoneId != null) { 

      ZonedDateTime zonedDepTime = ZonedDateTime.of(depLocalTime, depZoneId); 
      ZonedDateTime zonedArrTime = ZonedDateTime.of(arrLocalTime, arrZoneId); 

      Duration flightDuration = Duration.between(zonedDepTime, zonedArrTime).abs(); 

      return (int) flightDuration.toMinutes(); 

     } 

    } catch (Exception e) { 
     LOG.warn("::calculateFlightDuration depTime:{} dep.code:{} arrTime:{} arr.code:{}", departureDateTime, 
       depAirportCode, arrivalDateTime, arrAirportCode); 
    } 

    return 0; 
} 

는하지만 : 자바 이스탄불은 또한 시간대를 변경하는 것이 가정 오프셋은 +02 : 00이지만 IT가 안됨. 나는 또한 자바 업데이트를해야한다고 생각한다. 여기에 코드 변경 후 결과는 다음과 같습니다

depZoneId = Europe/Istanbul 
arrZoneId = Europe/Amsterdam 
zonedDepTime = 2017-11-06T14:50+02:00[Europe/Istanbul] //damn it's really annoying! 
zonedArrTime = 2017-11-06T16:45+01:00[Europe/Amsterdam] 

aaand 비행 시간은 동일하게 유지 : 답변들에 대한

flightDuration = PT2H55M 

감사합니다. 이제 이스탄불의 시간대 변경을 수정해야합니다.

+0

힌트 - 'OffsetDateTime' 대신'ZonedDateTime'을 사용해야합니다. 나는 그것이 당신이 그것을 해결하는 데 도움이되는 충분한 정보가되기를 바랍니다. 나중에 시간이 있으면 완전한 답을 쓸 것입니다. –

+0

안녕하세요 @ Jesper, 차이는 2017-11-06에 PT3H55M이어야하기 때문입니다. 이 날짜에 AMS의 오프셋은 +01 : 00이됩니다. –

+0

AMS가 겨울철로 바뀌었기 때문에 비행이 갑자기 1 시간 더 길지는 않습니까? – Jesper

답변

6

OffsetDateTime은 전체 연도의 공통 오프셋 (예 : UTC + 2)을 사용합니다. 그것은 서머 타임 라인을 따라 아무것도 다루지 않습니다.

여름 시간을 고려하려면 ZonedDateTime 대신 ZoneId을 사용해야합니다. Europe/Amsterdam의 경우 시간에 따라 UTC + 1 또는 UTC + 2가 선택됩니다.

ZonedDateTime zonedDepTime = ZonedDateTime.of(depLocalTime, ZoneId.of("Asia/Istanbul")); 
ZonedDateTime zonedArrTime = ZonedDateTime.of(arrLocalTime, ZoneId.of("Europe/Amsterdam"));