【问题标题】:String to Date conversion in JavaScriptJavaScript 中的字符串到日期转换
【发布时间】:2016-07-14 20:29:51
【问题描述】:

我的服务将其返回为日期7/14/2016 2:40 AM +00:00。如何在 JS 中将其转换为 UTC?

试过了:

new Date("7/14/2016 2:40 AM +00:00").toISOString();

在数据库中,日期已存储为 UTC,所以当我将日期显示为本地时间时。

【问题讨论】:

  • 你想多了……
  • 你之前试过momentjs吗?
  • @AlonEitan 为什么每个人都在每个 js 日期问题中提到这一点?添加一个重量为 12+kb 的复杂库来解析日期字符串有点多。
  • @JaredSmith 仅仅因为它有助于更​​轻松地处理日期方面,以及当您拥有充满图像和其他视觉效果的网站时,12+kb gzip 压缩的内容(如果您使用的是缩小版,可能会更少)
  • @JaredSmith 我完全同意 - 这基本上取决于您需要多久处理一次日期以及该任务的复杂程度。我认为它就像jQuery(或者可能是 angularjs 和其他类似的框架) - 您将使用它来进行复杂的 DOM 操作,但是当您只需要 document.getElementById() 时,您不必使用它

标签: javascript json date datetime utc


【解决方案1】:

有很多方法可以解析字符串以生成Date 对象。

  • 一种方法是使用Date 对象本身,或者将字符串传递给构造函数,或者使用Date.parse。但是,ECMAScript 规范中只需要 ISO8601 格式。任何其他输入都是特定于实现的,并且可能会或可能不会被不同的 JavaScript 运行时识别。特别是对于网络浏览器,不同浏览器支持的格式存在许多差异。

    此外,环境的语言环境在值的解析方式中起着重要作用。 1/2/2016 应该如何解析? 1月2日还是2月1日?您展示了一个7/14/2016 的示例,如果在英国运行(例如),这将是无效输入,其中日期格式为DD/MM/YYYY

  • 您可以编写自定义代码将字符串拆分为多个部分,单独解析每个部分,然后组合结果。这种方法的主要问题是代码往往是僵硬的,有时是脆弱的。它应该经过很好的测试,并且需要考虑许多边缘情况。

  • 您可以使用库,这是迄今为止最简单、最灵活的方法 (恕我直言)。有了一个好的库,您可以在其他人的共享经验以及单元测试中感到欣慰,这些单元测试(希望)是您选择的库的一部分。当然,使用库会带来一些权衡,包括增加文件大小和放弃某种程度的控制。您应该仔细评估这些权衡。

    有许多可用于 JavaScript 的日期库。最受欢迎的可能是 moment.js,尽管还有其他可供选择,并且一些较大的框架有时已经包含类似的功能。

    这是一个使用 moment.js 的示例:

    var i = "7/14/2016 2:40 AM +00:00";
    var f = "M/D/YYYY h:mm A Z";
    var m = moment(i, f);
    var o = m.format(f); // will be in the local time, in the same format as the input
    var d = m.toDate();  // if you really want a Date object
    

【讨论】:

    【解决方案2】:

    假设您可以保证所有日期的格式,以下代码就足够了:

    const datetime = '7/14/2016 2:40 PM +00:00'; // this is what your service returns
    const pieces = datetime.split(/[/: ]/);
    
    if (pieces[3] == 12) pieces[3] = 0; // fixes edge case for 12 AM/PM
    
    const hours = pieces[5] === 'PM' ? Number(pieces[3]) + 12 : pieces[3];
    const d = new Date(Date.UTC(pieces[2], pieces[0] - 1, pieces[1], hours, pieces[4]));
    
    console.log(datetime); // prints "7/14/2016 2:40 PM +00:00"
    console.log(d); // prints Date 2016-07-14T14:40:00.000Z
    

    编辑:有几个边缘情况没有正确处理,即上午 12 点/下午等,但也可以轻松解决。

    EDIT2:考虑了这种极端情况。

    EDIT3:正如评论所述,这仅适用于 UTC 时间。如果您收到的字符串可以有任何偏移量,这将不起作用。

    【讨论】:

    • 这不考虑除+00:00之外的任何偏移量。
    • 上午/下午 12 点几乎不是“边缘”案例。在均匀分布的随机样本中,大约 8% 的时间会发生这种情况。
    • 如果你真的想争论我对边缘情况的定义,那就去吧(:我已经编辑了答案来解释它,所以现在有点没有意义......
    • @MattJohnson,是的,我假设 OP 正在接收 UTC 字符串,因为示例是。如果时间可以有任何偏移,我的答案将不起作用。我添加了一个说明,以便人们知道他们是否阅读了我的答案,它仅适用于 UTC。
    • @michel 我尝试用 UTC 替换,然后将其转换为新日期,它在 IE 中也适用于我。尝试了您提供的解决方案,但这会在 IE 中引发错误。
    【解决方案3】:
    var str = "7\/15\/2016 1:00 AM +00:00".replace("+00:00","UTC");
    console.log(new Date(str).toISOString()); // 2016-07-15T01:00:00.000Z
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-27
      • 2011-06-13
      • 2016-05-03
      相关资源
      最近更新 更多