java – 时差计算错误

前端之家收集整理的这篇文章主要介绍了java – 时差计算错误前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我必须计算出发机场和到达机场之间的总飞行时间.

这项工作由以下代码片段完成:

  1. public int calculateFlightDuration(String departureDateTime,String depAirportCode,String arrivalDateTime,String arrAirportCode) {
  2. try {
  3. LocalDateTime depLocalTime = LocalDateTime.parse(departureDateTime,formatter);
  4. LocalDateTime arrLocalTime = LocalDateTime.parse(arrivalDateTime,formatter);
  5.  
  6. ZoneOffset depZoneOffset = getTimeZoneOffset(depAirportCode);
  7. ZoneOffset arrZoneOffset = getTimeZoneOffset(arrAirportCode);
  8.  
  9. if (depZoneOffset != null && arrZoneOffset != null) {
  10.  
  11. OffsetDateTime offsetDepTime = OffsetDateTime.of(depLocalTime,depZoneOffset);
  12. OffsetDateTime offsetArrTime = OffsetDateTime.of(arrLocalTime,arrZoneOffset);
  13.  
  14. Duration flightDuration = Duration.between(offsetArrTime,offsetDepTime).abs();
  15.  
  16. return (int) flightDuration.toMinutes();
  17.  
  18. }
  19.  
  20. } catch (Exception e) {
  21. LOG.warn("::calculateFlightDuration depTime:{} dep.code:{} arrTime:{} arr.code:{}",departureDateTime,depAirportCode,arrivalDateTime,arrAirportCode);
  22. }
  23.  
  24. return 0;
  25. }

这是问题所在:

当我想用这些参数计算未来航班的持续时间时:

  1. depLocalTime = 2017-11-06T14:50
  2. arrLocalTime = 2017-11-06T16:45
  3. depZoneOffset = +03:00
  4. arrZoneOffset = +02:00

作为这些参数的结果,flightDuration对象是:

  1. flightDuration = PT2H55M

似乎一切都好,对吧?但实际上并不好.让我解释;

出发机场代码是IST(土耳其),抵达机场代码是AMS(荷兰),这里是关键:

2017-10-29之后(在我计算的时间之前),AMS时间将支持1小时,其偏移量将为01:00,IST偏移量仍为03:00.所以正确的持续时间对象必须是:

  1. flightDuration = PT3H55M

我该如何解决这个问题?这真烦人.
谢谢你的帮助.

在ZonedDateTime评论后编辑:

伙计们,我也尝试过使用ZonedDateTime对象进行计算.这是使用ZonedDateTime对象的代码,它对结果没有影响.

  1. public int calculateFlightDuration(String departureDateTime,formatter);
  2.  
  3. ZoneOffset depZoneOffset = getTimeZoneOffset(depAirportCode);
  4. ZoneOffset arrZoneOffset = getTimeZoneOffset(arrAirportCode);
  5.  
  6. if (depZoneOffset != null && arrZoneOffset != null) {
  7.  
  8. ZonedDateTime zonedDepTime = ZonedDateTime.of(depLocalTime,depZoneOffset);
  9. ZonedDateTime zonedArrTime = ZonedDateTime.of(arrLocalTime,arrZoneOffset);
  10.  
  11. // OffsetDateTime offsetDepTime = OffsetDateTime.of(depLocalTime,depZoneOffset);
  12. // OffsetDateTime offsetArrTime = OffsetDateTime.of(arrLocalTime,arrZoneOffset);
  13.  
  14. Duration flightDuration = Duration.between(zonedDepTime,zonedArrTime).abs();
  15.  
  16. return (int) flightDuration.toMinutes();
  17.  
  18. }
  19.  
  20. } catch (Exception e) {
  21. LOG.warn("::calculateFlightDuration depTime:{} dep.code:{} arrTime:{} arr.code:{}",arrAirportCode);
  22. }
  23.  
  24. return 0;
  25. }

在@Joe C的回答之后,我再次更改了代码,我相信这是我应该去的方式:

  1. public int calculateFlightDuration(String departureDateTime,formatter);
  2.  
  3. ZoneId depZoneId = getTimeZoneId(depAirportCode);
  4. ZoneId arrZoneId = getTimeZoneId(arrAirportCode);
  5.  
  6. if (depZoneId != null && arrZoneId != null) {
  7.  
  8. ZonedDateTime zonedDepTime = ZonedDateTime.of(depLocalTime,depZoneId);
  9. ZonedDateTime zonedArrTime = ZonedDateTime.of(arrLocalTime,arrZoneId);
  10.  
  11. Duration flightDuration = Duration.between(zonedDepTime,arrAirportCode);
  12. }
  13.  
  14. return 0;
  15. }

但是:Java假设伊斯坦布尔也将其时区偏移量改为02:00,但不会发生.我想我还需要更新我的Java.以下是代码更改后的结果:

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

aaand的飞行持续时间保持不变:

  1. flightDuration = PT2H55M

谢谢你的回答.现在我必须修复伊斯坦布尔的时区变化.

解决方法

OffsetDateTime假定全年共同的偏移(例如UTC 2).它没有涵盖夏令时的任何内容.

如果您想考虑夏令时,则应使用ZonedDateTime而不是ZoneId.在Europe/Amsterdam的情况下,它将根据一年中的时间选择UTC 1或UTC 2.

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

猜你在找的Java相关文章