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で返しますか?
ジョンウェルズ

new Date("xx").toISOString()生成NaN-NaN-NaNTNaN:NaN:NaN.NZネイティブ実装はRangeExceptionをスローします。
ジョセフレノックス

日付オブジェクトをsoapサービスに渡したい場合...それが方法です!:)ありがとう。
thinklinux

1
OPが提供するサンプルでは、​​ミリ秒やタイムゾーンはありません。
Dan Dascalescu 2016

彼らはIEのドキュメントモード5に知られていないため、「getUTCFullYear」などのすべてのこれらの関数呼び出しが失敗している
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 2016

60

Web上のほとんどすべてのto-ISOメソッドは、文字列を出力する前に「Z」ulu時間(UTC)に変換することでタイムゾーン情報を削除します。ブラウザのネイティブ.toISOString()もタイムゾーン情報をドロップします。

サーバーまたは受信者は常に送信者のタイムゾーン情報を取得しながら、完全なISO日付を常にズールー時間または必要なタイムゾーンに変換できるため、これにより貴重な情報が破棄されます。

私が遭遇した最善の解決策は、Moment.js JavaScriptライブラリを使用して、次のコードを使用することです。

タイムゾーン情報とミリ秒で現在の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に準拠しており、データベースに格納するのに適しています。PythonとC#は気に入っているようです。


21
デートの人々と一緒に物事をしないでください。moment.jsを使用して髪を保存してください。
Valamas 2013年

1
実際、pythonとdbでは、それは苦痛であることが判明しました。dbはUTCを使用します(UTCサーバー側に簡単に変換できるため、問題ありません)。オフセット情報を保持したい場合は、別のフィールドが必要です。また、Pythonは、JavaScriptのミリ秒ではなく、ナノ秒の使用を優先します。これは、通常十分であり、プレーンな秒よりも優先されます。Pythonでは、dateutil.parser.parseのみが正しく解析し、ミリ秒のISOを書き込むには "_when = when.strftime("%Y-%m-%dT%H:%M:%S.%f%zが必要です"); return _when [:-8] + _when [-5:]"ナノをミリに変換します。イケてないよ。
ダニエルF

3
実際には、次のようにフォーマットを省略できますmoment(new Date()).format()。「バージョン1.5.0以降、フォーマットなしでmoment#formatを呼び出すと、デフォルトで... ISO8601フォーマットになりますYYYY-MM-DDTHH:mm:ssZ。ドキュメント:momentjs.com/docs
#/

1
良い点@ user193130ですが、出力はネイティブメソッドとは異なるため、注意が必要です。 moment().format() "2015-03-04T17:16:05+03:00" (new Date()).toISOString() "2015-03-04T14:16:24.555Z"
Olga

1
うるさいかもしれませんが、これらの例では、タイムゾーンではなく、UTCからの現在のオフセットを返します。タイムゾーンは、一般的に「アメリカ/トロント」などと表現される地理的領域です。多くのタイムゾーンはUTCオフセットを年に2回変更し、タイムゾーンは現在の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)が含まれていれば、この決定も当てはまります。おかげで:)
ウラジミール

IE8でも失敗します。(「「JSON」は未定義」)
Cees Timmerman、

1
特に指定された目標が簡潔さである場合、JSONを介したラウンドトリップは醜いです。toJSON代わりに日付のメソッドを使用してください。JSON.stringifyとにかくカバーの下でそれを使用しています。
Mark Amery

@CeesTimmerman IE8はJSONオブジェクトをサポートしますが、一部の互換モードではサポートしません。stackoverflow.com/questions/4715373/…を
Mark Amery

3
これはどのように優れてい.toISOString()ますか?
マーティン

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である場合を除く)、以下の関数を使用して1つの場所のローカルオフセットを表示します。毎回オフセットを表示する場合は、上記の関数の結果にその出力を追加することもできます。

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

それを行う必要があります。

先行ゼロについては、ここからこれを使用できます。

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」には対応していません。
ジェームズA.ローゼン

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の問題は、datetimeが "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');
}

Stack Overflowの基本をどこかで見つけて(他のStack Exchangeコードゴルフの一部だったと思います)、Internet Explorer 10以前でも動作するように改善しました。それは醜いですが、それは仕事を成し遂げます。


0

ショーンの素晴らしく簡潔な答えをいくつかの砂糖と現代の構文で拡張するには:

// 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.