Javascript:如何从UTC字符串和偏移量解析日期?

时间:2018-02-27 03:03:40

标签: javascript date typescript momentjs

方案

我有一个字符串格式的UTC日期和一个以分钟为单位的相关偏移号:

  • 日期:“2017-10-01T12:00:00.000Z”
  • 抵消:360

用户的浏览器处于Mountain Standard Time(-7)时区。日期值是从中央标准时间(-6)时区记录的,并与其偏移量一起保存(因此偏移量为360分钟)。可以假设偏移量不包括夏令时。

问题

如何使用记录时区的偏移量解析UTC日期?换句话说,尽管用户的浏览器是MST,我仍然希望将字符串中的日期显示为“2017-10-01 6:00 AM”。不需要显示时区。这是否可以使用时间 - 时区而不具有时区名称并且只是具有不包括DST的偏移量?

2 个答案:

答案 0 :(得分:2)

我猜时间戳“2017-10-01T12:00:00.000Z”是正确的,360的偏移真的是-360(因为你说它应该是美国中央标准时间-0600)。 / p>

  

可以假设偏移量不包括夏令时。

偏移从不考虑夏令时,它们是绝对值。夏令时会更改时区内某个区域的偏移量,通常也会通过更改时区名称(例如,中央标准时间到中央夏令时)来反映。

无论如何,如果原始值始终为UTC并且您希望在原始时区中显示它,则可以将原始UTC日期解析为日期,调整UTC时间值,然后使用toISOString(这是始终为UTC)并附加适当的偏移指示符。你还必须翻转偏移的符号。

以下功能可以避免内置解析器,不要试图使用它:

// Offset has opposite sign: 360 == -0600
var data = {date: "2017-10-01T12:00:00.000Z",
            offset: 360};
            
/* Return a timestamp adjusted for offset
** @param {object} data - object with the following properties 
**                          date: ISO 8601 format date and time string with Z offset
**                          offset: offset in minutes +ve west, -ve east
** @returns {string} ISO 8601 timestamp in zone
*/
function formatDate(data) {

  // Pad single digits with leading zero
  function pad(n){return (n<10? '0' : '') + n}

  // Format offset: 360 => -0600
  function formatOffset(offset) {
    var sign = offset < 0? '+' : '-'; // Note sign flip
    offset = Math.abs(offset);
    return sign + pad(offset/60|0) + pad(offset%60);
  }

  // Parse ISO 8601 date and time string, assume UTC and valid, ms may be missing
  function parseISO(s) {
    var b = s.split(/\D/);
    return new Date(Date.UTC(b[0],--b[1],b[2],b[3],b[4],b[5],b[6]|0));
  }

  var d = parseISO(data.date);
  var offset = data.offset;
  d.setUTCMinutes(d.getUTCMinutes() - offset);
  return d.toISOString().replace(/z$/i, formatOffset(offset));
}

console.log(formatDate(data));

答案 1 :(得分:1)

这就是你需要的吗?

const moment = require('moment');
moment
  .utc('2013-06-20T07:00:00.427')
  .zone(-360)
  .format();

在这里,您会找到很多显示选项 - &gt; http://momentjs.com/docs/#/displaying/

或者只是:

const date = new Date('2017-10-01T12:00:00.000Z');
date.setMinutes(-360);
date.toISOString();