Skip to content

Instantly share code, notes, and snippets.

@mobz
Last active February 26, 2020 09:08
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mobz/cf8d3a98722e0fbe10b2dbb2046efe4e to your computer and use it in GitHub Desktop.
Save mobz/cf8d3a98722e0fbe10b2dbb2046efe4e to your computer and use it in GitHub Desktop.
You can scrape the timezone database in javascript using the Intl object [ licensed CC0 ]
function getTimeZone( tz_str, date ) {
const utc_c = {
timeZone: "UTC",
hour12: false,
year: "numeric",
month: "numeric",
day: "numeric",
hour: "numeric",
minute: "numeric",
second: "numeric"
};
const loc_c = {
timeZone: tz_str,
hour12: false,
year: "numeric",
month: "numeric",
day: "numeric",
hour: "numeric",
minute: "numeric",
second: "numeric"
};
const locale = 'en-US';
const utc_f = new Intl.DateTimeFormat(locale, utc_c );
const loc_f = new Intl.DateTimeFormat(locale, loc_c );
// console.log( utc_f.resolvedOptions())
// console.log( loc_f.resolvedOptions())
let d = new Date( date );
const us_re = /(\d+).(\d+).(\d+),?\s+(\d+).(\d+).(\d+)/;
function parseDate( date_str ) {
try {
return Array.prototype.slice.call(us_re.exec( date_str ), 1).map( function(n) {
return parseInt(n, 10)
});
} catch(e) {
console.log("expected a US (m/d/y) date: ", + date_str );
return null;
}
}
function diffMinutes( d1, d2 ) {
let day = d1[1] - d2[1];
let hour = d1[3] - d2[3];
let minute = d1[4] - d2[4];
// console.log( d1, d2 );
if( day < -20 ) {
day = 1;
}
return ((( day * 24 ) + hour ) * 60 ) + minute;
}
return diffMinutes(
parseDate( utc_f.format( d )),
parseDate( loc_f.format( d )) );
}
function pretty( tz, date ) {
date = date || new Date();
console.log( "Timezone in", tz, "at", date.toISOString(), "is", getTimeZone( tz, date ) );
}
let now = new Date();
let december = new Date();
december.setMonth(11);
let june = new Date();
june.setMonth(5);
pretty( "GMT", now );
pretty( "Europe/London", now );
pretty( "America/New_York", now );
pretty( "Australia/Melbourne", december );
pretty( "Australia/Melbourne", june );
@mobz
Copy link
Author

mobz commented Apr 28, 2017

@spencermountain you can't tell whether a tz is daylight savings or not, and whether it's northern hemisphere or not, but you can get the timezone offset, which is probably all you need for 90% of the applications.

perhaps a database that just parses the continent and infers hemisphere from that would work? then ds and season can be inferred from that?

few notes, in node.js I've found support for locale != en-US is not baked in unless you compile your own version of node using specific flags for Intl, in browsers Chrome and Firefox appeared to be ok, smashed this out on the way to work, needs way more testing (esp in non-en locales), also some defensive testing of the locale = en-US actually producing a m/d/y date (maybe using known epochs?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment