【问题标题】:Extract time from JS Date object without offsetting the Time zone从 JS Date 对象中提取时间而不偏移时区
【发布时间】:2017-11-15 20:01:15
【问题描述】:

所以我们有多个客户,它们位于多个时区。我正在从 API 中提取一些日期,而这个字符串中的日期/时间正是我需要显示的。我一直在研究这个,并且挖掘了一段时间,但仍然没有想出一个明确的答案。传入的字符串格式如下:

"2017-12-29T20:00:00"

我想要的是将日期和时间按原样提取到两个字符串中(没有时区偏移,无论查看器位于何处),但是这样做有一些问题。也希望以正确的方式格式化它。示例:

"M/d/yyyy"
"hh:mm AM/PM" (12 hour)

我已经尝试了很多方法来解决这个问题,并且真的不想只抓取子字符串,但我有一半想这样做。任何帮助表示赞赏。

【问题讨论】:

  • 你考虑过使用momentjs吗? moment.format() 将使这成为一项简单的任务。否则,我宁愿获取子字符串,也不愿尝试使用内置的 javascript getHour、getMinute 等函数来构建它。
  • @cstricklan - 如果我把它放到 moment.format() 中,它会自动偏移任何时区吗?还是会保留字符串中提供的时间/日期?
  • 字符串"2017-12-29T20:00:00" 不包含时区信息。是的,调用 moment("2017-12-29T20:00:00") 会在本地时区创建 20:00 的时刻对象,但这也是 format() 函数用来创建字符串的时区,所以它会保持在晚上 10:00。
  • 旧建议仍然适用:永远不要使用内置日期解析器来解析字符串。编写自己的函数或使用库,有很多好的解析和格式化库可用(例如moment.jsfecha.js)。只需将字符串视为 UTC 并使用 UTC 方法进行所有格式化以避免任何时区问题。或者,只需重新格式化字符串并完全避免解析问题。
  • 始终使用 UTC 方法。

标签: javascript date iso8601


【解决方案1】:

考虑重新格式化字符串,它可以避免内置解析器和时区的所有问题:

function reformatTimestamp(s) {
  function z(n){return (n<10?'0':'')+ +n}
  var b = s.split(/\D/);
  var h = b[3]%12 || 12;
  var ap = b[3] < 12? 'AM':'PM';
  return b[1] + '/' + b[2] + '/' + b[0] +
         ' ' + z(h) + ':' + z(b[4]) + ' ' + ap;
}

console.log(reformatTimestamp('2017-12-29T20:00:00')) // 12/29/2017 08:00 PM

我认为用前导零填充月份和日期会更好(但我也会使用明确的日期格式,如 DD-MMM-YYYY,而不是特殊的 m/d/y)。

【讨论】:

    【解决方案2】:

    使用此代码:

    function formatAMPM(date) {
      var hours = date.getUTCHours();
      var minutes = date.getUTCMinutes();
      var ampm = hours >= 12 ? 'PM' : 'AM';
      hours = hours % 12;
      hours = hours ? hours : 12; // the hour '0' should be '12'
      minutes = minutes < 10 ? '0'+minutes : minutes;
      var strTime = hours + ':' + minutes + ' ' + ampm;
      return strTime;
    }
    
    var str = "2017-12-29T20:00:00";
    var dt = new Date(str + "Z");
    console.log("M/d/yyyy");
    console.log((dt.getUTCMonth() + 1) + '/' + dt.getUTCDate() + '/' +  dt.getUTCFullYear());
    console.log("hh:mm AM/PM");
    console.log(formatAMPM(dt));

    【讨论】:

    • @RobG 是的,你是对的。我已经相应地删除了 options1 行:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-14
    • 2016-04-22
    • 1970-01-01
    • 2014-10-25
    • 2020-08-18
    • 2020-01-23
    • 1970-01-01
    相关资源
    最近更新 更多