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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17415579/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 08:14:32  来源:igfitidea点击:

How to ISO 8601 format a Date with Timezone Offset in JavaScript?

javascripttimezonedate-formatting

提问by Meow

Goal:Find the local timeand UTC time offsetthen construct the URL in following format.

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

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

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

The format is based on the W3C recommendation: http://www.w3.org/TR/xmlschema11-2/#dateTime

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

The documentation says:

文档说:

For example, 2002-10-10T12:00:00?05:00 (noon on 10 October 2002, Central Daylight Savings Time as well as Eastern Standard Time in the U.S.) is equal to 2002-10-10T17:00:00Z, five hours later than 2002-10-10T12:00:00Z.

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

So based on my understanding, I need to find my local time by new Date() then use getTimezoneOffset() function to compute the difference then attach it to the end of string.

因此,根据我的理解,我需要通过 new Date() 找到我的本地时间,然后使用 getTimezoneOffset() 函数计算差异,然后将其附加到字符串的末尾。

1.Get local time with format

1.获取本地时间格式

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

output

输出

2013-07-02T09:00:00

2.Get UTC time offset by hour

2.按小时获取UTC时间偏移量

var offset = local.getTimezoneOffset() / 60;

output

输出

7

3.Construct URL (time part only)

3.构造URL(仅时间部分)

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

output:

输出:

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

The above output means my local time is 2013/07/02 9am and difference from UTC is 7 hours (UTC is 7 hours ahead of local time)

以上输出表示我的本地时间是 2013/07/02 9am,与 UTC 的时差为 7 小时(UTC 比当地时间提前 7 小时)

So far it seems to work but what if getTimezoneOffset() returns negative value like -120?

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

I'm wondering how the format should look like in such case because I cannot figure out from W3C document. Thanks in advance.

我想知道在这种情况下格式应该如何,因为我无法从 W3C 文档中弄清楚。提前致谢。

回答by Steven Moseley

The below should work properly, and for all browsers (thanks to @MattJohnson for the tip)

以下应该可以正常工作,并且适用于所有浏览器(感谢@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());

回答by Matt Johnson-Pint

getTimezoneOffset()returns the opposite sign of the format required by the spec that you referenced.

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

This format is also known as ISO8601, or more precisely as RFC3339.

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

In this format, UTC is represented with a Zwhile all other formats are represented by an offset from UTC. The meaning is the same as JavaScript's, but the order of subtraction is inverted, so the result carries the opposite sign.

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

Also, there is no method on the native Dateobject called format, so your function in #1 will fail unless you are using a library to achieve this. Refer to this documentation.

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

If you are seeking a library that can work with this format directly, I recommend trying moment.js. In fact, this is the default format, so you can simply do this:

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

This is a well-tested, cross-browser solution, and has many other useful features.

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

回答by Tom

I think it is worth considering that you can get the requested info with just a single API call to the standard library...

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

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

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

You would have to do text swapping if you want to add the 'T' delimiter, remove the 'GMT-', or append the ':00' to the end.

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

But then you can easily play with the other optionsif you want to eg. use 12h time or omit the seconds etc.

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

Note that I'm using Sweden as locale because it is one of the countries that uses ISO 8601 format. I think most of the ISO countries use this 'GMT-4' format for the timezone offset other then Canada which uses the time zone abbreviation eg. "EDT" for eastern-daylight-time.

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

You can get the same thing from the newer standard i18n function "Intl.DateTimeFormat()" but you have to tell it to include the time via the options or it will just give date.

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

回答by Bbb

This is my function for the clients timezone, it's lite weight and simple

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

  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;
  }

回答by Nahuel Greco

Check this:

检查这个:

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'

回答by Captain Fantastic

No moment.js needed: Here's a full round trip answer, from an inputtype of "datetime-local" which outputs an ISOLocal string to UTCseconds at GMT and back:

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

<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

回答by Jonathan Steele

My answer is a slight variation for those who just want today's date in the local timezone in the YYYY-MM-DD format.

对于那些只想要本地时区中 YYYY-MM-DD 格式的今天日期的人,我的回答是略有不同。

Let me be clear:

让我说清楚:

My Goal:get today's datein the user's timezonebut formatted as ISO8601 (YYYY-MM-DD)

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

Here is the code:

这是代码:

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

This works because the Sweden locale uses the ISO 8601 format.

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

回答by Arnold Gandarillas

Just my two sends here

只是我的两个发送到这里

I was facing this issue with datetimes so what I did is this:

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

const moment = require('moment-timezone')

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

Then save date to db to be able to compare it from some query.

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



To install moment-timezone

安装 moment-timezone

npm i moment-timezone