“正确”的JSON日期格式

时间:2012-04-23 18:32:32

标签: javascript json

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

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

16 个答案:

答案 0 :(得分:1602)

JSON本身指定应如何表示日期,但JavaScript会这样做。

应该使用DatetoJSON方法发布的格式:

2012-04-23T18:25:43.511Z

原因如下:

  1. 这是人类可读但也简洁

  2. 正确排序

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

  4. 符合ISO 8601

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

  6. ISO 8601由W3CRFC3339XKCD

  7. 认可

    这就是说,每个日期库都可以理解“自1970年以来的毫秒”。因此,为了便于移植,ThiefMaster是正确的。

答案 1 :(得分:113)

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

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

答案 2 :(得分:36)

没有正确的格式; JSON specification 未指定用于交换日期的格式,这就是为什么有这么多不同的方法。

最佳格式可以说是ISO 8601 format see Wikipedia)中代表的日期;它是一种众所周知且广泛使用的格式,可以跨多种语言处理,非常适合互操作性。例如,如果您可以控制生成的json,则以json格式向其他系统提供数据,选择8601作为日期交换格式是一个不错的选择。

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

答案 3 :(得分:24)

来自RFC 7493 (The I-JSON Message Format )

I-JSON代表互联网JSON或互操作JSON,具体取决于您的要求。

  

协议通常包含旨在包含的数据项   时间戳或持续时间。推荐所有这些数据   项目按照ISO 8601格式表示为字符串值,如指定的那样   在RFC 3339中,附加限制大写相反   如果使用小写字母,则不包括时区   默认情况下,甚至在包含可选的尾随秒数时也包括在内   他们的价值是“00”。还推荐所有数据项   包含持续时间符合“持续时间”生产的   RFC 3339的附录A,具有相同的附加限制。

答案 4 :(得分:12)

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

Date.UTC(2017,2,22)

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

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

有点宠爱,但很多人认为UTC只是GMT的新名称 - 错了!如果您的系统没有实现闰秒,那么您使用GMT(尽管不正确,通常称为UTC)。如果您完全实现闰秒,那么您确实使用的是UTC。未来的闰秒无法知晓;它们在必要时由IERS发布,需要不断更新。如果您正在运行一个试图实现闰秒但包含和过时的引用表(比您想象的更常见)的系统,那么您既没有GMT也没有UTC,您有一个假想的UTC系统。 / p>

这些日期计数器仅在以细分格式(y,m,d等)表示时才兼容。它们永远不会兼容时代格式。记住这一点。

答案 5 :(得分:4)

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

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

我还发现使用reviverMDN on Date.toJSON)的JSON.parse参数来在每次读取JSON字符串时将ISO字符串自动转换回javascript日期很有用。

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...

答案 6 :(得分:2)

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

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

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

好处

  1. 解析性能::如果您将日期存储为ISO-8601字符串,那么,如果您希望该特定字段下的日期值有效,但是如果您有一个必须确定值类型而又不包含该值的系统,那么这很好上下文中,您正在为日期格式解析每个字符串。
  2. 无需日期验证:您无需担心日期的验证和验证。即使字符串与ISO-8601格式匹配,也可能不是真实日期; EJSON日期永远不会发生。
  3. 明确类型声明:就通用数据系统而言,如果您想将ISO字符串存储为字符串(在一种情况下)和 real系统日期,在另一种采用ISO-8601字符串格式的通用系统中,从机械上不允许这样做(没有转义或类似的糟糕解决方案)。

结论

我了解人类可读的格式(ISO-8601字符串)在80%的用例中是有用的,并且方便,实际上,任何人都不应被告知 not < / em>将日期存储为ISO-8601字符串(如果应用程序可以理解的话),是一种通用的传输格式,该格式应保证某些值确定为 ,我们如何允许模棱两可和需要进行大量验证?

答案 7 :(得分:1)

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

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

JSON Date

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

答案 8 :(得分:1)

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

new Date().toISOString()

将输出:

  

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

Ta-da !!

答案 9 :(得分:0)

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

yourDate.substring(0,10)

这可能对你有所帮助

答案 10 :(得分:0)

“ 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)。

NB:

    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

答案 11 :(得分:0)

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

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

答案 12 :(得分:-4)

只有一个正确答案,大多数系统都错了。自纪元以来的毫秒数,也就是64位整数。时区是UI关注的问题,在应用层或数据库层中没有业务。为什么你的数据库关心什么时区,当你知道它将它存储为64位整数然后进行转换计算。

删除多余的位,只需将日期视为数字直至UI。您可以使用简单的算术运算符来执行查询和逻辑。

答案 13 :(得分:-4)

使用解析服务器

对我有用
{
    "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"
            }
}

答案 14 :(得分:-5)

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

答案 15 :(得分:-14)

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

{
"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时真正需要的功能。此外,对于具有相同时区偏移的日期时间也是如此。