web-dev-qa-db-ja.com

Date.toISOString()がUTCではなく現地時間

次の日時があるとします。

_var d = new Date("Sat Jul 21 2018 14:00:00 GMT+0200");
_

文字列(console.log(d))としてエクスポートすると、ブラウザ間で一貫性のない結果が得られます。

  • Sat Jul 21 2018 14:00:00 GMT+0200 (Paris, Madrid (heure d’été)) Chrome

  • _Sat Jul 21 14:00:00 UTC+0200 2018_とInternet Explorerなど.

したがって、一貫性のない形式のサーバーに日時を送信することはできません。

その場合の自然な考え方は、ISO8601日時を要求してd.toISOString();を使用することですが、UTC日時は_2018-07-21T12:00:00.000Z_になりますが、代わりにローカルタイムゾーンの時刻が必要です。

_2018-07-21T14:00:00+0200
or
2018-07-21T14:00:00
_

これを取得するには(momentjsなどのサードパーティの依存関係に依存せずに)?

私はこれを試しましたが、動作するようですが、-それを行うもっと自然な方法はありませんか?

_var pad = function(i) { return (i < 10) ? '0' + i : i; };

var d = new Date("Sat Jul 21 2018 14:00:00 GMT+0200");
Y = d.getFullYear();
m = d.getMonth() + 1;
D = d.getDate();
H = d.getHours();
M = d.getMinutes();
S = d.getSeconds();
s = Y + '-' +  pad(m) + '-' + pad(D) + 'T' + pad(H) + ':' + pad(M) + ':' + pad(S);
console.log(s);_
10
Basj

ECMA-262ではタイムゾーンを使用して日付文字列をフォーマットするための組み込みサポートが制限されており、実装に依存するtoStringおよびtoLocaleStringメソッドまたはtoISOStringのいずれかがあります、常にUTCです。 toISOStringでパラメータにUTCまたはローカルオフセット(デフォルトはUTC)を指定できるとよいでしょう。

ローカルオフセットを使用してISO 8601準拠のタイムスタンプを生成する独自の関数を記述することは難しくありません。

function toISOLocal(d) {
  var z  = n =>  ('0' + n).slice(-2);
  var zz = n => ('00' + n).slice(-3);
  var off = d.getTimezoneOffset();
  var sign = off < 0? '+' : '-';
  off = Math.abs(off);

  return d.getFullYear() + '-'
         + z(d.getMonth()+1) + '-' +
         z(d.getDate()) + 'T' +
         z(d.getHours()) + ':'  + 
         z(d.getMinutes()) + ':' +
         z(d.getSeconds()) + '.' +
         zz(d.getMilliseconds()) +
         sign + z(off/60|0) + ':' + z(off%60); 
}

console.log(toISOLocal(new Date()));
11
RobG