JavaScript로 ISO 8601 형식의 문자열을 어떻게 출력합니까?


247

나는이 Date개체를. 다음 스 니펫 title일부를 어떻게 렌더링 합니까?

<abbr title="2010-04-02T14:12:07">A couple days ago</abbr>

다른 도서관의 "상대 시간"부분이 있습니다.

나는 다음을 시도했다.

function isoDate(msSinceEpoch) {

   var d = new Date(msSinceEpoch);
   return d.getUTCFullYear() + '-' + (d.getUTCMonth() + 1) + '-' + d.getUTCDate() + 'T' +
          d.getUTCHours() + ':' + d.getUTCMinutes() + ':' + d.getUTCSeconds();

}

그러나 그것은 나에게 준다 :

"2010-4-2T3:19"

답변:


453

이미 다음과 같은 함수가 있습니다 toISOString().

var date = new Date();
date.toISOString(); //"2011-12-19T15:28:46.493Z"

어쨌든, 당신이 그것을 지원하지 않는 브라우저 에 있다면, 나는 당신을 덮었습니다.

if ( !Date.prototype.toISOString ) {
  ( function() {

    function pad(number) {
      var r = String(number);
      if ( r.length === 1 ) {
        r = '0' + r;
      }
      return r;
    }

    Date.prototype.toISOString = function() {
      return this.getUTCFullYear()
        + '-' + pad( this.getUTCMonth() + 1 )
        + '-' + pad( this.getUTCDate() )
        + 'T' + pad( this.getUTCHours() )
        + ':' + pad( this.getUTCMinutes() )
        + ':' + pad( this.getUTCSeconds() )
        + '.' + String( (this.getUTCMilliseconds()/1000).toFixed(3) ).slice( 2, 5 )
        + 'Z';
    };

  }() );
}

1
.toISOString ()은 확실히 날짜를 UTC로 반환합니까?
Jon Wells

new Date("xx").toISOString()생산 NaN-NaN-NaNTNaN:NaN:NaN.NZ네이티브 구현을 RangeException가 발생합니다.
Joseph Lennox

데이트 서비스를 비누 서비스에 전달하려면 ... 그렇습니다! :) 감사.
thinklinux

1
OP에서 제공 한 샘플에는 밀리 초 또는 시간대가 없습니다.
Dan Dascalescu

"getUTCFullYear"와 같은 모든 함수 호출은 IE 문서 모드 5에 알려지지 않았기 때문에 실패합니다.
Elaskanator

63

https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference:Global_Objects:Date 페이지의 마지막 예를 참조 하십시오 .

/* Use a function for the exact format desired... */
function ISODateString(d) {
    function pad(n) {return n<10 ? '0'+n : n}
    return d.getUTCFullYear()+'-'
         + pad(d.getUTCMonth()+1)+'-'
         + pad(d.getUTCDate())+'T'
         + pad(d.getUTCHours())+':'
         + pad(d.getUTCMinutes())+':'
         + pad(d.getUTCSeconds())+'Z'
}

var d = new Date();
console.log(ISODateString(d)); // Prints something like 2009-09-28T19:03:12Z

1
OP ( <abbr title="2010-04-02T14:12:07">) 에서 제공 한 샘플 에는 시간대가 없습니다. 아마도 그들은 현지 시간을 원했을 것입니다 .UI 시간 문자열에 적합합니까?
Dan Dascalescu

60

웹에서 거의 모든 toISO 방법은 문자열을 출력하기 전에 "Z"ulu 시간 (UTC)으로 변환을 적용하여 시간대 정보를 삭제합니다. 브라우저의 기본 .toISOString ()도 시간대 정보를 삭제합니다.

서버 또는 수신자가 항상 전체 ISO 날짜를 Zulu 시간 또는 필요한 시간대로 변환 할 수 있기 때문에 발신자의 시간대 정보를 계속 얻을 수 있으므로 중요한 정보는 삭제됩니다.

내가 찾은 가장 좋은 해결책은 Moment.js 자바 스크립트 라이브러리를 사용하고 다음 코드를 사용하는 것입니다.

시간대 정보 및 밀리 초로 현재 ISO 시간을 얻으려면

now = moment().format("YYYY-MM-DDTHH:mm:ss.SSSZZ")
// "2013-03-08T20:11:11.234+0100"

now = moment().utc().format("YYYY-MM-DDTHH:mm:ss.SSSZZ")
// "2013-03-08T19:11:11.234+0000"

now = moment().utc().format("YYYY-MM-DDTHH:mm:ss") + "Z"
// "2013-03-08T19:11:11Z" <- better use the native .toISOString() 

표준 시간대 정보는 있지만 밀리 초가없는 기본 JavaScript Date 객체의 ISO 시간을 가져 오려면

var current_time = Date.now();
moment(current_time).format("YYYY-MM-DDTHH:mm:ssZZ")

이것은 Date.js와 결합하여 Date.today ()와 같은 함수를 가져 와서 결과를 순간적으로 전달할 수 있습니다.

이와 같은 형식의 날짜 문자열은 JSON 컴파일러이며 데이터베이스에 저장하기에 적합합니다. 파이썬과 C #이 좋아하는 것 같습니다.


21
날짜 사람들과 함께 물건을 주위에하지 마십시오. moment.js를 사용하고 머리카락을 저장하십시오.
Valamas

1
실제로 파이썬과 db에서는 고통 스러웠습니다. db는 UTC를 사용하므로 (prob는 없습니다. UTC 서버 측으로 쉽게 변환 할 수 있으므로) 오프셋 정보를 유지하려면 다른 필드가 필요합니다. 그리고 파이썬은 자바 스크립트의 밀리 초 대신 나노초를 사용하는 것을 선호합니다. 보통 밀리 초보다 충분하고 선호됩니다. 파이썬에서는 dateutil.parser.parse 만이 올바르게 구문 분석하고 밀리 초 ISO를 작성하려면 "_when = when.strftime ("% Y- % m- % dT % H : % M : % S. % f % z "); _when [:-8] + _when [-5 :]"를 반환하여 나노를 밀리미터로 변환합니다. 그것은 좋지 않다.
Daniel F

3
실제로 다음과 같이 형식을 생략 할 수 있습니다 moment(new Date()).format(). "버전 1.5.0부터 형식없이 moment # format을 호출하면 기본적으로 ISO8601 형식이됩니다 YYYY-MM-DDTHH:mm:ssZ." Doc : momentjs.com/docs/#/displaying/fromnow
user193130

1
좋은 점은 @ user193130이지만 출력은 기본 방법과 다르기 때문에 조심해야합니다. moment().format() "2015-03-04T17:16:05+03:00" (new Date()).toISOString() "2015-03-04T14:16:24.555Z"
Olga

1
아마도 까다 롭지만이 예제는 표준 시간대가 아닌 UTC에서 현재 오프셋을 반환합니다. 시간대는 "미국 / 토론토"와 같이 일반적으로 표현되는 지역입니다. 많은 표준 시간대는 일년에 두 번 UTC 오프셋을 변경하므로 표준 시간대를 현재 UTC 오프셋에서 (항상) 확인할 수 없습니다. 따라서이 답변은 표준 시간대 정보도 삭제합니다. :-)
Martin Fido

27

질문 질문은 ISO 형식이었다 감소 정밀. 짜잔 :

 new Date().toISOString().slice(0, 19) + 'Z'
 // '2014-10-23T13:18:06Z'

후행 Z가 필요하다고 가정하면 그렇지 않으면 생략하십시오.


14

Internet Explorer 8 및 이전 버전에서는 지원되지 않는 최단 시간 :

new Date().toJSON()

12

IE7을 지원할 필요가없는 경우 다음은 훌륭하고 간결한 해킹입니다.

JSON.parse(JSON.stringify(new Date()))

IE7의 경우이 결정은 json3-library ( bestiejs.github.io/json3 ) 에 포함 된 경우에도 적합 합니다. 감사합니다 :)
vladimir

IE8에서도 실패합니다. ( " '
JSON'is

1
특히 명시된 목표가 간결한 경우 JSON을 통한 라운드 트립은 추악합니다. toJSON대신 날짜의 방법을 사용하십시오. JSON.stringify어쨌든 커버 아래에서 사용하고 있습니다.
Mark Amery

@CeesTimmerman IE8은 JSON일부 호환 모드는 아니지만 개체를 지원합니다 . 참조 stackoverflow.com/questions/4715373/...
마크 Amery

3
이것은 어떤 방법으로보다 낫 .toISOString()습니까?
Martin

7

고객이 머리에서 변환하는 것을 좋아하지 않기 때문에 일반적으로 UTC 날짜를 표시하고 싶지 않습니다. 현지 ISO 날짜 를 표시하기 위해 다음 기능을 사용합니다.

function toLocalIsoString(date, includeSeconds) {
    function pad(n) { return n < 10 ? '0' + n : n }
    var localIsoString = date.getFullYear() + '-'
        + pad(date.getMonth() + 1) + '-'
        + pad(date.getDate()) + 'T'
        + pad(date.getHours()) + ':'
        + pad(date.getMinutes()) + ':'
        + pad(date.getSeconds());
    if(date.getTimezoneOffset() == 0) localIsoString += 'Z';
    return localIsoString;
};

위의 함수는 표준 시간대 오프셋 정보를 생략하므로 (현지 시간이 UTC 인 경우 제외) 아래 함수를 사용하여 로컬 오프셋을 단일 위치에 표시합니다. 매번 오프셋을 표시하려는 경우 위 함수의 결과에 출력을 추가 할 수도 있습니다.

function getOffsetFromUTC() {
    var offset = new Date().getTimezoneOffset();
    return ((offset < 0 ? '+' : '-')
        + pad(Math.abs(offset / 60), 2)
        + ':'
        + pad(Math.abs(offset % 60), 2))
};

toLocalIsoString을 사용합니다 pad. 필요한 경우 거의 모든 패드 기능처럼 작동하지만 완전성을 위해 이것이 내가 사용하는 것입니다.

// Pad a number to length using padChar
function pad(number, length, padChar) {
    if (typeof length === 'undefined') length = 2;
    if (typeof padChar === 'undefined') padChar = '0';
    var str = "" + number;
    while (str.length < length) {
        str = padChar + str;
    }
    return str;
}

3

'T'뒤에 '+'가 없습니다.

isoDate: function(msSinceEpoch) {
  var d = new Date(msSinceEpoch);
  return d.getUTCFullYear() + '-' + (d.getUTCMonth() + 1) + '-' + d.getUTCDate() + 'T'
         + d.getUTCHours() + ':' + d.getUTCMinutes() + ':' + d.getUTCSeconds();
}

해야합니다.

선행 0의 경우 여기 에서 사용할 수 있습니다 .

function PadDigits(n, totalDigits) 
{ 
    n = n.toString(); 
    var pd = ''; 
    if (totalDigits > n.length) 
    { 
        for (i=0; i < (totalDigits-n.length); i++) 
        { 
            pd += '0'; 
        } 
    } 
    return pd + n.toString(); 
} 

다음과 같이 사용하십시오.

PadDigits(d.getUTCHours(),2)

대단하다! 그러나 누락 된 "0"을 해결하지는 않습니다.
James A. Rosen

1
정수를 2 문자 문자열로 변환하는 함수를 작성하고 (인수가 10보다 작 으면 '0'을 앞에 추가) 날짜 / 시간의 각 부분에 대해 호출하십시오.
dan04

3
function timeStr(d) { 
  return ''+
    d.getFullYear()+
    ('0'+(d.getMonth()+1)).slice(-2)+
    ('0'+d.getDate()).slice(-2)+
    ('0'+d.getHours()).slice(-2)+
    ('0'+d.getMinutes()).slice(-2)+
    ('0'+d.getSeconds()).slice(-2);
}

1
IE5 모드에서는 여기에있는 다른 모든 대답이 존재하지 않는 함수를 사용했기 때문에이 경로로 이동해야했습니다.
Elaskanator

3

toISOString의 문제점은 날짜 시간을 "Z"로만 제공한다는 것입니다.

ISO-8601은 2016-07-16T19 : 20 : 30 + 5 : 30 (표준 시간대가 UTC보다 앞서는 경우) 및 2016-07-16T19 : 20 : 30-01과 같은 형식으로 시간대와 시간의 차이로 날짜 시간을 정의합니다. : 00 (시간대가 UTC보다 늦은 경우)

나는 작은 플러그인으로 다른 플러그인 인 moment.js를 사용하는 것이 좋지 않다고 생각합니다. 특히 몇 줄의 코드로 얻을 수있을 때 특히 그렇습니다.



    var timezone_offset_min = new Date().getTimezoneOffset(),
        offset_hrs = parseInt(Math.abs(timezone_offset_min/60)),
        offset_min = Math.abs(timezone_offset_min%60),
        timezone_standard;

    if(offset_hrs < 10)
        offset_hrs = '0' + offset_hrs;

    if(offset_min > 10)
        offset_min = '0' + offset_min;

    // getTimezoneOffset returns an offset which is positive if the local timezone is behind UTC and vice-versa.
    // So add an opposite sign to the offset
    // If offset is 0, it means timezone is UTC
    if(timezone_offset_min < 0)
        timezone_standard = '+' + offset_hrs + ':' + offset_min;
    else if(timezone_offset_min > 0)
        timezone_standard = '-' + offset_hrs + ':' + offset_min;
    else if(timezone_offset_min == 0)
        timezone_standard = 'Z';

    // Timezone difference in hours and minutes
    // String such as +5:30 or -6:00 or Z
    console.log(timezone_standard); 

시간대 오프셋이 시간과 분으로 설정되면 날짜 / 시간 문자열에 추가 할 수 있습니다.

나는 그것에 블로그 게시물을 썼습니다 : http://usefulangle.com/post/30/javascript-get-date-time-with-offset-hours-minutes



2

훨씬 적은 코드로 출력을 얻을 수있었습니다.

var ps = new Date('2010-04-02T14:12:07')  ;
ps = ps.toDateString() + " " + ps.getHours() + ":"+ ps.getMinutes() + " hrs";

산출:

Fri Apr 02 2010 19:42 hrs

0
function getdatetime() {
    d = new Date();
    return (1e3-~d.getUTCMonth()*10+d.toUTCString()+1e3+d/1)
        .replace(/1(..)..*?(\d+)\D+(\d+).(\S+).*(...)/,'$3-$1-$2T$4.$5Z')
        .replace(/-(\d)T/,'-0$1T');
}

어딘가에서 스택 오버플로에 대한 기본 사항을 찾았으며 (다른 스택 교환 코드 골프의 일부라고 생각) Internet Explorer 10 또는 이전 버전에서도 작동하도록 개선했습니다. 추악하지만 작업이 완료됩니다.


0

설탕과 현대적인 구문으로 Sean의 위대하고 간결한 답변을 확장하려면 :

// date.js

const getMonthName = (num) => {
  const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Oct', 'Nov', 'Dec'];
  return months[num];
};

const formatDate = (d) => {
  const date = new Date(d);
  const year = date.getFullYear();
  const month = getMonthName(date.getMonth());
  const day = ('0' + date.getDate()).slice(-2);
  const hour = ('0' + date.getHours()).slice(-2);
  const minutes = ('0' + date.getMinutes()).slice(-2);

  return `${year} ${month} ${day}, ${hour}:${minutes}`;
};

module.exports = formatDate;

그런 다음 예를 들어.

import formatDate = require('./date');

const myDate = "2018-07-24T13:44:46.493Z"; // Actual value from wherever, eg. MongoDB date
console.log(formatDate(myDate)); // 2018 Jul 24, 13:44
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.