我见过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

哪一个是正确的?还是最好的?这方面有什么标准吗?


当前回答

我认为通用互操作性的最佳格式不是ISO-8601字符串,而是EJSON使用的格式:

{“myDateField”:{“$date”:<ms since epoch>}}

如下所述:https://docs.meteor.com/api/ejson.html

福利

解析性能:如果您将日期存储为ISO-8601字符串,那么如果您希望在该特定字段下有一个日期值,那么这是很好的,但是如果您有一个系统必须在没有上下文的情况下确定值类型,那么您将解析每个字符串的日期格式。无需日期验证:您不必担心日期的验证和验证。即使字符串与ISO-8601格式匹配,它也可能不是真正的日期;这绝不会发生在EJSON约会中。明确的类型声明:就通用数据系统而言,如果您希望在一种情况下将ISO字符串存储为字符串,而在另一种情况中存储真实的系统日期,则采用ISO-8601字符串格式的通用系统在机械上不允许这样做(没有转义技巧或类似的糟糕解决方案)。

结论

我知道,人类可读的格式(ISO-8601字符串)对于80%的用例来说是有用的,而且更方便,如果应用程序能够理解的话,确实不应该告诉任何人不要将日期存储为ISO-8601的字符串,但是对于一种普遍接受的传输格式来说,我们怎么能允许歧义和这么多验证的需要?

其他回答

JSON对日期一无所知。.NET所做的是非标准的黑客/扩展。

我会使用一种可以很容易地转换为JavaScript中的Date对象的格式,即可以传递给新的Date(…)的格式。最简单也是最可移植的格式是1970年以来包含毫秒的时间戳。

仅供参考,我见过这种格式:

Date.UTC(2017,2,22)

它与$.getJSON()函数支持的JSONP一起工作。我不确定我会推荐这种方法。。。只是把它作为一种可能性,因为人们是这样做的。

FWIW:不要在通信协议中使用从epoch开始的秒数,也不要使用从epoth开始的毫秒数,因为由于闰秒的随机实现,这些都充满了危险(你不知道发送方和接收方是否都正确地实现了UTC闰秒)。

有点讨厌,但许多人认为UTC只是GMT的新名称——错了!如果您的系统没有实现闰秒,那么您使用的是GMT(尽管不正确,但通常称为UTC)。如果你完全实现了闰秒,你真的在使用UTC。未来的闰秒是未知的;IERS在必要时发布它们,并需要不断更新。如果您运行的系统试图实现闰秒,但包含过期的参考表(比您想象的更常见),那么您既没有GMT,也没有UTC,那么您的系统就假装是UTC。

这些日期计数器仅在以分解格式(y、m、d等)表示时才兼容。它们在历元格式中从不兼容。记住这一点。

我认为通用互操作性的最佳格式不是ISO-8601字符串,而是EJSON使用的格式:

{“myDateField”:{“$date”:<ms since epoch>}}

如下所述:https://docs.meteor.com/api/ejson.html

福利

解析性能:如果您将日期存储为ISO-8601字符串,那么如果您希望在该特定字段下有一个日期值,那么这是很好的,但是如果您有一个系统必须在没有上下文的情况下确定值类型,那么您将解析每个字符串的日期格式。无需日期验证:您不必担心日期的验证和验证。即使字符串与ISO-8601格式匹配,它也可能不是真正的日期;这绝不会发生在EJSON约会中。明确的类型声明:就通用数据系统而言,如果您希望在一种情况下将ISO字符串存储为字符串,而在另一种情况中存储真实的系统日期,则采用ISO-8601字符串格式的通用系统在机械上不允许这样做(没有转义技巧或类似的糟糕解决方案)。

结论

我知道,人类可读的格式(ISO-8601字符串)对于80%的用例来说是有用的,而且更方便,如果应用程序能够理解的话,确实不应该告诉任何人不要将日期存储为ISO-8601的字符串,但是对于一种普遍接受的传输格式来说,我们怎么能允许歧义和这么多验证的需要?

没有正确的格式;JSON规范没有指定交换日期的格式,这就是为什么有这么多不同的方法。

最好的格式可以说是以ISO 8601格式表示的日期(参见维基百科);它是一种众所周知且广泛使用的格式,可以跨多种不同语言处理,因此非常适合互操作性。例如,如果您可以控制生成的json,则可以以json格式向其他系统提供数据,选择8601作为日期交换格式是一个不错的选择。

例如,如果您无法控制生成的json,那么您是来自多个不同现有系统的json的使用者,最好的处理方法是使用日期解析实用程序函数来处理不同的格式。

这是我的工作与解析服务器

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