JavaScriptでISO 8601でタイムゾーンオフセットを使用して日付をフォーマットする方法は?


100

目標:検索local timeし、UTC 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ドキュメントから理解できないので、このような場合の形式はどのようになっているのだろうと思います。前もって感謝します。


受け入れられた回答は10年以上古く、JSはtoISOString()2009年から含まれているという簡単なメモです。以下の私の答えを参照してください。
mikemaccana

回答:


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 '07

1
あなたがで定義を参照してください、符号を反転する必要が@正人さんdeveloper.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
bfavaretto

2
ここで、pad関数は、ミリ秒を除く日付の各セクションに適切な文字列を返します。たとえば、入力として5msの場合、05を返す05が返されます。これは、同じ関数jsbinの
Safique Ahmed Faruque

9
注意:この回答には微妙なバグがあります。フランスとカナダの特定の場所など、ゾーンにオフセット分があり、負の値(例:-09:30)である場合、タイムゾーンオフセットは正しく計算されません。Modは負の数を返すため、abs()の前にfloor()を実行すると、誤ってオフセットが負になります。このバグを修正するには、abs()とTHEN floor()を使用します。回答を編集しようとしましたが、どうやら「この編集は投稿の作成者に対処することを目的としており、編集としては意味がありません」と思われます。
tytk 2017

5
@tytk-大漁!つまり、確かに微妙です。私はあなたの修正を答えに加えました。コメントありがとうございます!
Steven Moseley 2017

67

getTimezoneOffset() 参照した仕様で必要な形式の反対符号を返します。

この形式はISO8601としても知られています。より正確にはRFC3339としても知られています

この形式では、UTCはaで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時間文字列を提供します。
オースティンフランス

1
@AustinFrance-あなたは正しいです!この点について他の人を頻繁に訂正しているので、その時に私がその間違いをしたことに驚いています。申し訳ありませんが、2年前にあなたのコメントを見られませんでした!回答を編集しました。
Matt Johnson-Pint 2015

9

標準ライブラリへの1回のAPI呼び出しだけで要求された情報を取得できることを検討する価値があると思います...

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

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

'T'デリミタを追加したり、 'GMT-'を削除したり、末尾に ':00'を追加したりする場合は、テキストスワッピングを行う必要があります。

ただし、必要に応じて、他のオプションを簡単に試すことができます。12時間を使用するか、秒を省略します。

ISO 8601形式を使用する国の1つであるスウェーデンをロケールとして使用していることに注意してください。ほとんどのISO諸国は、タイムゾーンの省略形を使用するカナダ以外のタイムゾーンオフセットにこの「GMT-4」形式を使用していると思います。東部夏時間の「EDT」。

新しい標準のi18n関数 "Intl.DateTimeFormat()"から同じことを取得できますが、オプションを介して時間を含めるように指示する必要があります。そうしないと、日付が表示されます。


1
うーん、svの場合、実際には「CET」を取得し、夏時間の日付は「CEST」を取得します...しかし、入力のおかげで、標準のAPIで十分です(ログメッセージの先頭に日付を付ける必要があります)。時間とタイムゾーンについて真剣に考えたかったら、ちょっとライブラリに行くと思います...
mmey

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

ここに私の2つの送信だけ

私は日時でこの問題に直面していたので、私がしたことはこれです:

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形式を使用しているため機能します。


無効な回答、これは回答しますが、他の質問...この回答はSOで簡単に見つけることができます。
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

これは、いくつかの単純な拡張メソッドで実現できます。次のDate拡張メソッドは、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.