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

874

Я видел так много разных стандартов для формата даты 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

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

  • 57
    В JSON нет формата даты, есть только строки, которые де-сериализатор решает сопоставить со значениями даты.
  • 9
    strings , numbers , true , false , null , objects и arrays
Показать ещё 5 комментариев
Теги:

11 ответов

1427
Лучший ответ

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

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

2012-04-23T18:25:43.511Z

Вот почему:

  • Это человек, читаемый, но также сжатый

  • Сортировка правильно

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

  • Он соответствует ISO 8601

  • ИСО 8601 хорошо зарекомендовал себя на международном уровне уже более десяти лет.

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

Говоря, каждая библиотека дат, когда-либо написанная, может понимать "миллисекунды с 1970 года". Таким образом, для удобства переноски ThiefMaster прав.

  • 25
    Это также предпочтительные представления в соответствии с ECMA : JSON.stringify({'now': new Date()}) "{"now":"2013-10-21T13:28:06.419Z"}"
  • 8
    Я бы добавил еще одну важную причину в список: он не зависит от локали. Если у вас была такая дата, как 02-03-2014, вам понадобится дополнительная информация, чтобы узнать, относится ли она к 3 февраля или 2 марта. Это зависит от того, используется ли формат США или другой формат.
Показать ещё 22 комментария
113

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

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

  • 1
    Является ли встроенный в JSON формат JSON.stringify наиболее приемлемым? И почему?! почему нет никакого стандарта на это? и все же все браузеры ведут себя одинаково при строковом объекте Date ?!
  • 2
    Тьфу, я бы ожидал ошибку ... Но, по крайней мере, Firefox действительно ее исправляет ... ну, это не является частью стандарта JSON, поэтому я бы не передавал объект Date в сериализатор JSON - он может работать не во всех браузеры. Очевидно, для сериализаторов JSON характерно использовать функцию toJSON() если она существует в неизвестном объекте. По крайней мере, Firefox делает это для объектов Date и Date.
Показать ещё 11 комментариев
32

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

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

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

  • 1
    @mlissner, но это мнение о том, какой из них лучше. ISO-8601 - это стандарт, но он не является стандартом для JSON (хотя я был бы склонен использовать его); например, Microsoft решила не использовать его ( msdn.microsoft.com/en-us/library/… ). Лучшая практика - придерживаться одного (разумного) соглашения, что бы это ни было. Как я уже говорил в ответе, лучший способ справиться с этим - определить вспомогательную функцию анализа даты, которая может обрабатывать ожидаемые форматы. Если вы интегрируетесь с системами, которые используют разные форматы, функция должна обрабатывать каждый случай.
  • 1
    @RussCam, мы можем идти вперед и назад, но если кто-то спрашивает, как лучше кодировать даты в JSON, они спрашивают, как форматировать даты, когда они создают JSON (и ответ обычно ISO-8601). Вы отвечаете на противоположный вопрос: как использовать даты JSON, когда они уже сделаны (хотя ваш совет обоснован).
Показать ещё 3 комментария
22

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

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

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

  • 2
    Это также формат, создаваемый Date().toISOString() и Date().toJSON() , с ограничением, что Date не отслеживает значение часового пояса и, следовательно, всегда генерирует временные метки в часовом поясе UTC ( Z ). Значение может быть проанализировано с использованием new Date("...") и Date.parseDate .
9

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

Date.UTC(2017,2,22)

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

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

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

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

  • 3
    Я бы не стал использовать этот формат, но остальная информация, которую вы предоставили, очень полезна, спасибо!
0

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

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

Изображение 2201

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

  • 2
    Правильный! Синтаксис обмена данными JSON не определяет стандарт: ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf, но на практике форматы, совместимые с ISO 8601, более желательны для разных платформ, включая среду выполнения JavaScript.
0

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

yourDate.substring(0,10)

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

-3

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

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

  • 0
    Комментарии были перемещены в чат .
  • 4
    Теперь у вас есть 2 проблемы: какую эпоху выбрать и какие миллисекунды считать? Вероятно, наиболее распространенным выбором является время Unix (1970-01-01T00: 00: 00 UTC и миллисекунды SI, за исключением тех, которые находятся в пределах високосной секунды), но, конечно, это делает будущие времена неопределенными.
Показать ещё 4 комментария
-4

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

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);
-4

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

{
    "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"
            }
}
-11

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

{
"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. Также это верно только для даты и времени, имеющих одинаковое смещение часового пояса.

  • 6
    Я сомневаюсь, что кто-то будет использовать json в 10000 году, или даже в том, что к этому времени 10000 будет все еще годом 10000. Но если к тому времени обе эти вещи все еще верны, формат можно просто расширить, чтобы он содержал 3 цифры. век компонент. Так что я бы сказал, что люди могут безопасно придерживаться RFC 3339, по крайней мере, до 9900 года
  • 6
    @ downvoters: Согласно Почему так важно голосование? Вам следует понизить голосование, если post contains wrong information, is poorly researched, or fails to communicate information изучено post contains wrong information, is poorly researched, or fails to communicate information . Пожалуйста, объясните, по какой из этих причин вы отклонили этот ответ.
Показать ещё 9 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню