158

目标:找到local timeUTC time offset构造以下格式的 URL。

示例网址:/Actions/Sleep?duration=2002-10-10T12:00:00−05:00

格式基于W3C 推荐。文档说:

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

所以根据我的理解,我需要找到我的当地时间,new Date()然后使用getTimezoneOffset()函数来计算差异,然后将它附加到字符串的末尾。

  1. 获取当地时间format

    var local = new Date().format("yyyy-MM-ddThh:mm:ss"); // 2013-07-02T09:00:00
    
  2. 按小时获取 UTC 时间偏移量

    var offset = local.getTimezoneOffset() / 60; // 7
    
  3. 构建 URL(仅限时间部分)

    var duration = local + "-" + offset + ":00"; // 2013-07-02T09:00:00-7:00
    

上面的输出意味着我的当地时间是 2013/07/02 上午 9 点,与 UTC 的差异是 7 小时(UTC 比当地时间早 7 小时)

到目前为止,它似乎有效,但如果getTimezoneOffset()返回负值(如 -120)呢?

我想知道在这种情况下格式应该是什么样子,因为我无法从 W3C 文档中弄清楚。

4

12 回答 12

258

这是一个简单的帮助函数,它将为您格式化 JS 日期。

function toIsoString(date) {
  var tzo = -date.getTimezoneOffset(),
      dif = tzo >= 0 ? '+' : '-',
      pad = function(num) {
          return (num < 10 ? '0' : '') + num;
      };

  return date.getFullYear() +
      '-' + pad(date.getMonth() + 1) +
      '-' + pad(date.getDate()) +
      'T' + pad(date.getHours()) +
      ':' + pad(date.getMinutes()) +
      ':' + pad(date.getSeconds()) +
      dif + pad(Math.floor(Math.abs(tzo) / 60)) +
      ':' + pad(Math.abs(tzo) % 60);
}

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

于 2013-07-02T00:35:10.413 回答
76

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

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

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

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

如果您正在寻找可以直接使用这种格式的库,我建议您尝试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

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

于 2013-07-02T00:58:46.053 回答
33

我认为值得考虑的是,您只需对标准库进行一次 API 调用即可获取请求的信息......

new Date().toLocaleString( 'sv', { timeZoneName: 'short' } );

// produces "2019-10-30 15:33:47 GMT−4"

如果要添加“T”分隔符、删除“GMT-”或将“:00”附加到末尾,则必须进行文本交换。

但是,如果您愿意,您可以轻松地使用其他选项。使用 12 小时时间或省略秒等。

请注意,我使用瑞典作为语言环境,因为它是使用 ISO 8601 格式的国家之一。我认为大多数 ISO 国家都使用这种“GMT-4”格式作为时区偏移量,而不是使用时区缩写的加拿大,例如。“EDT”表示东部夏令时间。

您可以从较新的标准 i18n 函数“Intl.DateTimeFormat()”中获得相同的结果,但您必须通过选项告诉它包含时间,否则它只会给出日期。

于 2019-10-30T21:06:10.380 回答
18

对于那些只想在当地时区以 YYYY-MM-DD 格式显示今天日期的人,我的回答是略有不同。

让我说清楚:

我的目标:用户的时区中获取今天的日期,但格式为 ISO8601 (YYYY-MM-DD)

这是代码:

new Date().toLocaleDateString("sv") // "2020-02-23" // 

这是因为瑞典语言环境使用 ISO 8601 格式。

于 2020-02-24T01:22:19.970 回答
7

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

  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;
  }
于 2018-05-25T22:08:13.803 回答
6

检查这个:

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 ? '-' : '+') + 
            Math.floor(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'
于 2019-06-21T19:13:39.273 回答
3

只有我的两分钱在这里

我在日期时间方面遇到了这个问题,所以我所做的是:

const moment = require('moment-timezone')

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

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


安装moment-timezone

npm i moment-timezone
于 2019-02-21T23:48:01.623 回答
2

不需要moment.js:这是一个完整的往返答案,从“datetime-local”的输入类型输出一个ISOLocal字符串到格林威治标准时间的UTC秒并返回:

<input type="datetime-local" value="2020-02-16T19:30">

isoLocal="2020-02-16T19:30"
utcSeconds=new Date(isoLocal).getTime()/1000

//here you have 1581899400 for utcSeconds

let isoLocal=new Date(utcSeconds*1000-new Date().getTimezoneOffset()*60000).toISOString().substring(0,16)
2020-02-16T19:30
于 2020-01-15T03:49:42.667 回答
2

您可以通过一些简单的扩展方法来实现这一点。以下日期扩展方法仅返回 ISO 格式的时区组件,然后您可以为日期/时间部分定义另一个并将它们组合为完整的日期时间偏移字符串。

Date.prototype.getISOTimezoneOffset = function () {
    const offset = this.getTimezoneOffset();
    return (offset < 0 ? "+" : "-") + Math.floor(Math.abs(offset / 60)).leftPad(2) + ":" + (Math.abs(offset % 60)).leftPad(2);
}

Date.prototype.toISOLocaleString = function () {
    return this.getFullYear() + "-" + (this.getMonth() + 1).leftPad(2) + "-" +
        this.getDate().leftPad(2) + "T" + this.getHours().leftPad(2) + ":" +
        this.getMinutes().leftPad(2) + ":" + this.getSeconds().leftPad(2) + "." +
        this.getMilliseconds().leftPad(3);
}

Number.prototype.leftPad = function (size) {
    var s = String(this);
    while (s.length < (size || 2)) {
        s = "0" + s;
    }
    return s;
}

示例用法:

var date = new Date();
console.log(date.toISOLocaleString() + date.getISOTimezoneOffset());
// Prints "2020-08-05T16:15:46.525+10:00"

我知道现在是 2020 年,现在大多数人可能都在使用 Moment.js,但有时仍然可以使用简单的复制和粘贴解决方案。

(我拆分日期/时间和偏移方法的原因是因为我使用的是旧的Datejs库,它已经提供了一个toString带有自定义格式说明符的灵活方法,但不包括时区偏移量。因此,我toISOLocaleString为没有的人添加了说图书馆。)

于 2020-08-05T06:38:21.267 回答
1

只使用没有库的 javascript 实际上只有两行:

var dt = new Date();
// Date in UTC and ISO format: "2021-11-30T20:33:32.222Z"
console.log(dt.toISOString());
var dtOffset = new Date(dt.setMinutes(dt.getMinutes() - dt.getTimezoneOffset()));
// Date in EST and ISO format: "2021-11-30T15:33:32.222Z"
console.log(dtOffset.toISOString());

new Date()将默认为当前语言环境,但如果需要,您也可以直接指定它:

var dt = new Date(new Date().toLocaleString("en-US", {timeZone: "America/New_York"}));

于 2021-11-30T20:37:48.960 回答
1

以下是我为此目的使用的功能:

function localToGMTStingTime(localTime = null) {
    var date = localTime ? new Date(localTime) : new Date();
    return new Date(date.getTime() + (date.getTimezoneOffset() * 60000)).toISOString();
};

function GMTToLocalStingTime(GMTTime = null) {
    var date = GMTTime ? new Date(GMTTime) : new Date();;
    return new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString();
};
于 2020-07-22T13:59:44.263 回答
0
function setDate(){
    var now = new Date();
    now.setMinutes(now.getMinutes() - now.getTimezoneOffset());
    var timeToSet = now.toISOString().slice(0,16);

    /*
        If you have an element called "eventDate" like the following:

        <input type="datetime-local" name="eventdate" id="eventdate" />

        and you would like to  set the current and minimum time then use the following:
    */

    var elem = document.getElementById("eventDate");
    elem.value = timeToSet;
    elem.min = timeToSet;
}
于 2020-10-26T07:03:34.887 回答