问题
From the ISO-8601:2004(E) Specification:
4.2.2.4 Representations with decimal fraction
If necessary for a particular application a decimal fraction of hour, minute or second may be included. If a decimal fraction is included, lower order time elements (if any) shall be omitted and the decimal fraction shall be divided from the integer part by the decimal sign specified in ISO 31-0, i.e. the comma [,] or full stop [.]. Of these, the comma is the preferred sign.
Simple enough. So according to this spec, fractions of a second are preferred to be written using a comma separating the whole and decimal parts, such as 2014-01-01T00:00:00,123
. However it seems that just about everywhere, only a decimal point (aka "full stop") is accepted!
Now I'm sure there are some languages or libraries that took this into account, and I know in many cases you can supply the full details of the format yourself. But it seems like such a glaring oversight of the specification and it appears that a wide variety of programmers have made the same mistake. Is there a reason why this is the case, other than pure human error?
Below is a list of where I tested. Feel free to edit the question to augment my list if you find any others. Thanks.
.NET / C#
DateTime dt = DateTime.Parse("2014-01-01T00:00:00,123");
Throws a FormatException
with the message "String was not recognized as a valid DateTime". The same thing with a period instead of a comma parses successfully.
JavaScript Date Object
Tested in latest (as of this writing) Chrome, Internet Explorer, Firefox and Node.js:
var dt = new Date('2014-01-01T00:00:00,123');
Returns "Invalid Date"
. Using a period instead works fine.
JavaScript with moment.js
var valid = moment("2014-01-01T00:00:00,123").isValid();
Returns false
. Using a period instead returns true
.
PHP
echo strtotime('2014-01-01T00:00:00,123');
Returns an empty string. Using a period instead works fine.
Ruby
require 'time'
puts Time.iso8601("2014-01-01T00:00:00,123")
Gives a runtime error. While Time
doesn't keep fractional seconds, it shouldn't error - and indeed if a period is used instead, it works.
回答1:
A pure ISO-8601-compliant parser MUST support both comma and dot. The comma is not strictly required, only recommended. So regarding this standard the given examples of JavaScript, PHP, Ruby etc. clearly indicate an error of those parser implementations.
RFC3339 indeed only supports a subset (excluding the comma AND also excluding decimal hours or decimal minutes!) - so not fully ISO-compliant.
XML-schema is similar. It excludes the comma, unfortunately (see the W3C-document).
So you ask why? That is my suspicion: Programming world is strongly dominated by US. In US culture the dot is used as decimal separator in numbers. So most people developing such frameworks, standards and libraries are sitting in US and mistakenly think that dots are quasi an international standard.
So the question remains, why ISO uses/recommends the comma? I don't know it exactly, but we all know the office of ISO group is located in Paris, not in US. And in Europe (excluding UK) the comma is generally preferred as decimal separator, also a cultural aspect.
Finally, not all parsers are wrong. At least Joda-Time supports comma, too, although preferring the dot in printing. What is the situation in NodaTime? I hope at least similar to Joda-Time. Please keep supporting parsing of comma. From an european perspective it is nice to see that not all stuff looks like american ;-).
回答2:
RFC3339, as defined by the IETF specifies only the .
as a delimiter.
Here's section 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
来源:https://stackoverflow.com/questions/20699705/why-does-the-iso-8601-specification-appear-to-be-universally-ignored-when-it-com