关于javascript:正确的JSON日期格式

The “right” JSON date format

对于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本身并没有指定日期应该如何表示,但JavaScript会这样做。

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

2012-04-23T18:25:43.511Z

这就是为什么:

  • 它既可读又简洁

  • 它排序正确

  • 它包括分数秒,可以帮助重新建立年表。

  • 符合ISO 8601

  • ISO 8601已在国际上建立了十多年。

  • ISO 8601由W3C、RFC339和XKCD批准。

  • 也就是说,所有的日期库都能理解"1970年以来的毫秒数"。因此,为了便于携带,Thiefmaster是正确的。


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

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


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

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

    例如,如果您没有对生成的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.


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

    1
    Date.UTC(2017,2,22)

    它与由$.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

    下图显示了这是首选方式的原因:

    JSON Date

    如你所见,日期有一个本地方法toJSONreturn采用这种格式,可以很容易地再次转换成Date


    在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位整数时,那么做转换计算。

    去掉多余的部分,把日期当作用户界面上的数字。您可以使用简单的算术运算符进行查询和逻辑。


    以下代码对我有效。此代码将以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时真正需要的功能。同样,只有日期时间具有相同时区偏移量时才是这样。