У меня есть страница, которая в настоящее время использует микроформат datetime для отображения метки времени, но я показывал только удобочитаемое время для моего часового пояса:
<abbr class = "published" title = "2009-01-09T09:16:00-05:00">
Friday, January 9, 2009 at 9:16 am (EST)</abbr>
Я бы хотел переписать innerHTML для тега abbr в том же формате, но в локальном часовом поясе пользователя. Итак, для читателя из Сиэтла приведенное выше должно быть преобразовано в:
<abbr class = "published" title = "2009-01-09T09:16:00-05:00">
Friday, January 9, 2009 at 6:16 am (PST)</abbr>
Я посмотрел на Объект Javascript Date, который позволяет мне получить смещение местного часового пояса. Но у меня есть несколько проблем:
Я не вижу простого способа создать новый объект Date из метки времени ISO-8601. (Полагаю, я мог бы анализировать с помощью подстрок или регулярных выражений, если бы не было более быстрого способа.)
Я не вижу способа получить названное сокращение для часового пояса. Например, для читателя в Сиэтле я бы хотел, чтобы время добавлялось в конец "(PST)", иначе этому пользователю будет непонятно, что метка времени была преобразована (особенно если он является частым посетителем и уже привык к тому, что мои времена в EST).



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вот мой код, который анализирует временную метку ISO:
function isoDateStringToDate (datestr) {
if (! this.re) {
// The date in YYYY-MM-DD or YYYYMMDD format
var datere = "(\\d{4})-?(\\d{2})-?(\\d{2})";
// The time in HH:MM:SS[.uuuu] or HHMMSS[.uuuu] format
var timere = "(\\d{2}):?(\\d{2}):?(\\d{2}(?:\\.\\d+)?)";
// The timezone as Z or in +HH[:MM] or -HH[:MM] format
var tzre = "(Z|(?:\\+|-)\\d{2}(?:\\:\\d{2})?)?";
this.re = new RegExp("^" + datere + "[ T]" + timere + tzre + "$");
}
var matches = this.re.exec(datestr);
if (! matches)
return null;
var year = matches[1];
var month = matches[2] - 1;
var day = matches[3];
var hour = matches[4];
var minute = matches[5];
var second = Math.floor(matches[6]);
var ms = matches[6] - second;
var tz = matches[7];
var ms = 0;
var offset = 0;
if (tz && tz != "Z") {
var tzmatches = tz.match(/^(\+|-)(\d{2})(\:(\d{2}))$/);
if (tzmatches) {
offset = Number(tzmatches[2]) * 60 + Number(tzmatches[4]);
if (tzmatches[1] == "-")
offset = -offset;
}
}
offset *= 60 * 1000;
var dateval = Date.UTC(year, month, day, hour, minute, second, ms) - offset;
return new Date(dateval);
}
К сожалению, он также не обрабатывает аббревиатуры часовых поясов. Вам придется изменить выражение "tzre", чтобы принимать буквы, и единственное известное мне решение для работы с сокращениями часовых поясов в Javascript - это иметь справочную таблицу, которую вы будете обновлять вручную в случае изменений региональных летнее время.
Хороший улов, что "var ms = 0;" там вообще не должно быть. Оглядываясь назад, я почти уверен, что в регулярном выражении, соответствующем часовому поясу, где-то отсутствует квантификатор ноль или один.
EcmaScript формализовал добавление строки стиля ISO-8601 в качестве импута для даты JavaScript. Поскольку большинство реализаций JS не поддерживают это, я создал оболочку для объекта Date, которая имеет эту функцию. Если вы установите теги заголовков для вывода со смещением UTC / GMT / Z / Zulu, вы можете использовать мой Расширения EcmaScript 5 для объекта Date JS.
Для значений DateTime, которые должны использоваться в клиентских скриптах, я обычно стараюсь всегда делать следующее. Сохранять дату + время в зоне UTC (даже в базах данных). Дата и время передачи в зоне UTC. От клиента к серверу вы можете использовать метод .toISOString () по указанной выше ссылке. От сервера к клиенту это относительно просто.
Через jQuery (с расширением):
$('.published').each(function(){
var dtm = new Date(this.title);
if (!isNaN(dtm)) {
this.text(dtm.toString());
}
});Я не помню, добавил ли я во входные данные поддержку даты, отличной от utc, но учесть их было бы несложно.
Вы использовали переменную "ms" дважды подряд, аннулировав ее предыдущее использование.