提问人:Kamyar Nazeri 提问时间:4/24/2012 最后编辑:leonheessKamyar Nazeri 更新时间:8/18/2023 访问量:1848485
什么是“正确”的 JSON 日期格式?
What is the "right" 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
哪一个是正确的?还是最好的?这有什么标准吗?
答:
JSON 对日期一无所知。.NET 所做的是非标准的黑客/扩展。
我会使用一种可以很容易地转换为 JavaScript 中对象的格式,即可以传递给新 Date(...)
的格式。最简单、可能最便携的格式是自 1970 年以来包含毫秒的时间戳。Date
评论
没有正确的格式;JSON规范没有指定交换日期的格式,这就是为什么有这么多不同的方法可以做到这一点。
最好的格式可以说是以 ISO 8601 格式表示的日期(参见维基百科);它是一种众所周知且广泛使用的格式,可以跨多种不同的语言进行处理,因此非常适合互操作性。如果您可以控制生成的 json,例如,以 json 格式向其他系统提供数据,则选择 8601 作为日期交换格式是一个不错的选择。
如果您无法控制生成的 json,例如,您是来自多个不同现有系统的 json 的使用者,则处理此问题的最佳方法是使用日期解析实用程序函数来处理预期的不同格式。
评论
JSON 本身没有指定日期应该如何表示,但 JavaScript 指定了。
2012-04-23T18:25:43.511Z
原因如下:
它是人类可读的,但也简洁明了
它正确排序
它包括小数秒,可以帮助重新建立年表
它符合 ISO 8601
ISO 8601 在国际上已经建立了十多年
话虽如此,每个曾经编写过的日期库都可以理解“自 1970 年以来的毫秒”。因此,为了便于携带,ThiefMaster 是对的。
评论
JSON.stringify({'now': new Date()}) "{"now":"2013-10-21T13:28:06.419Z"}"
-
ASCII
I-JSON 代表 Internet JSON 或可互操作的 JSON,具体取决于您询问的人。
协议通常包含旨在包含的数据项 时间戳或持续时间。建议所有此类数据 项目以 ISO 8601 格式表示为字符串值,如指定 在 RFC 3339 中,具有大写的附加限制 比使用小写字母,则不包括时区 默认值,并且即使 它们的值为“00”。还建议所有数据项 包含的持续时间符合 RFC 3339 的附录 A,具有相同的附加限制。
评论
Date().toISOString()
Date().toJSON()
Date
Z
new Date("...")
Date.parseDate
这个问题只有一个正确答案,大多数系统都错了。自纪元以来的毫秒数,又名 64 位整数。时区是一个 UI 问题,在应用程序层或数据库层中没有业务。为什么你的数据库关心某物是什么时区,当你知道它会将其存储为 64 位整数时,然后进行转换计算。
去掉多余的部分,只将日期视为数字,直到 UI。您可以使用简单的算术运算符来执行查询和逻辑。
评论
我认为这实际上取决于用例。在许多情况下,使用适当的对象模型(而不是将日期呈现为字符串)可能更有益,如下所示:
{
"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 解析器将为您完成所有操作
- 使用任何日期时间框架或任何语言的实现轻松创建
- 可以很容易地扩展以支持其他日历刻度(希伯来语、汉语、伊斯兰教等)和时代(公元、公元前等)
- 这是 10000 年安全 ;-)(RFC 3339 不是)
- 支持全天日期和浮动时间(Javascript 不支持)
Date.toJSON()
我不认为正确的排序(如 RFC 3339 的 funroll 所指出的那样)是将日期序列化为 JSON 时真正需要的功能。此外,这仅适用于具有相同时区偏移量的日期时间。
评论
在 Sharepoint 2013 中,以 JSON 格式获取数据时,没有将日期转换为仅日期格式的格式,因为该日期应采用 ISO 格式
yourDate.substring(0,10)
这可能对您有所帮助
仅供参考,我已经看到使用了这种格式:
Date.UTC(2017,2,22)
它与函数支持的 JSONP 一起使用。不确定我是否会推荐这种方法......只是把它作为一种可能性扔在那里,因为人们正在这样做。$.getJSON()
FWIW:切勿在通信协议中使用自纪元以来的秒数,也不要使用自纪元以来的毫秒数,因为由于闰秒的随机实现,这些都充满了危险(您不知道发送方和接收方是否都正确实现了UTC闰秒)。
有点讨厌宠物,但很多人认为UTC只是GMT的新名称 - 错误!如果您的系统没有实现闰秒,那么您使用的是 GMT(尽管不正确,但通常称为 UTC)。如果你完全实现了闰秒,你就真的在用UTC。未来的闰秒无法得知;它们由IERS在必要时发布,并需要不断更新。如果你正在运行一个试图实现闰秒的系统,但包含和过时的参考表(比你想象的更常见),那么你既没有GMT,也没有UTC,你有一个假装是UTC的不稳定系统。
这些日期计数器仅在以分解格式(y、m、d 等)表示时才兼容。它们从来都不兼容纪元格式。请记住这一点。
评论
它对我有用 parse Server
{
"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"
}
}
以下代码对我有用。此代码将以 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-23T18:25:43.511Z
下图显示了为什么这是首选方式:
所以正如你所看到的 Date 有一个 原生方法 ,它以这种格式,可以很容易地再次转换为......toJSON
return
Date
评论
我认为通用互操作性的最佳格式不是 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本身没有日期格式,它不关心任何人如何存储日期。但是,由于这个问题被标记为 javascript,我假设您想知道如何在 JSON 中存储 javascript 日期。你可以只将一个日期传递给该方法,它将默认使用,而该方法又使用(Date.toJSON 上的 MDN):JSON.stringify
Date.prototype.toJSON
Date.prototype.toISOString
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 上的 MDN) 参数自动将 ISO 字符串转换回 javascript 日期很有用。reviver
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...
如有疑问,只需按 (Firefox 中的 ++) 进入现代浏览器的 javascript Web 控制台,然后编写以下内容:F12CtrlShiftK
new Date().toISOString()
将输出:
“2019-07-04T13:33:03.969Z”
哒哒!!
评论
toISOString
“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
JSON 中没有正式的日期格式。但最好的解决方案是使用 ISO 8601 格式,将日期描述为字符串,例如 ."2023-08-17T08:20:28.438Z"
评论
strings
和numbers
true
false
null
objects
arrays
date