从日期对象计算 BST 时间
Calculating BST time from Date object?
我已经回顾了几个关于类似主题的问题,但没有一个涉及计算目的地时区的问题,考虑到它的DST(夏令时)。我正在尝试编写一个简单的小部件,向访问该页面的任何人显示特定时区的实时本地时间。感兴趣的时区是BST(什么是BST?),但如果可能的话,我希望看到任何语言环境的通用实现。这是我使用vanilla JavaScript的尝试:
function getBST() {
var date = new Date(),
utc = date.getTime() + date.getTimezoneOffset() * 60000,
local = new Date(utc), // this is 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);
根据@RobG的回答,我编写了以下代码:
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);
我通过在调试器中暂停并更改当前日期的月份来测试 BST,输出晚了一个小时,因此它似乎可以正常工作。感谢大家的帮助!
在纯 JS 中不可能,仅使用 Date
方法,但(当然)有一个库:http://momentjs.com/timezone/
例:
moment.tz("Europe/London").format(); // 2016-01-15T09:21:08-07:00
支持一个时区并不难,只要您知道它何时转换进出夏令时。
JavaScript 日期由以 UTC 为单位的时间值和基于主机系统设置的时区偏移量组成。因此,您需要做的就是将您想要的时区偏移量应用于 UTC 时间和 presto,您的时间在任何时区都有。
没有用于缩写时区的标准化系统,尽管有一些事实上的标准(例如IATA时区代码和IANA时区)。我猜你说的BST是指英国夏令时,也称为英国夏令时(BDT)和英国夏令时(BDST)。它也可能是孟加拉国标准时间或布干维尔标准时间,也称为"BST"。
有各种库(例如时刻时区)使用 IANA 代码,并且可以提供任何受支持的时区的时间(或多或少)任何时间。
BST 从每年 3 月最后一个星期日的 01:00UTC 开始,到 10 月最后一个星期日的 01:00 UTC 结束,因此算法为:
- 根据系统的本地设置创建新日期(例如
new Date()
) - 根据 UTC 值创建 BST 开始和结束日期(今年为 2016-03-27T01:00:00Z 和 2016-03-30T02:00:00Z)
- 查看当前 UTC 时间是否在该范围内
- 如果是这样,请在 #1 中创建的日期的 UTC 时间上添加 1 小时
- 根据日期的 UTC 值输出格式化字符串
就是这样,唯一困难的部分是找到合适的周日日期。您根本不需要考虑本地时区偏移量,因为一切都基于 UTC,Date 对象也是如此。
现在我没有时间提供代码,所以试一试,我可以在大约 10 小时内回复您。
编辑
所以这是代码。前两个函数是帮助程序,一个获取一个月中的最后一个星期日,另一个使用偏移量格式化 ISO 8601 字符串。大部分工作都在这两个职能中。希望评论足够,如果需要更多解释,请询问。
我没有在字符串中包含毫秒,如果需要,请随时添加它们,在格式化字符串的偏移部分之前添加+ '.' + ('00' + d.getUTCMilliseconds()).slice(-3)
。
请注意,如果开始或停止夏令时的日期发生更改,则需要修改该函数,但这并不常见。当然,历史日期需要一个小型数据库,用于显示特定年份和时期的夏令时何时开始和停止。
/* Return a Date for the last Sunday in a month
** @param {number} year - full year number (e.g. 2015)
** @param {number} month - calendar month number (jan=1)
** @returns {Date} date for last Sunday in given month
*/
function getLastSunday(year, month) {
// Create date for last day in month
var d = new Date(year, month, 0);
// Adjust to previous Sunday
d.setDate(d.getDate() - d.getDay());
return d;
}
/* Format a date string as ISO 8601 with supplied offset
** @param {Date} date - date to format
** @param {number} offset - offset in minutes (+east, -west), will be
** converted to +/-00:00
** @returns {string} formatted date and time
**
** Note that javascript Date offsets are opposite: -east, +west but
** this function doesn't use the Date's offset.
*/
function formatDate(d, offset) {
function z(n){return ('0'+n).slice(-2)}
// Default offset to 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 for current time in London. Assumes
** daylight saving starts at 01:00 UTC on last Sunday in March
** and ends at 01:00 UTC on the last Sunday in October.
** @param {Date} d - date to test. Default to current
** system date and time
** @param {boolean, optional} obj - if true, return a Date object. Otherwise, return
** an ISO 8601 formatted string
*/
function getLondonTime(d, obj) {
// Use provided date or default to current date and time
d = d || new Date();
// Get start and end dates for daylight saving for supplied date's year
// Set UTC date values and time to 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 is between dstStart and dstEnd, add 1 hour to UTC time
// and format using +60 offset
if (d > dstS && d < dstE) {
d.setUTCHours(d.getUTCHours() +1);
return formatDate(d, 60);
}
// Otherwise, don't adjust and format with 00 offset
return obj? d : formatDate(d);
}
document.write('Current London time: ' + getLondonTime(new Date()));
伦敦时间/英国夏令时:
const now = new Date();
console.log(now.toLocaleString('en-GB', { timeZone: 'Europe/London' }));
- Java脚本时间添加
- Json数据包含日期和时间格式
- 如何根据时间运行不同的脚本
- 用每小时的差值填充数组/列表-从下拉列表中给定两个时间值
- 在wordpress一定时间后更改自定义字段
- 更改angularjs中的日期-时间格式
- 将当前时间添加到我的页面上的特定部分
- 门户网站:当地时间有多有用
- 显示时间的脚本
- 如何在窗体打开时从javascript倒计时计时器值中节省时间
- 通过JSON&比较时间
- Javascript时间轨迹
- 将日期时间作为 JSON 发送将无法在我的视图中正确显示
- 将日期时间从json转换为可读格式
- 高库存时期时间与时区不匹配
- Jquery如何检查今天的时间大于使用给定时间
- jquerydatetimepicker日期和时间应在框默认值中,而无需单击框
- primefaces日历可以禁用过去的日期和时间吗
- 从日期对象计算 BST 时间
- 在JavaScript中从没有BST的时间戳中格式化日期