Как я могу преобразовать микроформат даты и времени в местное время в javascript?

У меня есть страница, которая в настоящее время использует микроформат даты и времени для отображения метки времени, но я показывали только удобочитаемое время для моего собственного часового пояса:

<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, который позволяет мне получить местный часовой пояс компенсировать. Но у меня есть несколько проблем:

  1. Я не вижу простого способа создать новый объект Date из временной метки ISO-8601. . (Я полагаю, что мог бы анализировать подстроки или регулярные выражения, если нет более быстрого способа.)

  2. Я не вижу способа получить названную аббревиатуру для часового пояса. Например, для читателя в Сиэтле я бы хотел, чтобы в конце времени было добавлено «(PST)», иначе этому пользователю не будет ясно, была ли преобразована метка времени (особенно если он частый гость и уже привык к тому, что мои времена в EST).


person Kip    schedule 12.01.2009    source источник


Ответы (2)


Вот мой код, который анализирует метку времени 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 — это иметь справочную таблицу, которую вы обновляете вручную в случае изменений в региональных летнее время.

person Tony    schedule 12.01.2009
comment
Вы использовали переменную ms дважды подряд, аннулируя ее предыдущее использование. - person ; 09.06.2013
comment
Хороший улов, var ms = 0; там вообще не должно быть. Оглядываясь назад, я почти уверен, что в регулярном выражении, соответствующем часовому поясу, тоже где-то отсутствует квантификатор нуля или единицы. - person Tony; 12.06.2013

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, во входных данных, но было бы несложно их учесть.

person Tracker1    schedule 13.04.2010