2017-10-04 181 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; 
} 

但是: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

提示 - 您需要使用'ZonedDateTime'而不是'OffsetDateTime'。我希望這些信息足以幫助你解決問題。如果我有時間,我會寫一個完整的答案。 –

+0

Hi @Jesper,那是因爲在2017年11月6日的差異必須是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"));