Java – TDOA calculation error
I have to calculate the total flight time between the departure airport and the arrival airport
This is done by the following code snippet:
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; }
This is the problem:
When I want to use these parameters to calculate the duration of future flights:
depLocalTime = 2017-11-06T14:50 arrLocalTime = 2017-11-06T16:45 depZoneOffset = +03:00 arrZoneOffset = +02:00
As a result of these parameters, the flightduration object is:
flightDuration = PT2H55M
Everything seems all right, doesn't it? But it's actually not good Let me explain;
The departure airport code is IST (Turkey), and the arrival airport code is AMS (Netherlands). Here is the key:
After October 29, 2017 (before the time I calculated), AMS time will support 1 hour, its offset will be 01:00, and ist offset will still be 03:00 Therefore, the correct duration object must be:
flightDuration = PT3H55M
How can I solve this problem? This is really annoying Thanks for your help.
Edit after zoneddatetime comment:
Guys, I've also tried to use the zoneddatetime object for calculation This is the code that uses the zoneddatetime object, which has no effect on the result
public int calculateFlightDuration(String departureDateTime,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:{}",arrAirportCode); } return 0; }
After @ Joe C's answer, I changed the code again. I believe this is the way I should go:
public int calculateFlightDuration(String departureDateTime,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,arrAirportCode); } return 0; }
However: Java assumes that Istanbul also changes its time zone offset to 02:00, but it will not happen I think I need to update my java The following is the result of the code change:
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's flight duration remains unchanged:
flightDuration = PT2H55M
Thank you for your answer Now I have to fix the time zone change in Istanbul
Solution
Offsetdatetime assumes a common offset throughout the year (for example, UTC 2) It doesn't cover anything about daylight saving time
If you want to consider daylight saving time, you should use zoneddatetime instead of zoneid In the case of Europe / Amsterdam, it will select UTC 1 or UTC 2 according to the time of year
zoneddatetime zonedDepTime = zoneddatetime.of(depLocalTime,ZoneId.of("Asia/Istanbul")); zoneddatetime zonedArrTime = zoneddatetime.of(arrLocalTime,ZoneId.of("Europe/Amsterdam"));