tzAbbr.js 2.56 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
/* Friendly timezone abbreviations in client-side JavaScript

`tzAbbr()` or `tzAbbr(new Date(79,5,24))`
=> "EDT", "CST", "GMT", etc.!

There's no 100% reliable way to get friendly timezone names in all
browsers using JS alone, but this tiny function scours a
stringified date as best it can and returns `null` in the few cases
where no friendly timezone name is found (so far, just Opera).

Device tested & works in:
12
* IE 6 [through] 11 (latest versions of all)
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
* Firefox 3 [through] 16 (16 = latest version to date)
* Chrome 22 (latest version to date)
* Safari 6 (latest version to date)
* Mobile Safari on iOS 5 & 6
* Android 4.0.3 stock browser
* Android 2.3.7 stock browser
* IE Mobile 9 (WP 7.5)

Known to fail in:
* Opera 12 (desktop, latest version to date)

For Opera, I've included (but commented out) a workaround spotted
on StackOverflow that returns a GMT offset when no abbreviation is
found. I haven't found a decent workaround.

If you find any other cases where this method returns null or dodgy
results, please say so in the comments; even if we can't find a
workaround it'll at least help others determine if this approach is
suitable for their project!
*/
33 34 35 36 37 38 39 40 41 42 43 44 45 46
define([], function() {
  return function (dateInput) {
    var dateObject = dateInput || new Date(),
      dateString = dateObject + "",
      tzAbbr = (
        // Works for the majority of modern browsers
        dateString.match(/\(([^\)]+)\)$/) ||
        // IE outputs date strings in a different format:
        dateString.match(/([A-Z]+) [\d]{4}$/)
      );

    if (tzAbbr) {
      // Old Firefox uses the long timezone name (e.g., "Central
      // Daylight Time" instead of "CDT")
47 48 49 50 51 52 53 54 55 56 57 58 59
      /*
         If the timezone string does not cotain capital English letters
         (For example, the timezone string may be a Chinese string),
         then the following code line will produce a null-reference
         exception, and the execution of the javascript codes will 
         be stopped, which may cause some strange behaviors. So a 
         try-catch is needed here to prevent the execution being stopped.
      */
      try {
          tzAbbr = tzAbbr[1].match(/[A-Z]/g).join("");
      } catch(err) {
          tzAbbr = tzAbbr[1];
      }
60 61 62 63 64 65 66 67 68 69 70 71 72 73
    }

    // Uncomment these lines to return a GMT offset for browsers
    // that don't include the user's zone abbreviation (e.g.,
    // "GMT-0500".) I prefer to have `null` in this case, but
    // you may not!
    // First seen on: http://stackoverflow.com/a/12496442
    // if (!tzAbbr && /(GMT\W*\d{4})/.test(dateString)) {
    //  return RegExp.$1;
    // }

    return tzAbbr;
  };
});