javascript - Calculating BST time from Date object? -
i've reviewed few questions on similar topics already, none of them address calculating destination timezone, taking its dst (daylight savings time) account. i'm trying write simple widget displays live local time of specific timezone visiting page. timezone of interest bst (what bst?), if possible i'd love see generic implementation locale. here's attempt, using vanilla javascript:
function getbst() { var date = new date(), utc = date.gettime() + date.gettimezoneoffset() * 60000, local = new date(utc), // gmt, not bst day = local.getdate(), mon = local.getmonth() + 1, year = local.getfullyear(), hour = local.gethours(), minute = ('0' + local.getminutes()).slice(-2), second = ('0' + local.getseconds()).slice(-2), suffix = hour < 12 ? 'am' : 'pm'; hour = (hour - 24) % 12 + 12; return mon + '/' + day + '/' + year + ', ' + hour + ':' + minute + ':' + second + ' ' + suffix; } setinterval(function () { document.body.textcontent = getbst(); }, 1000);
based on @robg's answer, i've written code:
function resetday(date) { date.setutcmilliseconds(0); date.setutcseconds(0); date.setutcminutes(0); date.setutchours(1); return date; } function lastday(date, day) { while (date.getutcday() !== day) { date.setutcdate(date.getutcdate() - 1); } return date; } function adjustdst(date, begin, end) { if (date >= begin && date < end) { date.setutchours(date.getutchours() + 1); } return date; } function updatebst() { var date = new date(); var begin = resetday(new date()); begin.setutcmonth(3, -1); begin = lastday(begin, 0); var end = resetday(new date()); end.setutcmonth(10, -1); end = lastday(end, 0); date = adjustdst(date, begin, end); var day = date.getutcdate(), mon = date.getutcmonth() + 1, year = date.getutcfullyear(), hour = date.getutchours(), minute = ('0' + date.getutcminutes()).slice(-2), second = ('0' + date.getutcseconds()).slice(-2), suffix = hour < 12 ? 'am' : 'pm'; hour = (hour - 24) % 12 + 12; return mon + '/' + day + '/' + year + ', ' + hour + ':' + minute + ':' + second + ' ' + suffix; } setinterval(function () { document.body.textcontent = updatebst(); }, 1000);
i tested bst pausing in debugger , changing month of current date, , output hour later seems work properly. everyone!
it's not difficult support 1 timezone provided know when transitions in , out of daylight saving.
a javascript date consists of time value in utc , timezone offset based on host system settings. need apply timezone offset want utc time , presto, there's time in timezone.
there no standardised system abbreviating time zones, though there defacto standards (e.g. iata timezone codes , iana timezones). guess bst mean british summer time, known british daylight time (bdt) , british daylight saving time (bdst). might bangladesh standard time or bougainville standard time known "bst".
there various libraries (such moment timezone) use iana codes , can provide time supported time zone (more or less) time.
bst starts @ 01:00 utc on last sunday in march , ends @ 01:00 utc on last sunday in october each year, algorithm is:
- create new date based on system's local settings (e.g.
new date()
) - create dates start , end of bst based on utc values (for year, 2016-03-27t01:00:00z , 2016-03-30t02:00:00z)
- see if current utc time falls in range
- if so, add 1 hour utc time of date created in #1
- output formatted string based on date's utc values
that's it, hard part finding appropriate sunday dates. don't need consider local timezone offset @ all, since based on utc , date objects too.
right don't have time provide code, have go , can in 10 hrs.
edit
so here's code. first 2 function helpers, 1 gets last sunday in month, other formats iso 8601 string offset. of work in 2 functions. comments sufficient, if more explanation required, ask.
i haven't included milliseconds in string, feel free add them if want, add + '.' + ('00' + d.getutcmilliseconds()).slice(-3)
before offset part of formatted string.
note function need modified if dates starting or stopping daylight saving changed, infrequent. historic dates of course need small database of when daylight saving starts , stops particular years , periods.
/* return date last sunday in month ** @param {number} year - full year number (e.g. 2015) ** @param {number} month - calendar month number (jan=1) ** @returns {date} date last sunday in given month */ function getlastsunday(year, month) { // create date last day in month var d = new date(year, month, 0); // adjust previous sunday d.setdate(d.getdate() - d.getday()); return d; } /* format date string iso 8601 supplied offset ** @param {date} date - date format ** @param {number} offset - offset in minutes (+east, -west), ** converted +/-00:00 ** @returns {string} formatted date , time ** ** note javascript date offsets opposite: -east, +west ** function doesn't use date's offset. */ function formatdate(d, offset) { function z(n){return ('0'+n).slice(-2)} // default offset 0 offset = offset || 0; // generate offset string var offsign = offset < 0? '-' : '+'; offset = math.abs(offset); var offstring = offsign + ('0'+(offset/60|0)).slice(-2) + ':' + ('0'+(offset%60)).slice(-2); // generate date string return d.getutcfullyear() + '-' + z(d.getutcmonth()+1) + '-' + z(d.getutcdate()) + 't' + z(d.getutchours()) + ':' + z(d.getutcminutes()) + ':' + z(d.getutcseconds()) + offstring; } /* return date object current time in london. assumes ** daylight saving starts @ 01:00 utc on last sunday in march ** , ends @ 01:00 utc on last sunday in october. ** @param {date} d - date test. default current ** system date , time ** @param {boolean, optional} obj - if true, return date object. otherwise, return ** iso 8601 formatted string */ function getlondontime(d, obj) { // use provided date or default current date , time d = d || new date(); // start , end dates daylight saving supplied date's year // set utc date values , time 01:00 var dsts = getlastsunday(d.getfullyear(), 3); var dste = getlastsunday(d.getfullyear(), 10); dsts = new date(date.utc(dsts.getfullyear(), dsts.getmonth(), dsts.getdate(),1)); dste = new date(date.utc(dste.getfullyear(), dste.getmonth(), dste.getdate(),1)); // if date between dststart , dstend, add 1 hour utc time // , format using +60 offset if (d > dsts && d < dste) { d.setutchours(d.getutchours() +1); return formatdate(d, 60); } // otherwise, don't adjust , format 00 offset return obj? d : formatdate(d); } document.write('current london time: ' + getlondontime(new date()));
Comments
Post a Comment