"Правильный" формат даты JSON

Я видел так много разных стандартов для формата даты JSON:

"\"\\/Date(1335205592410)\\/\""         .NET JavaScriptSerializer
"\"\\/Date(1335205592410-0500)\\/\""    .NET DataContractJsonSerializer
"2012-04-23T18:25:43.511Z"              JavaScript built-in JSON object
"2012-04-21T18:25:43-05:00"             ISO 8601

Какой из них правильный? Или лучше? Есть ли какой-то стандарт на этом?

Ответы

Ответ 1

Сам JSON не определяет, как даты должны быть представлены, но JavaScript делает.

Вы должны использовать формат, испускаемый методом Date toJSON:

2012-04-23T18:25:43.511Z

Вот почему:

  1. Это читаемое человеком, но также краткое

  2. Сортирует правильно

  3. Он включает доли секунды, которые могут помочь восстановить хронологию

  4. Соответствует ISO 8601

  5. ISO 8601 был признан во всем мире уже более десяти лет.

  6. ISO 8601 одобрен W3C, RFC3339 и XKCD

При этом каждая библиотека дат, когда-либо написанная, может понимать "миллисекунды с 1970 года". Так что для легкой переносимости, ThiefMaster подходит.

Ответ 2

JSON ничего не знает о датах. Что делает .NET нестандартным взломом/расширением.

Я бы использовал формат, который можно легко преобразовать в объект Date в JavaScript, то есть тот, который можно передать в new Date(...). Самый простой и, вероятно, самый переносимый формат - это метка времени, содержащая миллисекунды с 1970 года.

Ответ 3

Там нет правильного формата; Спецификация JSON не определяет формат для обмена датами, поэтому существует так много разных способов сделать это.

Наилучшим форматом, возможно, является дата, представленная в формате ISO 8601 (см. Википедия); Это хорошо известный и широко используемый формат, который может обрабатываться на разных языках, что делает его очень подходящим для взаимодействия. Например, если у вас есть контроль над сгенерированным json, вы предоставляете данные другим системам в формате json, выбрав 8601 в качестве формата обмена датами.

Если у вас нет контроля над сгенерированным json, например, вы являетесь пользователем json из нескольких различных существующих систем, то лучший способ справиться с этим - использовать служебную функцию анализа даты для обработки различных ожидаемых форматов.

Ответ 4

Из RFC 7493 (Формат сообщений I-JSON):

I-JSON означает либо Internet JSON, либо Interoperable JSON, в зависимости от того, кого вы спросите.

Протоколы часто содержат элементы данных, которые предназначены для временных меток или продолжительности времени. РЕКОМЕНДУЕТСЯ, что все такие данные элементы выражаются в виде строковых значений в формате ISO 8601, как указано в RFC 3339, с дополнительными ограничениями, чем буквы нижнего регистра, чтобы включить часовой пояс не по умолчанию, и что дополнительные секундные секунды будут включены, даже если их значение равно "00". Также РЕКОМЕНДУЕТ, что все элементы данных содержащие продолжительности времени, соответствуют "длительности" производства в Приложение A RFC 3339 с теми же дополнительными ограничениями.

Ответ 5

Только для справки я видел этот формат:

Date.UTC(2017,2,22)

Он работает с JSONP, который поддерживается функцией $.getJSON(). Не уверен, что я зашел так далеко, чтобы рекомендовать этот подход... просто бросая его туда как возможность, потому что люди делают это таким образом.

FWIW: Никогда не используйте секунды с эпохи в протоколе связи или миллисекунды с эпохи, потому что это чревато опасностью благодаря рандомизированной реализации секунд прыжка (вы понятия не имеете, отправитель и получатель оба правильно реализуют секунды прыжка в формате UTC).

Вид домашней ненависти, но многие люди считают, что UTC - это просто новое имя для GMT - неправильно! Если ваша система не реализует секунды прыжка, вы используете GMT ​​(часто называемый UTC, несмотря на то, что он неверен). Если вы полностью реализуете прыжковые секунды, вы действительно используете UTC. Невозможно знать будущие секунды прыжка; они публикуются IERS по мере необходимости и требуют постоянных обновлений. Если вы используете систему, которая пытается реализовать прыжки секунд, но содержит и устаревшую ссылочную таблицу (более часто, чем вы думаете), то у вас нет ни GMT, ни UTC, у вас есть система ожидания, претендующая на UTC.

Эти счетчики даты совместимы только при выражении в разбитом формате (y, m, d и т.д.). Они НИКОГДА не совместимы в формате эпохи. Помните об этом.

Ответ 6

Сам JSON не имеет формата даты, ему все равно, как кто-то хранит даты. Однако, поскольку этот вопрос помечен javascript, я предполагаю, что вы хотите знать, как хранить даты javascript в JSON. Вы можете просто передать дату методу JSON.stringify, и он будет использовать Date.prototype.toJSON по умолчанию, который, в свою очередь, использует Date.prototype.toISOString (MDN в Date.toJSON):

const json = JSON.stringify(new Date());
const parsed = JSON.parse(json); //2015-10-26T07:46:36.611Z
const date = new Date(parsed); // Back to date object

Я также счел полезным использовать параметр reviver в JSON.parse (MDN в JSON.parse) для автоматического преобразования строк ISO обратно в даты JavaScript при каждом чтении строк JSON.

const isoDatePattern = new RegExp(/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/);

const obj = {
 a: 'foo',
 b: new Date(1500000000000) // Fri Jul 14 2017, etc...
}
const json = JSON.stringify(obj);

// Convert back, use reviver function:
const parsed = JSON.parse(json, (key, value) => {
    if (typeof value === 'string' &&  value.match(isoDatePattern)){
        return new Date(value); // isostring, so cast to js date
    }
    return value; // leave any other value as-is
});
console.log(parsed.b); // // Fri Jul 14 2017, etc...

Ответ 7

Я считаю, что лучшим форматом универсального взаимодействия является не строка ISO-8601, а формат, используемый EJSON:

{ "myDateField": { "$date": <ms-since-epoch> } }

Как описано здесь: https://docs.meteor.com/api/ejson.html

Выгоды

  1. Производительность синтаксического анализа: если вы сохраняете даты в виде строк ISO-8601, это хорошо, если вы ожидаете значение даты в этом конкретном поле, но если у вас есть система, которая должна определять типы значений без контекста, вы анализируете каждую строку для Формат даты.
  2. Нет необходимости в проверке даты : вам не нужно беспокоиться о проверке даты. Даже если строка соответствует формату ISO-8601, она не может быть реальной датой; это никогда не может произойти с датой EJSON.
  3. Однозначное объявление типа: что касается универсальных систем данных, если вы хотите сохранить строку ISO в виде строки в одном случае и реальную системную дату в другом, универсальные системы, использующие формат строки ISO-8601, не позволят этого механически (без уловок или подобных ужасных решений).

Заключение

Я понимаю, что читаемый человеком формат (строка ISO-8601) полезен и более удобен для 80% случаев использования, и, действительно, никто никогда не должен указывать не хранить свои даты в виде строк ISO-8601, если это их приложения. понять, но для общепринятого транспортного формата, который должен гарантировать определенные значения, которые наверняка будут датами, как мы можем допустить двусмысленность и необходимость в такой большой проверке?

Ответ 8

В случае сомнений просто перейдите в веб-консоль javascript современного браузера, нажав F12 (Ctrl + K в Firefox), и напишите следующее:

new Date().toISOString()

Будет выводить:

"2019-07-04T13:33:03.969Z"

Та-да !!

Ответ 9

В Sharepoint 2013, получая данные в JSON, нет формата для преобразования даты только в формат даты, потому что в эту дату должен быть формат ISO

yourDate.substring(0,10)

Это может быть полезно для вас

Ответ 10

Предпочтительным способом является использование 2018-04-23T18:25:43.511Z...

На рисунке ниже показано, почему это предпочтительный способ:

JSON Date

Итак, как вы видите, у Date есть собственный метод toJSON, который return в этом формате и может быть легко преобразован в Date снова...

Ответ 11

var myDateFormate = DateConvert (YourDate);//вывод ex: 01-Jan-2019

function DateConvert(data) {
    var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
    var data1 = data.replace("/Date(", "").replace(")/", "");
    var date = new Date(parseInt(data1));
    var month = date.getMonth();// + 1;
    return date.getDate() + "-" + (month.length > 1 ? month : monthNames[month]) + "-" + date.getFullYear();
}

Ответ 12

это работа для меня с сервером разбора

{
    "ContractID": "203-17-DC0101-00003-10011",
    "Supplier":"Sample Co., Ltd",
    "Value":12345.80,
    "Curency":"USD",
    "StartDate": {
                "__type": "Date",
                "iso": "2017-08-22T06:11:00.000Z"
            }
}

Ответ 13

Есть только один правильный ответ на это, и большинство систем ошибочно. Число миллисекунд с эпохи, а также 64-битное целое число. Часовой пояс - это проблема с пользовательским интерфейсом и не имеет бизнеса на уровне приложения или уровне db. Почему ваш db заботится о том, в каком часовом поясе что-то есть, когда вы знаете, что он будет хранить его как 64-битное целое число, а затем выполнить вычисления преобразования.

Извлеките посторонние биты и просто обработайте даты как числа до пользовательского интерфейса. Вы можете использовать простые арифметические операторы для выполнения запросов и логики.

Ответ 14

Следующий код работал для меня. Этот код будет печатать дату в формате ДД-ММ-ГГГГ.

DateValue=DateValue.substring(6,8)+"-"+DateValue.substring(4,6)+"-"+DateValue.substring(0,4);

иначе вы также можете использовать:

DateValue=DateValue.substring(0,4)+"-"+DateValue.substring(4,6)+"-"+DateValue.substring(6,8);

Ответ 15

Я думаю, что это действительно зависит от варианта использования. Во многих случаях может быть выгоднее использовать правильную объектную модель (вместо отображения даты в строке), например так:

{
"person" :
      {
 "name" : {
   "first": "Tom",
   "middle": "M",
  ...
}
 "dob" :  {
         "year": 2012,
         "month": 4,
         "day": 23,
         "hour": 18,
         "minute": 25,
         "second": 43,
         "timeZone": "America/New_York"
    }   
   }
}

Следует признать, что это более многословно, чем RFC 3339, но:

  • это человек, читаемый, а также
  • он реализует правильную объектную модель (как в ООП, насколько это позволяет JSON)
  • он поддерживает часовые пояса (не только смещение UTC на заданную дату и время)
  • он может поддерживать меньшие единицы, такие как миллисекунды, наносекунды,... или просто доли секунды
  • он не требует отдельного шага разбора (для разбора строки даты и времени), JSON-анализатор все сделает за вас
  • легкое создание с любой структурой даты и времени или реализация на любом языке
  • может быть легко расширен для поддержки других календарных шкал (иврит, китайский, исламский...) и эпох (AD, BC,...)
  • это год 10000 безопасно ;-) (RFC 3339 не)
  • поддерживает даты за весь день и плавающее время (Javascript Date.toJSON() нет)

Я не думаю, что правильная сортировка (как отмечает funroll для RFC 3339) - это функция, которая действительно нужна при сериализации даты в JSON. Также это верно только для даты и времени, имеющих одинаковое смещение часового пояса.