1375

我见过很多不同的 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

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

4

15 回答 15

2215

JSON本身并没有指定日期应该如何表示,但 JavaScript 会。

应该使用Date'stoJSON方法发出的格式:

2012-04-23T18:25:43.511Z

原因如下:

  1. 它是人类可读的,但也很简洁

  2. 它正确排序

  3. 它包括小数秒,可以帮助重新建立年表

  4. 符合ISO 8601

  5. ISO 8601 已在国际上建立了十多年

  6. ISO 8601 得到W3CRFC3339XKCD的认可

话虽如此,曾经编写的每个日期库都可以理解“自 1970 年以来的毫秒数”。所以为了便于携带,ThiefMaster是对的。

于 2013-04-11T15:20:43.507 回答
144

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

我会使用一种可以轻松转换为DateJavaScript 对象的格式,即可以传递给new Date(...). 最简单且可能最便携的格式是自 1970 年以来包含毫秒的时间戳。

于 2012-04-23T18:34:02.300 回答
55

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

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

如果您无法控制生成的 json,例如,您是来自多个不同现有系统的 json 消费者,则处理此问题的最佳方法是使用日期解析实用程序函数来处理预期的不同格式。

于 2012-04-23T18:35:40.133 回答
32

来自RFC 7493(I-JSON 消息格式)

I-JSON 代表 Internet JSON 或 Interoperable JSON,具体取决于您询问的对象。

协议通常包含旨在包含时间戳或持续时间的数据项。建议将所有此类数据项表示为 ISO 8601 格式的字符串值,如RFC 3339中所指定,附加限制是使用大写而不是小写字母,不默认包含时区,以及可选的尾随秒数即使它们的值为“00”,也包括在内。还建议所有包含持续时间的数据项都符合 RFC 3339 附录 A 中的“持续时间”产生式,并具有相同的附加限制。

于 2015-03-27T18:48:00.117 回答
26

如有疑问,只需按F12(在 Firefox 中为Ctrl+ Shift+ K)进入现代浏览器的 javascript Web 控制台并编写以下内容:

new Date().toISOString()

将输出:

“2019-07-04T13:33:03.969Z”

达达!!

于 2019-07-04T13:35:21.890 回答
21

仅供参考,我已经看到使用这种格式:

Date.UTC(2017,2,22)

它适用于该函数支持的JSONP$.getJSON()。不确定我是否会推荐这种方法......只是把它作为一种可能性扔出去,因为人们正在这样做。

FWIW:永远不要在通信协议中使用自纪元以来的秒数,也不要使用自纪元以来的毫秒数,因为由于闰秒的随机实现(您不知道发送方和接收方是否都正确实现了 UTC 闰秒),这些都充满了危险。

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

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

于 2017-02-27T07:33:07.853 回答
9

“2014-01-01T23:28:56.782Z”

日期以标准且可排序的格式表示,该格式表示 UTC 时间(由 Z 表示)。ISO 8601 还通过将 Z 替换为时区偏移的 + 或 – 值来支持时区:

“2014-02-01T09:28:56.321-10:00”

ISO 8601 规范中的时区编码还有其他变体,但 –10:00 格式是当前 JSON 解析器支持的唯一 TZ 格式。一般来说,最好使用基于 UTC 的格式 (Z),除非您特别需要确定生成日期的时区(仅在服务器端生成中可能)。

注意:

    var date = new Date();
    console.log(date); // Wed Jan 01 2014 13:28:56 GMT- 
    1000 (Hawaiian Standard Time) 
        
    var json = JSON.stringify(date);
    console.log(json);  // "2014-01-01T23:28:56.782Z"

告诉你这是首选方式,即使 JavaScript 没有标准格式

// JSON encoded date
var json = "\"2014-01-01T23:28:56.782Z\"";

var dateStr = JSON.parse(json);  
console.log(dateStr); // 2014-01-01T23:28:56.782Z
于 2020-02-15T19:59:29.033 回答
8

JSON 本身没有日期格式,它不关心任何人如何存储日期。但是,由于这个问题是用 javascript 标记的,我假设您想知道如何在 JSON 中存储 javascript 日期。您可以将日期传递给该JSON.stringify方法,Date.prototype.toJSON默认情况下将使用它,然后使用Date.prototype.toISOStringMDN on 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

我还发现,每当我读取 JSON 字符串时,使用(JSON.parse 上reviver的 MDN)的参数自动将 ISO 字符串转换回 javascript 日期很有用。JSON.parse

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...
于 2019-05-08T13:04:19.213 回答
6

首选方法是使用2018-04-23T18:25:43.511Z...

下图显示了为什么这是首选方式:

JSON 日期

因此,如您所见, Date 有一个本机 Method toJSON,它return采用这种格式并且可以很容易地Date再次转换为......

于 2019-01-31T11:33:13.483 回答
4

我相信通用互操作性的最佳格式不是 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 字符串,如果这是他们的应用程序的话理解,但是对于应该保证某些值肯定是日期的普遍接受的传输格式,我们怎么能允许模棱两可并需要如此多的验证?

于 2019-02-08T09:01:50.673 回答
3

在 Sharepoint 2013 中,以 JSON 格式获取数据没有将日期转换为仅日期格式的格式,因为该日期应为 ISO 格式

yourDate.substring(0,10)

这可能对你有帮助

于 2016-09-16T11:09:02.150 回答
-3

解析服务器对我有用

{
    "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"
            }
}
于 2017-08-24T06:45:58.043 回答
-7

对此只有一个正确答案,而且大多数系统都会出错。自纪元以来的毫秒数,即 64 位整数。时区是一个 UI 问题,在 app 层或 db 层没有业务。为什么你的数据库关心什么是什么时区,当你知道它将把它存储为一个 64 位整数时,然后进行转换计算。

去掉无关的位,将日期视为 UI 上的数字。您可以使用简单的算术运算符来执行查询和逻辑。

于 2015-12-16T23:56:41.030 回答
-8

以下代码对我有用。此代码将以DD-MM-YYYY格式打印日期。

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);
于 2018-04-10T06:11:00.153 回答
-18

我认为这真的取决于用例。在许多情况下,使用适当的对象模型(而不是将日期呈现为字符串)可能更有益,如下所示:

{
"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 更冗长,但是:

  • 它也是人类可读的
  • 它实现了一个适当的对象模型(如在 OOP 中,只要 JSON 允许)
  • 它支持时区(不仅仅是给定日期和时间的 UTC 偏移量)
  • 它可以支持更小的单位,如毫秒、纳秒……或简单的小数秒
  • 它不需要单独的解析步骤(解析日期时间字符串),JSON 解析器将为您做所有事情
  • 使用任何日期时间框架或任何语言的实现轻松创建
  • 可以轻松扩展以支持其他日历刻度(希伯来语、汉语、伊斯兰...)和时代(AD、BC、...)
  • 10000 年是安全的;-)(RFC 3339 不是)
  • 支持全天日期和浮动时间(JavascriptDate.toJSON()不支持)

我不认为正确的排序(如 funroll 对 RFC 3339 所述)是在将日期序列化为 JSON 时真正需要的功能。这也仅适用于具有相同时区偏移的日期时间。

于 2016-01-01T15:30:19.970 回答