如何在JavaScript中使用ISO 8601格式化带有时区偏移的日期?

问题描述 投票:78回答:5

目标:找到local timeUTC time offset,然后按以下格式构建URL。

示例URL:/ Actions / Sleep?duration = 2002-10-10T12:00:00-05:00

格式基于W3C建议:http://www.w3.org/TR/xmlschema11-2/#dateTime

文件说:

例如,2002-10-10T12:00:00-05:00(2002年10月10日中午,中央夏令时以及美国东部标准时间)等于2002-10-10T17:00:00Z,比2002-10-10T12:00:00Z晚5个小时。

所以基于我的理解,我需要通过新的Date()找到我的本地时间,然后使用getTimezoneOffset()函数来计算差异,然后将它附加到字符串的末尾。

1.以格式获取当地时间

var local = new Date().format("yyyy-MM-ddThh:mm:ss"); //today (local time)

产量

2013-07-02T09:00:00

2.以小时为单位获取UTC时间偏移量

var offset = local.getTimezoneOffset() / 60;

产量

7

3.Construct URL(仅限时间部分)

var duration = local + "-" + offset + ":00";

输出:

2013-07-02T09:00:00-7:00

以上输出结果表示我的当地时间是2013/07/02 9am,与UTC的差异是7小时(UTC是比当地时间早7小时)

到目前为止它似乎工作,但如果getTimezoneOffset()返回负值如-120怎么办?

我想知道在这种情况下格式应该是什么样的,因为我无法从W3C文档中找到答案。提前致谢。

javascript timezone
5个回答
149
投票

以下应该适用于所有浏览器(感谢@MattJohnson提示)

Date.prototype.toIsoString = function() {
    var tzo = -this.getTimezoneOffset(),
        dif = tzo >= 0 ? '+' : '-',
        pad = function(num) {
            var norm = Math.floor(Math.abs(num));
            return (norm < 10 ? '0' : '') + norm;
        };
    return this.getFullYear() +
        '-' + pad(this.getMonth() + 1) +
        '-' + pad(this.getDate()) +
        'T' + pad(this.getHours()) +
        ':' + pad(this.getMinutes()) +
        ':' + pad(this.getSeconds()) +
        dif + pad(tzo / 60) +
        ':' + pad(tzo % 60);
}

var dt = new Date();
console.log(dt.toIsoString());

62
投票

getTimezoneOffset()返回您引用的规范所需格式的相反符号。

这种格式也称为ISO8601,或者更准确地称为RFC3339

在这种格式中,UTC用Z表示,而所有其他格式用UTC的偏移量表示。含义与JavaScript相同,但减法的顺序是反转的,因此结果带有相反的符号。

此外,在本机Date对象上没有名为format的方法,因此除非您使用库来实现此功能,否则#1中的函数将失败。请参阅this documentation

如果您正在寻找可以直接使用此格式的库,我建议您尝试使用moment.js。实际上,这是默认格式,因此您可以简单地执行此操作:

var m = moment();    // get "now" as a moment
var s = m.format();  // the ISO format is the default so no parameters are needed

// sample output:   2013-07-01T17:55:13-07:00

这是一个经过良好测试的跨浏览器解决方案,并具有许多其他有用的功能。


2
投票

这是我对客户时区的功能,它重量轻,简单

  function getCurrentDateTimeMySql() {        
      var tzoffset = (new Date()).getTimezoneOffset() * 60000; //offset in milliseconds
      var localISOTime = (new Date(Date.now() - tzoffset)).toISOString().slice(0, 19).replace('T', ' ');
      var mySqlDT = localISOTime;
      return mySqlDT;
  }

0
投票

只是我的两个发送到这里

我在日期时遇到了这个问题所以我做的是这样的:

const moment = require('moment-timezone')

const date = moment.tz('America/Bogota').format()

然后将日期保存到db,以便能够从某个查询中进行比较。


安装moment-timezone

npm i moment-timezone

0
投票

检查一下:

function dateToLocalISO(date) {
    const off    = date.getTimezoneOffset()
    const absoff = Math.abs(off)
    return (new Date(date.getTime() - off*60*1000).toISOString().substr(0,23) +
            (off > 0 ? '-' : '+') + 
            (absoff / 60).toFixed(0).padStart(2,'0') + ':' + 
            (absoff % 60).toString().padStart(2,'0'))
}

// Test it:
d = new Date()

dateToLocalISO(d)
// ==> '2019-06-21T16:07:22.181-03:00'

// Is similar to:

moment = require('moment')
moment(d).format('YYYY-MM-DDTHH:mm:ss.SSSZ') 
// ==> '2019-06-21T16:07:22.181-03:00'
© www.soinside.com 2019 - 2024. All rights reserved.