Форматы отображения даты в зависимости от браузера и локализации

7 3

Преобразование форматов дат является одной из самых распространенных проблем, возникающих при разработке ПО. И такая, казалось бы, мелочь может сильно затруднить разработку.

Так, например, в Веб-доступе DIRECTUM при получении значения реквизита с помощью методов getValue() и getDispalyValue() возвращается строка в формате «dd.mm.yyyy».

Дата в базе sql хранится в формате – “yyyy-mm-dd hh24:mi:ss”

А формат даты, обрабатываемый браузером, ещё зависит и от поставщика:

  • Firefox – mm/dd/yyyy;
  • IE11 - mm/dd/yyyy или mm-dd-yyyy;
  • Chrome - mm/dd/yyyy или mm-dd-yyyy или mm.dd.yyyy.

Именно из-за этих особенностей, после выполнения следующего кода, в переменной myDate будет результат “InvalidDate”.

  var requisiteDate = WA.CR.form.requisites.Дата2.getValue();
  var myDate = new Date(requisiteDate);

Так как же работать с таким разнообразием форматов и не запутаться?

Строку необходимо преобразовать в формат понятный javascript с помощью метода replace().

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

Например:

  var requisite = WA.CR.form.requisites.Дата2;
  var requisiteDate = WA.CR.form.requisites.Дата2.getDisplayValue();
  maxDate = new Date(requisiteDate.replace(/(\d+).(\d+).(\d+)/, '$2/$1/$3')); 
  requisite.setValue(maxDate);

Так же стоит учитывать тот факт, что метод написания дат в английском языке отличается от русского. Ниже приведен перечень масок, который сможет покрыть базовые потребности при разработке с учетом локализации.

// Маска для перевода отображаемой в русской локализации даты в данные типа Дата
  var VisualToCompDateMask = '$3/$2/$1';
  // Маска для перевода отображаемой в русской локализации даты в русский формат
  var VisualToRussianDateMask = '$1.$2.$3';
  // Маска для перевода русской даты в формат, отображаемый в русской локализации 
  var RussianToVisualDateMask = '$1.$2.$3';
  // Переопределить маски для английской локализации
  if (currentCultureName === "en-US") {
    // Маска для перевода отображаемой в английской локализации даты в данные типа Дата
    VisualToCompDateMask = '$3/$1/$2';
    // Маска для перевода отображаемой в английской локализации даты в русский формат
    VisualToRussianDateMask = '$2.$1.$3';
    // Маска для перевода русской даты в формат, отображаемый в английской локализации
    RussianToVisualDateMask = '$2/$1/$3';
    }

Пример использования замены для правильного формирования и сравнения дат:

  // Перевести дату русского формата в тип Дата
  OldDeadline = new Date(result.replace(/(\d+).(\d+).(\d+)/, '$3/$2/$1'));
  // Сравнить запрашиваемую дату со сроком исполнения: если запросили меньше - вывести предупреждение
  if (new Date(dialog.form.requisites["Date"].getValue().replace(/(\d+).(\d+).(\d+)/, VisualToCompDateMask)) < OldDeadline) 
    { WA.CR.inlineHint.showError(L("NEW_DEADLINE_ERROR_MESSAGE")); }

Если есть необходимость преобразовать дату с проверкой на правильность самой даты, то можно воспользоваться функцией ParseDateTime.

/**
* Преобразовать строку в дату и время с учетом текущей локализации.
*
* @global
* @function parseDateTime
* @param {string} date Строка даты в формате ДД.ММ.ГГГГ ЧЧ:ММ
* @return {Date} Отформатированная строка.
*
* @example
* parseDateTime('1')
* parseDateTime('12.11.2012')
* parseDateTime('12.11.12 14:21')
*/

В качестве заключения следует отметить, что любые даты, с которыми вы работаете в javascript, желательно приводить к единому формату и типу Date, чтобы обеспечить их корректную обработку.

7
Авторизуйтесь, чтобы оценить материал.
3
Александр Чугунов

Не проще ли было сделать так, чтобы в WA по getValue() возвращалась дата, а не строка? Чтобы не писать каждый раз одно и то же и не мучаться с этим? 
Можно самому добавить метод getDate() (или аналог, упрощающий жизнь) для реквизита, но, думаю, вендору стоит задуматься над доработкой WA для реквизитов типа дата, если эта проблема реально существует и приходится такие костыли делать.

Юлия Баркова

У реквизита типа дата уже есть метод getDate. Вариант использования getDate не рассматривали?

Александр Чугунов

Юлия, в справке про getDate ничего нет... =( Если такой метод есть, то эта статья только научит некорректному подходу. Рецензенты, ау....

Авторизуйтесь, чтобы написать комментарий