2017-10-04 148 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"));