对于JSON日期格式,我看到了很多不同的标准:
1 2 3 4
| ""\\/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中没有日期格式,只有字符串由反/序列化程序决定映射到日期值。
- strings、numbers、true、false、null、objects和arrays。
- 然而,Javascript内置的JSON对象和ISO8601包含了人类和计算机需要理解的所有信息,并且不依赖于计算机时代的开始(1970-1-1)。
- 也许这应该改为要求最好的约定,因为这里的答案忽略了这个问题。
- 您所称的"javascript内置JSON对象"也符合ISO8601标准。标准允许指定秒的小数部分和两种描述时区的方法。参见W3C的注释。
- 它们是相同日期值的不同格式
- @Poussma,问题中的值不是从计算机时代开始的,微软将其定义为从2001年1月1日午夜开始的100纳秒间隔。
JSON本身并没有指定日期应该如何表示,但JavaScript会这样做。
您应该使用Date的toJSON方法发出的格式:
2012-04-23T18:25:43.511Z
这就是为什么:
它既可读又简洁
它排序正确
它包括分数秒,可以帮助重新建立年表。
符合ISO 8601
ISO 8601已在国际上建立了十多年。
ISO 8601由W3C、RFC339和XKCD批准。
也就是说,所有的日期库都能理解"1970年以来的毫秒数"。因此,为了便于携带,Thiefmaster是正确的。
- 这也是ECMA:JSON.stringify({'now': new Date()})"{"now":"2013-10-21T13:28:06.419Z"}"的首选陈述。
- 我会在列表中添加另一个重要的原因:它是独立于区域设置的。如果你的日期是2014年3月2日,你需要更多的信息来知道它是指2月3日还是3月2日。这取决于使用的是美国格式还是其他格式。
- 考虑到一些浏览器不解析ISO8601,例如Safari。
- 提到和链接xkcd:d@ajorquera我通常使用momentjs。在这方面我也看到过IE的问题
- 我想一个更好的方法是增加时间补偿。很简单的原因是,您确切地知道从您的位置创建事件的日期,可能是事件,但您不知道事件发生的日期。如果碰巧你不知道这个事件是在哪里发生的,那么你就不能从事件中获得足够的关于它产生的位置的信息。
- 关于第二点,10000年后排序不正确。不过,我们确实有近8000年的时间来提出一种新的格式,所以这可能不是一个问题。
- Sebastian在日期问题上是正确的,但是使用仅限日期的ISO格式更简单(您可以在XKCD条带中看到)。在任何情况下,两者都必须替换JavaScript的标准JSON序列化。
- 将日期序列化为JSON时,"它排序正确"是如何相关的?
- tojson()不支持全天日期、浮动时间和时区。
- 自1970年以来,秒数的问题在于它不包括时区。你不应该用那个。曾经。没有时区的日期总是本地化的,请注意!
- 不幸的是,JSON.parse()不会复制日期对象,而是将其保留为字符串:JSON.parse(JSON.stringify({'now': new Date()}))给出{now:"2016-03-30T15:49:18.369Z"}。
- 事实上,@erfa,由于-在ASCII中的位数之前,到10万年它会很好的排序。P
- 关于ISO8601,最棒的是它包含了如此多的格式可供选择!
- @Gerard van Helden与您的语句相反,UNIX时间戳定义得很好,并且始终是UTC。
- @marten-排序是相关的,因为当日期表示为ISO字符串时,词汇排序和时间排序会折叠到相同的操作。节省CPU并简化代码,因为普通的旧.sort()默认使用词汇排序。
- @LKraider这并不总是真的。Unix时间戳不包含任何有关时区的信息,因此在获取时间戳之前将日期转换为UTC是一种很好的做法,但并不总是遵守。我们不应该依赖编程语言来进行这种转换。
- "是"dineirockenbach UNIX时间数秒,因为有elapsed 00:00:00协调世界时(UTC),星期四,1970年1月,闰秒不计数",所以它不匹配,否则在UTC闰秒,但它永远是UTC。现在是完全不同的表示之间的转换,在你去的权利。
- 你让我在"endorsed red xkcd":)
- 谢谢你提的xkdc代言。制造我的日子!
- xkcd推ISO 8601格式(它是特别有趣的是,ISO 8601悬停提示说是发表在06/05/88和最最近修改12/01/04在一个混乱的亮点。
- 手术的问题是关于约会,在约会和时间的需要。知识只是没有时间约会的最好方法?例如,birth_date?
- 有没有任何特别的偏好使用UTC(又名Z)为时区?或是±hh:mm湖泊作为等效?有人认为这是可以实现的Z将使用?
- 可以请你在点(包括3名分数秒,它可以帮助重新建立chronology)?
- "martinthoma秒的分数允许恢复的命令是相同的事件发生在第二。没有人的分数秒,它到底是什么是一阶。
- 如果你需要解析的字符串在另一个语言,你可以使用:"%Y-%m-%dT%H:%M:%S.%fZ"
JSON对日期一无所知。NET所做的是一个非标准的黑客/扩展。
我将使用一种可以在javascript中轻松转换为Date对象的格式,即可以传递给new Date(...)的格式。最简单而且可能也是最可移植的格式是自1970年以来包含毫秒的时间戳。
- javascript内置的json.stringify格式是最被接受的格式吗?为什么?!为什么没有任何标准?但是,当字符串化日期对象时,所有浏览器的行为都相同?!
- 啊,我想会有个错误…但至少火狐会把它串起来…好吧,它不是JSON标准的一部分,所以我不会将日期对象提供给JSON序列化程序——它可能不适用于所有浏览器。显然,对于JSON序列化程序来说,如果它存在于未知对象上,那么使用toJSON()函数是一个常见的想法。至少火狐会为日期对象这样做,日期对象也有这样的方法。
- stackoverflow.com/questions/10286385/…-让我们看看是否有人知道FF的行为为何如此。
- 如果你走这条路,确保你不需要处理早于1970年的日期!
- 有些应用程序/库支持负时间戳。
- 正如@bendolman所说,这个"解决方案"不能恰当地处理1970年1月1日(epoch)之前的日期。此外,还有一个原因是ISO8601首先存在。在地球上,我们有一个叫做"时区"的东西,它以毫秒为单位在哪里?JSON可能没有日期标准,但是日期存在于JSON之外,并且有一个标准。Funroll的答案是正确的(另请参见:xkcd.com/1179)。
- 这不是一个.NET黑客,当时没有人试图定义日期格式标准。当Microsoft创建Ajax时,他们必须传递日期,以便尝试使用转义和标记的Unix时间戳(与您提到的其他库一样),这样就不会与文本或整数混淆。这在.NET中不再使用,每个人都使用json.net或其他支持ISO格式的序列化程序。
- 也许还值得一提的是,从1970年开始的(毫秒)时间对于未来的日期来说是不可预测的,因为我们有闰秒。所以我不会使用if进行进程间通信和数据存储。但是,在程序内部使用它是很好的,因为它可以存储在单个整数中,这会给您带来一些性能优势。
- 时间戳最大的问题是它们不包括时区。这可能很麻烦。(尽管大多数库都假定使用UTC,但并非所有库都这样做,这使得它非常混乱)。因此,日期表示应始终包括时区,而简单的uint表示则不能。
- Unix时间戳始终是UTC,您在生成时间戳之前从本地时区转换,然后在显示时再次返回到本地时区,这里没有歧义。
- 这些评论中的每一条都说,70年代前的日期或未来的日期是无法表示的,这是对时代的误解。所有时间都是相对的,一旦你达到/低于第1年,日期字符串就会真正崩溃。不管你时间的源时钟是什么,它几乎可以肯定是基于纪元时间的表示,所以你不能通过避免纪元时间使它更精确。
- @JoshFromQaribou ISO 8601在零年级及以下有代表性。一般来说,尽管任何低于1583的代码都很可能破坏大多数解析器。所以你基本上是对的,在那个时代,恐惧是毫无根据的。
- 看看电话的答案(short link stackoverflow.com/a/42480073/4102223)。从1970年开始的时间戳对于服务/系统之间的交换不是可靠的时间格式。
没有正确的格式;JSON规范没有指定用于交换日期的格式,这就是为什么有这么多不同的方法可以做到这一点的原因。
最好的格式可以说是以ISO 8601格式表示的日期(参见维基百科);它是一种众所周知且广泛使用的格式,可以跨多种语言处理,使其非常适合互操作性。例如,如果您可以控制生成的JSON,那么您可以以JSON格式向其他系统提供数据,选择8601作为日期交换格式是一个不错的选择。
例如,如果您没有对生成的JSON的控制权,那么您是来自多个不同现有系统的JSON的使用者,处理这一问题的最佳方法是使用日期分析实用程序函数来处理预期的不同格式。
- @姆利斯纳,但这是关于哪一个最好的观点。ISO-8601是一个标准,但它不是JSON的标准(尽管我倾向于使用它);例如,微软决定不使用它(msdn.microsoft.com/en-us/library/…)。最好的做法是坚持一个(合理的)惯例,不管它是什么。正如我在答案中所说,处理这个问题的最佳方法是定义一个日期解析实用程序函数,该函数可以处理预期的格式。如果您与使用不同格式的系统集成,那么函数应该处理每种情况。
- @Russcam,我们可以来来回回,但是如果有人问用JSON编码日期的最佳方法,他们会问如何在生成JSON时格式化日期(答案通常是ISO-8601)。您回答的是相反的问题:如何在JSON日期被创建之后使用它们(尽管您的建议是合理的)。
- JSON模式规范实际上指出,由模式验证的日期必须是8601格式。
- @你有链接吗?
- @vallismortis——这是为双方交换的给定JSON结构定义模式的规范草案,而不是JSON规范中日期的格式。我要根据评论来修改我的答案,似乎我说得不够清楚。
来自RFC7493(i-json消息格式):
i-json代表Internet JSON或互操作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.
- 所以这是一个由Date().toISOString()格式和Date().toJSON(),酒店是不限制的轨道Date时区值A和发射的时间戳,因此总是在UTC(Z)时区。的价值和Date.parseDateparsed new Date("...")可以使用。
仅供参考,我已经看到使用的格式:
它与由$.getJSON()函数支持的jsonp一起工作。不确定我会推荐这种方法…把它扔出去是有可能的,因为人们是这样做的。
fwiw:不要在通信协议中使用从epoch开始的秒数,也不要使用从epoch开始的毫秒数,因为这些都充满了危险,这要归功于闰秒的随机实现(您不知道发送方和接收方是否都正确地实现了UTC闰秒)。
有点讨厌,但很多人认为UTC只是格林尼治标准时间的新名字——错了!如果您的系统没有实现闰秒,那么您使用的是格林威治标准时间(尽管不正确,但通常称为UTC)。如果您完全实现闰秒,那么您实际上使用的是UTC。无法知道未来的闰秒;它们将根据需要由IER发布,需要不断更新。如果您运行的系统试图实现闰秒,但包含和过期的引用表(比您想象的更常见),那么您既没有GMT,也没有UTC,那么您有一个不稳定的系统,假装是UTC。
这些日期计数器仅在以分解格式(Y、M、D等)表示时才兼容。它们从来都不兼容的时代格式。记住这一点。
- 我不会使用这种格式,但您提供的其他信息非常有用,谢谢!
我认为,实现通用互操作性的最佳格式不是ISO-8601字符串,而是EJSON使用的格式:
{"myDateField": {"$date" : } }
如本文所述:https://docs.meteor.com/api/ejson.html
效益
解析性能:如果您将日期存储为iso-8601字符串,那么如果您希望在该特定字段下有一个日期值,那么这是非常好的,但是如果您有一个系统,它必须在没有上下文的情况下确定值类型,那么您将解析日期格式的每个字符串。
不需要日期验证:您不必担心日期的验证和验证。即使一个字符串符合ISO-8601格式,它也可能不是一个真实的日期;这在ejson日期中是不可能发生的。
明确的类型声明:就通用数据系统而言,如果您希望在一种情况下将ISO字符串存储为字符串,而在另一种情况下将真实的系统日期存储为字符串,那么采用ISO-8601字符串格式的通用系统将不会机械地允许这样做(没有转义技巧或类似的糟糕解决方案)。
结论
我理解人类可读格式(iso-8601字符串)对80%的用例是有用的,而且更为方便,事实上,如果他们的应用程序理解这一点,任何人都不应该被告知不要将其日期存储为iso-8601字符串,而对于一种普遍接受的传输格式,它应该确保某些值确实是日期,我们如何才能允许模棱两可和需要如此多的验证?
首选的方法是使用2018-04-23T18:25:43.511Z…
下图显示了这是首选方式的原因:
如你所见,日期有一个本地方法toJSON,return采用这种格式,可以很容易地再次转换成Date…
- 对的!JSON数据交换语法没有指定标准:ecma international.org/publications/files/ecma-st/ecma-404.p‌&8203;df,但实际上,在包括javascript运行时在内的平台上,ISO 8601兼容格式更为可取。
在SharePoint 2013中,获取JSON中的数据没有将日期转换为仅日期格式的格式,因为在该日期中应该是ISO格式。
1
| yourDate.substring(0,10) |
这可能对你有帮助
它对我和Parse Server一起工作
1 2 3 4 5 6 7 8 9 10
| {
"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"
}
} |
对此只有一个正确答案,大多数系统都会出错。自epoch以来的毫秒数,也称为64位整数。时区是一个用户界面问题,在应用层或数据库层没有业务。为什么你的数据库关心什么是时区,当你知道它将存储为64位整数时,那么做转换计算。
去掉多余的部分,把日期当作用户界面上的数字。您可以使用简单的算术运算符进行查询和逻辑。
- 评论已经搬到了聊天。
- 现在你有2个问题:你选择的时代",这是你milliseconds计数?可能的选择是最普通的Unix时间(1970年1 01t00:00:00 UTC和Si milliseconds除了那些在一个跨越第二的情况下),但当然让未定义未来的时代。
- 那么你如何microseconds代表?rfc3339精细任何精密的作品,你会有一个阅读器和一个parses给你正确的时区的时间邮票,它的额外的信息。日历应用程序通常关心的时区。
- 我喜欢使用milliseconds从Unix时代,直到我的交易记录系统,这是一个不使用milliseconds从Unix时代在复活节的时间!这是不是一个有趣的调试。至少有一个时间戳你的选择描述数据集的样本点由指定的时间带。
- 用户界面是不是一个时区,除非你不记下失踪的飞行。航班是张贴在本地时间和后续的DST规则变化的特异性。失去的失去重要的业务信息的均值偏移
- 一些进一步的counterarguments包含代表的能力(如果那是在1970年的时代,时代的趋势和jsons)在人类可读。
- 原因:错误的答案是downvote和你自己挖一个大洞,如果你尝试和实现自己的计划和时间/日期转换器从零开始。你一定要疯狂一把的时候,看上去稳定轮库存在的约会时间。
以下代码对我有效。此代码将以dd-mm-yyyy格式打印日期。
1
| DateValue=DateValue.substring(6,8)+"-"+DateValue.substring(4,6)+"-"+DateValue.substring(0,4); |
否则,您还可以使用:
1
| DateValue=DateValue.substring(0,4)+"-"+DateValue.substring(4,6)+"-"+DateValue.substring(6,8); |
我认为这真的取决于用例。在许多情况下,使用适当的对象模型(而不是将日期呈现为字符串)可能更有益,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| {
"person" :
{
"name" : {
"first":"Tom",
"middle":"M",
...
}
"dob" : {
"year": 2012,
"month": 4,
"day": 23,
"hour": 18,
"minute": 25,
"second": 43,
"timeZone":"America/New_York"
}
}
} |
诚然,这比RFC3339更详细,但:
- 它也是人类可读的
- 它实现了一个适当的对象模型(在OOP中,只要JSON允许)
- 它支持时区(不只是给定日期和时间的UTC偏移量)
- 它可以支持更小的单位,如毫秒、纳秒……或者只是分数秒
- 它不需要单独的解析步骤(要解析日期-时间字符串),JSON解析器将为您做任何事情。
- 使用任何日期时间框架或任何语言实现轻松创建
- 可以很容易地扩展到支持其他日历尺度(希伯来语、汉语、伊斯兰教…)和纪元(公元前、公元前…)
- 现在是10000年安全期;-)(RFC3339没有)
- 支持全天日期和浮动时间(javascript的Date.toJSON()不支持)
我不认为正确的排序(如RFC3339的Funroll所指出的)是将日期序列化到JSON时真正需要的功能。同样,只有日期时间具有相同时区偏移量时才是这样。
- 据使用JSON的人将在这一年10000,或甚至是一年的时间想安静的10000 10000年。但如果那些东西都是真的那么安静,简单的扩展格式CAN包含组件A 3位数的世纪。所以我说,人民可以在RFC 3339 CAN驱动器,至少直到今年9900
- "downvoters根据投票:为什么重要?你应该downvote if a post contains wrong information, is poorly researched, or fails to communicate information。请为这一个理由解释你的答案downvoted本。
- @马丁有两件事。1。尽管我知道这是有帮助的,但你从来没有被要求对落选作出解释。2。我没有否定你的答案,但我想人们不喜欢你的答案,因为他们认为这样做是错误的。因为这个问题是在寻找做某件事的最佳方式,所以这将被称为"错误信息"。
- 我没有对你投反对票,但我可以肯定地理解,"发明另一种糟糕的指定格式"(基本上就是你所说的格式)是如何被视为错误或研究不足的。
- 不是一个好的选择,因为这不是标准的交换格式。
- 回答太差。我认为这是一个糟糕的选择,因为不使用或执行标准
- 正如其他人指出的,JSON中没有日期标准。只有RFC3339,它实际上是时间戳格式,而不是日期格式。特别是,它不包括时区,但对未来日期很重要。时区的变化比你想象的要频繁。
- @marten它覆盖了时区-"z"表示时区是UTC。我也会投反对票,但现在没有必要了。
- @菲尔,UTC不是真正的时区(地球上没有一个地方使用"UTC"作为它的正式时区),它是一个时间标准。同时,时区偏移也是不可预测的。如果2025年莫斯科时间"12:00"仍像今天一样是"9:00 UTC",那么在过去30年中,它已经改变了几次。如果你想表达一个未来的本地时间,你需要真正的时区。
- 我可以说:你很顽强!以-15分的(当前)分数发布答案,已获得23次落选!(我没有投反对票,顺便说一句)
- @马汀,我编辑了你,并给你投了赞成票。我明白为什么你所做的会有用。
- 很好地理解为什么存储UTC时间戳并不总是最佳选择:codeblog.jonsket.uk/2019/03/27/…