Mac Flight Tracker widget timezone bug

The Flight Tracker dashboard widget that comes with Mac OS X 10.4 (Tiger) seems to have a fairly major bug. However, this bug seems to be the result of something quite obscure to do with timezones, and it only seems to manifest itself in the UK during the summer.

I've noticed this problem a few times: specifically whenever any one of my close friends or family members flies anywhere. This time, my mother is on her way back from San Diego to Bristol via Newark. Thanks to the incredibly annoying terrorist attack attempt today, my dad and I were understandably concerned about flight delays, so I pulled up the Flight Tracker. Unfortunately, the information seems completely wrong.

Turns out, the minutes are right but the hours don't relate to any of the relevant timezones.

Anyway, a little background. Here in the UK, we have two main time scenarios: firstly GMT, which is for all intents and purposes, UTC. We also use BST: "British Summer Time" which is UTC+1h, and kicks in for archaic agrarian reasons and the "Think of the children!" brigade who are convinced it'll stop traffic accidents.

While the rest of OS X seems okay and correctly uses BST, Apple's Mail.app has always strangely listed incoming mail as being sent relative to "BDT", which comes out as "British Daylight Time", which is fairly meaningless as there's no such thing. The times are correct, but they just have the wrong abbreviation afterwards. On researching it, this seems to be the result of bad data from the Unicode people which might have made its way into NSDate. Anyway, it's usually just a cosmetic thing, and of little or no consequence.

I believe, however, that it's the cause of the Flight Tracker widget's problems. To test this, I altered the widget to display the timezone, by replacing the bit in FlightTracker.js, in function formatDateForDisplay() that says

var timeStr = date.toLocaleTimeString("short");

with

var timeStr = date.toLocaleTimeString("long");

This reveals that the times are supposedly in "BDT". I believe this might be the problem. I think something is reinterpreting this as "Brazilian Daylight Time", which would explain the weird offsets. I think JavascriptCore or something is referring to the same bad data as Mail.app, probably via NSDate. I'm not a Safari hacker, and I haven't really investigated that far, so I'm not sure where the problem is.

Looking a bit deeper into FlightTracker.js, I'm not really surprised there's a problem. The timezone calculation code is fairly messy, with comments such as:

// We're going to be stupid and hard coded about parsing the server provided date strings for now
// ??? for some reason parseInt returns 0 on this but parsefloat works ???

and

// here we do proper handling of the timezone offsets.
// We enter everything in pretending it's UTC time
// and then we convert it to miliseconds since 1970,
// add the timezone offset in miliseconds to it
// and then set this as the new UTC time

There seems to be some string hacking going on at several places to decode the data sent from FlyteComm. The original data is reasonably well structured, with the timezone offsets being given correctly as -0700 and +0100, which presumably indicate that the times are given as local times of the departure/arrival locations, as per normal for the airline industry.

I'm not completely sure what's going on, as I'm not really set up to debug someone else's widget, especially one with weird custom controls, and barely any code comments. It's obvious to me that the widget isn't particularly well written, and is one of those things that "just works". It was probably hacked up for fun by a Dashboard developer, and then fasttracked to the nearest Steve Jobs keynote rehearsal. As Steve Jobs's Dashboard demos tend to be done at MWSF and WWDC, I doubt this problem has ever really been seen at Apple. I bet if it was a problem with Pacific Daylight Time being misinterpreted, it'd be fixed immediately! I've done a little bit of googling, and it looks like the BDT bug has already been submitted to Apple (several times), and it's still there.

When I get a chance, I may try to debug this one further, and perhaps rewrite FlightTracker's timezone code properly using the correct offsets rather than performing nasty magic using getLocaleTimeString().

What I would prefer is that the timezone of each time is given next to the time. Ideally, they should toggle-on-click or slowly fade between local times (to the flight) and local times to the machine, and possibly relative times ("1 hour ago", "in 53 minutes", etc.) That would make the tool a lot more intuitive anyway. I'd rather not reinvent the whole widget, as in all other ways, the widget's really not too bad.

UPDATE: I've logged this with Apple as bug #4676024.

Tags

18 comments on “Mac Flight Tracker widget timezone bug

  1. Actually, I think I\'m seeing a related bug right now, tracking a flight from Denver to Ontario, CA (that\'s PST for the next couple of hours). The flight details are an hour fast.

  2. Hi Tom:

    Did you ever get an answer from Apple about this? I would sure like to fix the problem.

    Thanks!

  3. I got a reply back in October stating that it was a \"known issue\". That\'s all!

    Now, since we\'re back in BST, I may take another swipe at it.

  4. cool. keep us updated. this has been annoying the hell out of me for a long time too!

  5. Nice work. I\'m totally confused - by my calculation, the flight tracker is showing departure/arrival times at GMT+3 (or should that be BST+3). I cannot think of a logical explanation. Any updates Tom?
    Thanks for the effort!

  6. Top spot! I think the google calendar widget I use has a similar problem as well...

  7. Hi!

    I llve in Portugal and my time zone is (I believe) considered WEST. I started to try to debug the createDateFromServerString() function, and it seems to me that it is not extracting properly the timezone offset from the server string, so I ask you if it is possible to instruct me how to get real server strings or if you could post here some few actual lines.

    Actually I patched inelegantly in the same function:

    date.setUTCHours(hour-3);

    It works, but it sucks!

    Thanks!

  8. I have just created an HTML document to send POST data to the Flytecomm site...

    When a flight has a departure/landing date in UTC (Zulu time), the string in the xml file is as follows (flights departing from Oporto - OPO):

    2007-12-10T15:40:50Z
    2007-12-10T13:35:00Z
    2007-12-10T16:10:00Z

    Just take a look of a landing time in Palma de Maiorca:

    2007-12-10T18:55:00+01:00

    Taking a look at the code, it is not prepared to handle the \'Z\'., But still, I don\'t know what string is really processed by the createDateFromServerString() function.

    Nevertheless, I don\'t understand why it takes any time and sums 3. It seems to me that the author wanted to show times in \'client-computer-time\', not in local departure/landing time.

  9. I am sorry about the last post:

    if (!isNaN(tzhour) && !isNaN(tzmin)) {
    tzOffsetMS = tzhour * 3600 * 1000 + tzmin*60*1000;
    if (tzsign == \"+\")
    tzOffsetMS *= -1;
    }

    should handle the \'Z\' situation...

  10. OK, I almost quit as this is really strange!...

    The createDateFromServerString() function should be working correctly, and there is only malfunction if you are living near GMT... winter time or summer time.

    I tried the createDateFromServerString() code in a html page, run it on firefox and safari, and worked fine. On this widget, it adds 3 hours if you are on GMT, GMT+1 (summer), WET (Western Europe Time) or WEST (summer).
    HOW MANY JAVASCRIPT ENGINES ARE RUNNING IN MAC OSX???!!

    As I usually guide myself on Portuguese time, even when I am abroad, I tweaked the FlightTracker.js the following way...

    In function formatDateForDisplay():

    //date.setTime(dateInfo.date.getTime() - tzOffset); // ORIGINAL CODE
    date.setTime(dateInfo.date.getTime() - 3*3600000); // MY CODE

    I want to know the landing/departure times according to my clock, and not according to (other people\'s) local times, so I took off the \'tzOffset\', as it would simply put back the time difference. Remember that the dateInfo already has the time in UTC and the .toLocaleTimeString method outputs the time already according to your local clock.
    Then, I just ripped the extra 3 hours. It is working fine.

  11. I created a new widget just to find which WebKit version the DASHBOARD is using, and finally I got some insight about this issue.

    The same javascript code writes the following:

    ON SAFARI 3.0.4 (523.12):
    Your WebKit version number is 523.12 and is not a nightly build.

    ON DASHBOARD:
    Your WebKit version number is 419.2.1 and is not a nightly build.

    So, that\'s why I was getting different results with the same code!!! The actual version of WebKit deals properly with LAT 0º time zones, but the one used by Dashboard does not.

    NEXT QUESTION: How can I update Dashboard\'s WebKit?

  12. I wouldn\'t recommend updating WebKit! Who knows what else would be broken, plus it might get in the way of future software updates.

    Anyway, good job investigating this one, António... what do you think is the actual piece of code that\'s broken?

    From what I can tell, createDateFromServerString() returns a valid date object, along with tzOffset and dayOffset. I\'ve played around with my timezone, date (forcing daylight savings), and some input strings, and it seems to give the correct results, when the date object returned is fed through .toUTCString().

    So, if that date object is correct, then it must be the conversion to local time (ie. toLocaleTimeString), OR tzOffset returned by createDateFromServerString().

    If that\'s the case, then by taking the date object (ie. dateInfo.date) and a fresh \"now\" date (ie. new Date()), and subtracting one from the other:

    var dateInfo = createDateFromServerString(foo);
    var now = new Date();
    var diff = now.getTime() - dateInfo.date.getTime();

    you should then have a correct number of milliseconds, so you could say \"in 15 minutes\" or \"6 hours ago\" rather than a misleading and potentially bogus \"local\" time. Alternatively, you could write your own \"toLocaleTimeString\" that works.

    All that\'s assuming that dateInfo.date is correct, though... ie. dateInfo.date.getTime() returns the correct number of milliseconds since midnight of January 1, 1970 UT/UTC/GMT/+0/Z, rather than using some timezone local to the browser or the flight in question.

    Have you got any definite test cases to say that it\'s not correct?

    Unfortunately, I\'m swamped at the moment, so I can\'t spend any significant time on this :(

    Incidentally, I just checked and the bug I filed with Apple was marked as a duplicate of #4617358, and closed, so I can\'t track it.

  13. I have Webkit 523.12 framework installed (/System/Library/Frameworks/WebKit.framework) but apparently only Safari 3 uses it; Dashboard is using the 419.2.1 which I don\'t have clue where is located. But I quit updating it by myself, because of future sw updates...

    Nevertheless, this widget works perfectly if you use any timezone (for instance, Central Europe, any of America\'s timezone) which is not \"over\" the GMT meridian; if you are \"over\" GMT, then comes those 3 extra hours.

    My next step will be to inject some parts of FlightTracker code in the test widget (initially HelloWorld, now WorkHorse), and check if the date is being properly processed by the javascript engine used by Dashboard.

    But this will have to wait for more free time... :(

  14. It seems I got it world-wide working!!!

    The problem is that the setUTCHours(), setUTCMinutes() and setUTCSeconds() are buggy in the current javascript engine present in Dashboard (actually, WebKit v.419.2.1). Each one of this methods adds an extra hour if you are located in Portugal, Great Britain or Ireland. As each on of these methods are called in function createDateFromServerString(), we usually get a wrong 3 hours offset from our local clock.

    I solved these issue, adding the following patch in createDateFromServerString() function:

    //date.setUTCHours(hour); // setUTCHours() is buggy in WebKit version 419.2.1
    //date.setUTCMinutes(min);
    //date.setUTCSeconds(sec);
    date.setHours(hour-date.getTimezoneOffset()/60, min, sec); // Here is the deal!

    I commented out the three original lines, and added the last line to do the right thing!

    I did another modification, as of personal taste: I just want to know the departure/landing times according to my own clock, and not according to the place where the plane takes off/lands. So I went to formatDateForDisplay() and did the following modification:

    //var date = new Date();
    //var tzOffset = dateInfo.tzOffset - date.getTimezoneOffset()*60000;
    //date.setTime(dateInfo.date.getTime() - tzOffset);
    //if (date != null) {
    if (dateInfo.date != null) {
    //var timeStr = date.toLocaleTimeString(\"short\");
    var timeStr = dateInfo.date.toLocaleTimeString(\"short\"); // This line added!
    if (timeStr != \"Invalid Date\") {
    retVal = timeStr;
    }
    }

    It is working, now, on several timezones, and you are free to test it out!

    Cheers!

  15. Olá Tom, Olá António,
    well first of all to Tom, António and everyone- Happy New Year! I just found this post. This is a bug which annoyed me for quite some years. Great if you found a way to solve this!

    To use your modifications I looked for and found this WebKit file on my system (OS X.10.4.11 (PowerPC)). However I couldn\'t open it or write the code you mentioned above in it. (Normally I just use this MAC and not hack within it\'s entrails....) Any hint for beginners how to open this WebKit file? Is there a danger if I mess it up?
    Be sure ANY comment would be highly appreciated!
    Anjin, frequent flyer, Lisboa

  16. Hi (and Happy New Year) anjin,

    I really, really wouldn\'t recommend altering or replacing WebKit... it\'s an important part of OS X, and unless you really know what you\'re doing, you could end up breaking a lot of stuff!

    It\'s also not necessary for the changes António has been making. There is a problem with WebKit in Dashboard, but it looks like he\'s managed to work around it.

    Instead, the idea is to edit the code in the Flight Tracker widget itself. It\'s also a very good idea to take a copy of the widget and alter that instead. Saying that, even then it\'s not something I\'d consider a job for a beginner. I would read up on developing widgets before you attempt this.

    Right now, the unaltered Flight Tracker seems to be working properly for me, so I can\'t really check António\'s changes. I\'m using Leopard (10.5.1) and am currently in GMT. I only seemed to have trouble when we were in British Summer Time.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

HTML tags are not allowed.