2017-10-04 10 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 

すべてが問題ないようですね。しかし、実際にはOKではありません。私に説明させてください。

出発空港コードは、IST(トルコ)と到着空港コードはAMS(オランダ)であり、ここでの鍵です:2017年10月29日の後

(私は計算時間の前に)、AMSの時間がされますそのオフセットは+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; 
} 

しかし:Javaは、イスタンブールでもその時間帯を変更することを前提としてい+02:00にオフセットされますが、ITはおこなわれません。私はまた、私のJavaを更新する必要があると思う。ここでは、コードの変更後の結果は次のとおりです。

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

こんにちは@ジェスパー、違いは2017-11-06でPT3H55Mでなければならないからです。この日に、AMSのオフセットは+01:00になります。 –

+0

しかし、AMSが冬の時間に切り替わっただけなので、飛行は突然1時間長くならないでしょうか? – Jesper

答えて

6

OffsetDateTimeは、1年全体の共通オフセット(例: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"));