JavaScript에서 시간대 오프셋으로 날짜를 ISO 8601 형식으로 지정하는 방법은 무엇입니까?


100

목표 : 찾기 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 시간 늦습니다.

따라서 내 이해를 바탕으로 new 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. URL 구성 (시간 부분 만 해당)

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

산출:

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

위 출력은 내 현지 시간이 2013/07/02 9am이고 UTC와의 차이가 7 시간임을 의미합니다 (UTC는 현지 시간보다 7 시간 빠름).

지금까지 작동하는 것처럼 보이지만 getTimezoneOffset ()이 -120과 같은 음수 값을 반환하면 어떻게 될까요?

나는 W3C 문서에서 알아낼 수 없기 때문에 이러한 경우 형식이 어떻게 생겼는지 궁금합니다. 미리 감사드립니다.

답변:


174

아래는 모든 브라우저에서 제대로 작동해야합니다 (팁은 @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());


2
기호는 GMT에서 현지 시간의 오프셋을 나타냅니다
Steven Moseley

1
@ 마사토 산 당신은 정의를 참조 부호를 반전해야 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...을
bfavaretto

2
여기서 pad 함수는 밀리 초를 제외하고 날짜의 각 섹션에 대해 적절한 문자열을 반환합니다. 예를 들어, 입력으로 5ms 동안 05를 반환합니다. 이는 005로 간주됩니다. 다음은 동일한 함수의 최소 수정 버전이있는 링크입니다. jsbin
Safique Ahmed Faruque

9
참고 :이 답변에는 미묘한 버그가 있습니다. 프랑스 및 캐나다의 특정 위치와 같이 시간대에 오프셋 분이 있고 음수 (예 : -09 : 30) 인 경우 시간대 오프셋이 올바르게 계산되지 않습니다. Mod는 음수를 반환하므로 abs () 전에 floor ()를 수행하면 실수로 오프셋이 MORE 음수로 변경됩니다. 이 버그를 수정하려면 abs () 및 THEN floor (). 답변을 편집하려고했지만 "이 편집은 게시물 작성자를 다루기위한 것이며 편집으로 의미가 없습니다".
tytk

5
@tytk-그레이트 캐치! 그것은 참으로 미묘합니다. 답변에 수정 사항을 추가했습니다. 댓글 주셔서 감사합니다!
Steven Moseley

67

getTimezoneOffset() 참조한 사양에 필요한 형식의 반대 부호를 반환합니다.

이 형식은 ISO8601 또는보다 정확하게는 RFC3339 라고도 합니다.

이 형식에서 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

이것은 잘 테스트 된 브라우저 간 솔루션이며 다른 많은 유용한 기능이 있습니다.


toISOString () 사용은 작동하지 않습니다. +01 : 00 형식을 사용하려면 시간 부분이 현지 시간이어야합니다. toISOString ()은 UTC 시간 문자열을 제공합니다.
Austin France

1
@AustinFrance-당신이 맞아요! 나는이 점에서 다른 사람들을 자주 수정하기 때문에 그 당시에 그 실수를 저질렀다는 것에 놀랐습니다. 2 년 전에 댓글을 보지 못해서 죄송합니다! 답변이 수정되었습니다.
Matt Johnson-Pint 2015 년

9

표준 라이브러리에 대한 단일 API 호출만으로 요청 된 정보를 얻을 수 있다는 점을 고려할 가치가 있다고 생각합니다.

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

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

'T'구분 기호를 추가하거나 'GMT-'를 제거하거나 끝에 ': 00'을 추가하려면 텍스트 교체를 수행해야합니다.

그러나 원하는 경우 다른 옵션을 쉽게 사용할 수 있습니다 . 12h 시간을 사용하거나 초를 생략하십시오.

스웨덴은 ISO 8601 형식을 사용하는 국가 중 하나이기 때문에 로케일로 스웨덴을 사용하고 있습니다. 나는 대부분의 ISO 국가가 시간대 약어를 사용하는 캐나다 이외의 시간대 오프셋 에이 'GMT-4'형식을 사용한다고 생각합니다. 동부 일광 절약 시간의 경우 "EDT".

새로운 표준 i18n 함수 "Intl.DateTimeFormat ()"에서 동일한 것을 얻을 수 있지만 옵션을 통해 시간을 포함하도록 지정해야합니다. 그렇지 않으면 날짜 만 제공됩니다.


1
sv의 경우 실제로 "CET"가 표시되고 서머 타임 날짜 인 "CEST"가 표시됩니다.하지만 입력 덕분에 표준 API로 충분합니다 (로그 메시지에 날짜를 접두사로 지정해야 함). 시간과 시간대에 대해 진지하게 알고 싶다면 순간 라이브러리를
찾아 보겠습니다

4

이것은 클라이언트 시간대에 대한 내 기능이며 가볍고 간단합니다.

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

@tsh, 확실합니까? 나중에 현지 시간을 시뮬레이션하는 데 사용되는 현재 시간 오프셋을 얻고 있습니다. 아마도 그 시점에서 오프셋이 달랐을 수도 있지만, 지금은 관심이 있기 때문에 중요하지 않습니다.
Andrew

2

이것을 확인하십시오 :

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'

1

moment.js가 필요하지 않습니다. 여기 에 ISOLocal 문자열을 GMT에서 UTCseconds로 출력하는 "datetime-local" 입력 유형 에서 전체 왕복 답변이 있습니다 .

<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

0

내 두 사람 만 여기로 보내

나는 datetimes와 함께이 문제에 직면했기 때문에 내가 한 일은 다음과 같습니다.

const moment = require('moment-timezone')

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

그런 다음 일부 쿼리에서 비교할 수 있도록 날짜를 db에 저장하십시오.


설치하기 위해서 moment-timezone

npm i moment-timezone

0

내 대답은 YYYY-MM-DD 형식의 현지 시간대로 오늘 날짜를 원하는 사람들을위한 약간의 변형입니다.

명확히하겠습니다.

내 목표는 : 얻을 오늘 날짜 에서 사용자의 시간대를 하지만, ISO8601의 형식 (YYYY-MM-DD)

다음은 코드입니다.

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

이것은 스웨덴 로케일이 ISO 8601 형식을 사용하기 때문에 작동합니다.


잘못된 대답, 이것은 대답이지만 다른 질문 ...이 대답은 쉽게 찾을 수 있습니다.
PsychoX

0

이를 위해 내가 사용한 기능은 다음과 같습니다.

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

0

몇 가지 간단한 확장 방법으로이를 달성 할 수 있습니다. 다음 날짜 확장 메서드는 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없이 누군가를 위해 말했다.)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.