问题描述
我在亚洲,我想计算澳大利亚的偏移量.我知道如何计算代码的偏移量,如下所示:
I am in Asia and I want to calculate the offset of Australia. I know how to calculate the value of the offset the code is written below:
var timezone_offset = new Date().getTimezoneOffset();
但是如何计算其他位置呢?有人可以指导我吗?
But how to calculate it for the other locations? Anyone can guide me??
推荐答案
虽然可以用一个简短的函数完成 ,但是最好使用一个库,因为有许多要解决的问题.可以使用 toLocaleString 或 Intl.DateTimeFormat .
While this can be done in a short function, it would be best to use a library as there are many quirks to overcome. The offset can be determined using the timezone options of toLocaleString or Intl.DateTimeFormat.
但是,如果用于格式化的语言与位置的语言匹配,它将返回时区缩写而不是偏移量.为了解决这个问题,下面的函数首先使用英语,如果返回的是缩写而不是偏移量,则使用法语.英文偏移量从GMT开始,法语偏移量从UTC开始.偏移量为+0时,它们仅返回"GMT"或"UTC".
However, if the language used for formatting matches the language of the location, it returns the timezone abbreviation instead of the offset. To deal with that, the following function first uses English and if that returns the abbreviation rather than an offset, it uses French. English offsets start with GMT, French offsets start with UTC. Where the offset is +0, they return just "GMT" or "UTC".
已通过维基百科列出的所有IANA位置进行了测试,并且似乎适用于所有它们,但应该对其进行更广泛的测试.另外,在尝试运行功能之前,应该先进行功能测试(例如,对 Int.DateTimeFormat 构造函数, formatToParts 方法和 timeZoneName 选项的支持).
It's been tested with all IANA locations listed by wikipedia and seems to work for all of them but it should be tested more widely. Also, there should be feature tests before attempting to run it (i.e. support for Int.DateTimeFormat constructor, formatToParts method and the timeZoneName option).
// Return offset on date for loc in ±H[:mm] format. Minutes only included if not zero
function getTimezoneOffset(date, loc) {
// Try English to get offset. If get abbreviation, use French
let offset;
['en','fr'].some(lang => {
// Get parts - can't get just timeZoneName, must get one other part at least
let parts = new Intl.DateTimeFormat(lang, {
minute: 'numeric',
timeZone: loc,
timeZoneName:'short'
}).formatToParts(date);
// Get offset from parts
let tzName = parts.filter(part => part.type == 'timeZoneName' && part.value);
// timeZoneName starting with GMT or UTC is offset - keep and stop looping
// Otherwise it's an abbreviation, keep looping
if (/^(GMT|UTC)/.test(tzName[0].value)) {
offset = tzName[0].value.replace(/GMT|UTC/,'') || '+0';
return true;
}
});
// Format offset as ±HH:mm
// Normalise minus sign as ASCII minus (charCode 45)
let sign = offset[0] == '\x2b'? '\x2b' : '\x2d';
let [h, m] = offset.substring(1).split(':');
return sign + h.padStart(2, '0') + ':' + (m || '00');
}
let d = new Date();
console.log('Current offset for following locations:');
['Australia/Yancowinna',
'Australia/Lord_Howe',
'Australia/Canberra',
'Pacific/Honolulu',
'Europe/London',
'Canada/Eastern'
].forEach( loc =>
console.log(loc + ': ' + getTimezoneOffset(d, loc))
);
我不建议您使用此功能,这实际上是为了显示特定位置的偏移量有多混乱.
I don't suggest you use this function, it's really to show how messy getting the offset for a specific location can be.
请注意,澳大利亚有许多偏移量,有些地方有夏令时,而其他地方则没有.
Note that Australia has a number of offsets and some places observe daylight saving and others don't.
这篇关于获取其他位置在Javascript中的偏移量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!