Javascript “正确”的 JSON 日期格式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10286204/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 00:41:40  来源:igfitidea点击:

The "right" JSON date format

javascriptjson

提问by Kamyar Nazeri

I've seen so many different standards for the JSON date format:

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

Which one is the right one? Or best? Is there any sort of standard on this?

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

回答by funroll

JSONitself does notspecify how dates should be represented, but JavaScript does.

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

You shoulduse the format emitted by Date's toJSONmethod:

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

2012-04-23T18:25:43.511Z

2012-04-23T18:25:43.511Z

Here's why:

原因如下:

  1. It's human readable but also succinct

  2. It sorts correctly

  3. It includes fractional seconds, which can help re-establish chronology

  4. It conforms to ISO 8601

  5. ISO 8601 has been well-established internationally for more than a decade

  6. ISO 8601 is endorsed by W3C, RFC3339, and XKCD

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

  2. 它排序正确

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

  4. 它符合ISO 8601

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

  6. ISO 8601 得到W3CRFC3339XKCD 的认可

That being said, every date library ever written can understand "milliseconds since 1970". So for easy portability, ThiefMasteris right.

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

回答by ThiefMaster

JSON does not know anything about dates. What .NET does is a non-standard hack/extension.

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

I would use a format that can be easily converted to a Dateobject in JavaScript, i.e. one that can be passed to new Date(...). The easiest and probably most portable format is the timestamp containing milliseconds since 1970.

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

回答by Russ Cam

There is no right format; The JSON specificationdoes not specify a format for exchanging dates which is why there are so many different ways to do it.

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

The best format is arguably a date represented in ISO 8601 format(see Wikipedia); it is a well known and widely used format and can be handled across many different languages, making it very well suited for interoperability. If you have control over the generated json, for example, you provide data to other systems in json format, choosing 8601 as the date interchange format is a good choice.

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

If you do not have control over the generated json, for example, you are the consumer of json from several different existing systems, the best way of handling this is to have a date parsing utility function to handle the different formats expected.

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

回答by Bryan Larsen

From RFC 7493 (The I-JSON Message Format ):

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

I-JSON stands for either Internet JSON or Interoperable JSON, depending on who you ask.

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

Protocols often contain data items that are designed to contain timestamps or time durations. It is RECOMMENDED that all such data items be expressed as string values in ISO 8601 format, as specified in RFC 3339, with the additional restrictions that uppercase rather than lowercase letters be used, that the timezone be included not defaulted, and that optional trailing seconds be included even when their value is "00". It is also RECOMMENDED that all data items containing time durations conform to the "duration" production in Appendix A of RFC 3339, with the same additional restrictions.

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

回答by Tel

Just for reference I've seen this format used:

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

Date.UTC(2017,2,22)

It works with JSONPwhich is supported by the $.getJSON()function. Not sure I would go so far as to recommend this approach... just throwing it out there as a possibility because people are doing it this way.

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

FWIW:Never use seconds since epoch in a communication protocol, nor milliseconds since epoch, because these are fraught with danger thanks to the randomized implementation of leap seconds (you have no idea whether sender and receiver both properly implement UTC leap seconds).

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

Kind of a pet hate, but many people believe that UTC is just the new name for GMT -- wrong! If your system does not implement leap seconds then you are using GMT (often called UTC despite being incorrect). If you do fully implement leap seconds you really are using UTC. Future leap seconds cannot be known; they get published by the IERS as necessary and require constant updates. If you are running a system that attempts to implement leap seconds but contains and out-of-date reference table (more common than you might think) then you have neither GMT, nor UTC, you have a wonky system pretending to be UTC.

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

These date counters are only compatible when expressed in a broken down format (y, m, d, etc). They are NEVER compatible in an epoch format. Keep that in mind.

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

回答by Shayan Ahmad

When in doubt simply go to the javascript web console of a modern browser by pressing F12 (Ctrl+K in Firefox) and write the following:

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

new Date().toISOString()

Will output:

将输出:

"2019-07-04T13:33:03.969Z"

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

Ta-da!!

达达!!

回答by Ciabaros

I believe that the best format for universal interoperabilityis not the ISO-8601 string, but rather the format used by EJSON:

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

{ "myDateField": { "$date" : <ms-since-epoch> } }

{ "myDateField": { "$date" : <ms-since-epoch> } }

As described here: https://docs.meteor.com/api/ejson.html

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

Benefits

好处

  1. Parsing performance:If you store dates as ISO-8601 strings, this is great if you are expecting a date value under that particular field, but if you have a system which must determine value types without context, you're parsing every string for a date format.
  2. No Need for Date Validation:You need not worry about validation and verification of the date. Even if a string matches ISO-8601 format, it may not be a real date; this can never happen with an EJSON date.
  3. Unambiguous Type Declaration:as far as generic data systems go, if you wanted to store an ISO string as a stringin one case, and a real system datein another, generic systems adopting the ISO-8601 string format will not allow this, mechanically (without escape tricks or similar awful solutions).
  1. 解析性能:如果您将日期存储为 ISO-8601 字符串,那么如果您希望在该特定字段下有一个日期值,这很好,但是如果您的系统必须在没有上下文的情况下确定值类型,那么您正在解析每个字符串以获得一个日期格式。
  2. 无需日期验证:您无需担心日期的验证和验证。即使字符串匹配 ISO-8601 格式,它也可能不是真实的日期;EJSON 日期永远不会发生这种情况。
  3. 明确的类型声明:就通用数据系统而言,如果您想在一种情况下将 ISO 字符串存储为字符串,而在另一种情况下存储真实系统日期,则采用 ISO-8601 字符串格式的通用系统机械地不允许这样做(没有逃避技巧或类似的可怕解决方案)。

Conclusion

结论

I understand that a human-readable format (ISO-8601 string) is helpful and more convenientfor 80% of use cases, and indeed no-one should ever be told notto store their dates as ISO-8601 strings if that's what their applications understand, butfor a universally accepted transport format which should guarantee certain values to for surebe dates, how can we allow for ambiguity and need for so much validation?

我知道人类可读的格式(ISO-8601 字符串)对 80% 的用例很有帮助,也更方便,而且确实没有人应该被告知不要将他们的日期存储为 ISO-8601 字符串,如果那是他们的应用程序理解,但是对于应该保证某些值肯定是日期的普遍接受的传输格式,我们怎么能允许歧义和需要如此多的验证?

回答by Justus Romijn

JSON itself has no date format, it does not care how anyone stores dates. However, since this question is tagged with javascript, I assume you want to know how to store javascript dates in JSON. You can just pass in a date to the JSON.stringifymethod, and it will use Date.prototype.toJSONby default, which in turns uses Date.prototype.toISOString(MDN on Date.toJSON):

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

I also found it useful to use the reviverparameter of JSON.parse(MDN on JSON.parse) to automatically convert ISO strings back to javascript dates whenever I read JSON strings.

我还发现,每当我读取 JSON 字符串时,使用(JSON.parse 上的 MDN)的reviver参数将 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...

回答by Alireza

The prefered way is using 2018-04-23T18:25:43.511Z...

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

The picture below shows why this is the prefered way:

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

JSON Date

JSON 日期

So as you see Date has a native Method toJSON, which returnin this format and can be easily converted to Dateagain...

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

回答by raghava arr

In Sharepoint 2013, getting data in JSON there is no format to convert date into date only format, because in that date should be in ISO format

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

yourDate.substring(0,10)

This may be helpful for you

这可能对你有帮助