Получить текущее смещение по Гринвичу из идентификатора часового пояса

Как получить текущее смещение по Гринвичу из идентификатора часового пояса? В идеале, он также должен включать полное имя формы.

Например:

"America/Los_Angeles"  //output: GMT-0700 (Pacific Daylight Time)

Было бы неплохо, если бы он работал и со строками ISO, например:

2020-12-21T03:57:00Z   //output: GMT-0800 (Pacific Standard Time)

person haha    schedule 02.05.2020    source источник


Ответы (1)


Вы можете использовать параметры timeZone и timeZoneName в Intl.DateTimeFormat, как показано ниже, чтобы получить название более распространенных часовых поясов, но менее известные, вероятно, будут отсутствовать. Также:

  1. Вы не можете получить их оба в одном и том же вызове, поэтому вам нужно вызвать его дважды.
  2. В некоторых случаях вы просто получите короткие и длинные имена без фактического смещения.
  3. Имена часовых поясов не стандартизированы, поэтому разные реализации могут возвращать разные имена или просто фактическое смещение без имени.
  4. Вы получите смещение для даты и времени, которые вы создаете, а не дату и время для местоположения, поэтому может быть неправильно, если эта разница пересекает границу летнего времени.

e.g.

// Get short offset, might show the actual offset but might be a short name
let formatterA = new Intl.DateTimeFormat('en',{timeZone:'America/New_York', timeZoneName:'short'});
console.log( formatterA.format(new Date()) ); // 5/2/2020, EDT

// Get short offset, might show the actual offset but might be a short name
let formatterB = new Intl.DateTimeFormat('en',{timeZone:'America/New_York', timeZoneName:'long'});
console.log( formatterB.format(new Date()) ); // 5/2/2020, Eastern Daylight Time

Другая стратегия получения смещения заключается в создании даты в часовом поясе и получении разницы с датой в формате UTC с теми же значениями года, месяца, дня и т. д. путем анализа результатов. У него все еще есть проблема с переходом на летнее время. Intl.DateTimeFormat.prototype.formatToParts помогает как для этого ответа.

Тем не менее, я предлагаю вам использовать такую ​​библиотеку, как Luxon, так как возня с этим материалом может привести к головной боли, особенно немного вокруг изменений перехода на летнее время.

var DateTime = luxon.DateTime;

let d = DateTime.fromISO("2017-05-15T09:10:23", { zone: "Europe/Paris" });

console.log(d.toFormat('ZZ'));    // +02:00
console.log(d.toFormat('ZZZZZ')); // Central European Summer Time

let e = DateTime.fromISO("2017-05-15T09:10:23", { zone: "Pacific/Kiritimati" });

console.log(e.toFormat('ZZ'));    // +14:00
console.log(e.toFormat('ZZZZZ')); // Line Islands Time 
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/global/luxon.min.js"></script>

person RobG    schedule 02.05.2020
comment
@yogadog — строка, созданная встроенным модулем Date.prototype.toString, определена в ECMA-262 для включения значения смещения, однако строка имени часового пояса зависит от реализации и необязательна, а имя и смещение указаны только в часовом поясе хоста, поэтому на самом деле не имеют отношения к вопросу. - person RobG; 03.05.2020