Из ISO-8601: 2004 (E) Спецификация:
4.2.2.4 Представления с десятичной дробью
- Файл Ajax / Flash загружается с индикатором выполнения?
- Назначение массива php в массив javascript
- Доступ к данным $ _POST в API PayPal returnURL
- пусть jquery знает, какая была последняя посещаемая php-страница?
- Пакет SCORM не связывается с LMS
При необходимости для конкретного приложения может быть включена десятичная доля часа, минуты или секунды. Если включена десятичная дробь, элементы нижнего порядка (если они есть) должны быть опущены, а десятичная дробь должна быть разделена на целую часть десятичным знаком, указанным в ISO 31-0, то есть запятой [,] или полной остановкой [ .]. Из них запятая является предпочтительным знаком.
Достаточно просто. Таким образом, согласно этой спецификации, доли секунды предпочтительнее записывать с использованием запятой, разделяющей целую и десятичную части, такие как 2014-01-01T00:00:00,123
. Однако кажется, что почти везде, только десятичная точка (ака «полная остановка») принимается!
Теперь я уверен, что есть некоторые языки или библиотеки, которые учитывали это, и я знаю, что во многих случаях вы можете предоставить полную информацию о формате самостоятельно. Но это похоже на такой вопиющий контроль над спецификацией, и кажется, что большое количество программистов совершили ту же ошибку. Есть ли причина, почему это так, кроме чистой человеческой ошибки?
Ниже приведен список тех, где я тестировал. Не стесняйтесь редактировать вопрос, чтобы увеличить мой список, если найдете другие. Благодарю.
DateTime dt = DateTime.Parse("2014-01-01T00:00:00,123");
Выдает FormatException
с сообщением «String не был признан допустимым DateTime». То же самое с периодом, а не с запятой, выполняется успешно.
Протестировано в последнее время (на момент написания этой статьи) Chrome, Internet Explorer, Firefox и Node.js:
var dt = new Date('2014-01-01T00:00:00,123');
Возвращает "Invalid Date"
. Использование периода работает отлично.
var valid = moment("2014-01-01T00:00:00,123").isValid();
Возвращает false
. Использование периода вместо этого возвращает true
.
echo strtotime('2014-01-01T00:00:00,123');
Возвращает пустую строку. Использование периода работает отлично.
require 'time' puts Time.iso8601("2014-01-01T00:00:00,123")
Дает ошибку времени выполнения. Хотя Time
не сохраняет дробные секунды, это не должно быть ошибкой – и действительно, если период используется вместо этого, он работает.
Чистый ISO-8601-совместимый анализатор ДОЛЖЕН поддерживать как запятую, так и точку. Запятая не требуется строго, рекомендуется только. Поэтому в отношении этого стандарта приведенные примеры JavaScript, PHP, Ruby и т. Д. Четко указывают на ошибку этих реализаций парсера.
RFC3339 действительно поддерживает только подмножество (исключая запятую И также исключая десятичные часы или десятичные минуты!) – поэтому не полностью соответствует ISO.
XML-схема похожа. К сожалению, он не содержит запятую (см. Документ W3C).
Итак, вы спрашиваете, почему? Это мое подозрение: в мире программирования сильно доминируют США. В американской культуре точка используется как десятичный разделитель в числах. Поэтому большинство людей, разрабатывающих такие рамки, стандарты и библиотеки, сидят в США и ошибочно считают, что точки являются квази-международным стандартом.
Поэтому остается вопрос, почему ISO использует / рекомендует запятую? Я точно не знаю, но мы все знаем, что офис группы ИСО находится в Париже, а не в США. А в Европе (исключая Великобританию) запятая обычно предпочтительнее как десятичный разделитель, а также культурный аспект.
Наконец, не все парсеры ошибаются. По крайней мере, Joda-Time поддерживает также запятую, хотя предпочитает точку в печати. Какова ситуация в NodaTime? Надеюсь, по крайней мере, похоже на Joda-Time. Продолжайте поддерживать разбор запятой. С европейской точки зрения приятно видеть, что не все вещи выглядят как американские ;-).
RFC3339 , как определено IETF, указывает только .
как разделитель.
Вот раздел 5.6:
5.6. Internet Date/Time Format The following profile of ISO 8601 [ISO8601] dates SHOULD be used in new protocols on the Internet. This is specified using the syntax description notation defined in [ABNF]. date-fullyear = 4DIGIT date-month = 2DIGIT ; 01-12 date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on ; month/year time-hour = 2DIGIT ; 00-23 time-minute = 2DIGIT ; 00-59 time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap second ; rules time-secfrac = "." 1*DIGIT time-numoffset = ("+" / "-") time-hour ":" time-minute time-offset = "Z" / time-numoffset partial-time = time-hour ":" time-minute ":" time-second [time-secfrac] full-date = date-fullyear "-" date-month "-" date-mday full-time = partial-time time-offset date-time = full-date "T" full-time