什么是“正确的” JSON日期格式?

2020/09/18 08:01 · javascript ·  · 0评论

我已经看到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

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

JSON本身没有指定日期应如何表示,但JavaScript却指定了。

应该使用DatetoJSON方法发出的格式

2012-04-23T18:25:43.511Z

原因如下:

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

  2. 排序正确

  3. 它包括小数秒,可以帮助重新建立时间顺序

  4. 符合ISO 8601

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

  6. W3CRFC3339XKCD认可ISO 8601

话虽这么说,每个日期库都可以理解“自1970年以来的毫秒数”。因此,为了方便携带,ThiefMaster是正确的。

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

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

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

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

例如,如果您无法控制生成的json,则您是几个不同现有系统中json的使用者,那么处理此问题的最佳方法是使用日期解析实用程序功能来处理所需的不同格式。

RFC 7493(I-JSON消息格式)开始

I-JSON代表Internet JSON或可互操作JSON,具体取决于您问谁。

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

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

Date.UTC(2017,2,22)

它与功能支持的JSONP一起使用$.getJSON()不确定我是否会推荐这种方法...只是把它扔出去是一种可能,因为人们是这样做的。

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

有点讨厌,但许多人认为UTC只是GMT的新名称-错误!如果您的系统未实现leap秒,则说明您使用的是GMT(尽管不正确,但通常称为UTC)。如果您完全实现了leap秒,则说明您确实在使用UTC。无法知道未来的leap秒;它们会在必要时由IERS发布,并且需要不断更新。如果您正在运行一个试图实施leap秒但包含和过时的参考表(比您想象的更常见)的系统,那么您既没有GMT也没有UTC,那么您的系统就会很虚假,假装为UTC。

这些日期计数器仅在以细分格式(y,m,d等)表示时才兼容。它们从不兼容于时代格式。记在脑子里。

如有疑问,只需按F12Ctrl+Shift+K在Firefox中)进入现代浏览器的javascript Web控制台,然后编写以下代码:

new Date().toISOString()

将输出:

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

-

JSON本身没有日期格式,它不在乎任何人如何存储日期。但是,由于此问题是用javascript标记的,因此我假设您想知道如何在JSON中存储javascript日期。您可以只将日期传递给该JSON.stringify方法,方法将Date.prototype.toJSON默认使用,而方法又使用Date.prototype.toISOStringDate.toJSON上的MDN):

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.parse上的MDNreviver参数可以在每次读取JSON字符串时自动将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...

我相信实现通用互操作性的最佳格式不是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字符串,如果这就是他们的应用理解,但是对于一种普遍接受的传输格式,该格式应保证某些值可以肯定是日期,我们如何允许歧义和需要进行大量验证?

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

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

JSON日期

因此,如您所见,Date具有本机方法toJSON,该方法return采用这种格式,可以轻松地Date再次转换为...

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

yourDate.substring(0,10)

这可能对您有帮助

“ 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); // 2014年1月1日星期三13:28:56 GMT- 1000(夏威夷标准时间)

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

如果您使用的是Kotlin,则可以解决您的问题。(MS Json格式)

val dataString = "/Date(1586583441106)/"
val date = Date(Long.parseLong(dataString.substring(6, dataString.length - 2)))

它对我来说解析服务器工作

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

只有一个正确的答案,大多数系统都会弄错。自纪元以来的毫秒数,又称64位整数。时区是一个与UI有关的问题,在应用程序层或数据库层中没有事务。为什么您的数据库为什么要关心某个时区,当您知道它将以64位整数形式存储时,然后进行转换计算。

去除多余的位,仅将日期视为直到UI的数字。您可以使用简单的算术运算符进行查询和逻辑。

以下代码对我有用。该代码将以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);

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

{
"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)
  • 支持全天日期和浮动时间(JavaScript Date.toJSON()不支持)

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

本文地址:http://javascript.askforanswer.com/shenmeshizhengquede-jsonriqigeshi.html
文章标签: ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!