Why it doesn't work?

作業のメモ、記録をブログに残しています。

JavaScript Dateオブジェクトの値をhtml <input type="datetime-local">のフォーマットに変換する

HTMLソース部分

<input id="start_time" type="datetime-local" step="1">

にDateオブジェクトの値を初期値として設定してみます。
"datetime-local"のvalue属性に"YYYY-MM-DDThh:mm:ss"のフォーマット文字列を設定する事で初期値として表示することができます。

toISOStringメソッドを使用してみる

初めはtoISOStringメソッドを使用すればISOフォーマットの文字列が取得できると考え、以下のような実装をしました。

<script>
var d = new Date('2018/01/28 15:35:00');
var s = d.toISOString();
document.getElementById("start_time").value = s;
</script>

ところが、上手く表示されません。
f:id:zakiyamatakashi:20180128160138p:plain
コンソール上で警告が出てました。

The specified value "2018-01-28T06:35:00.000Z" does not conform to the required format. The format is "yyyy-MM-ddThh:mm" followed by optional ":ss" or ":ss.SSS".

".000Z"が入力フォーマットとして不要なようです。と、いうことで

toISOStringメソッドで取得した文字列を切り出す

取得した文字列の年から秒までを切り出してみました。

<script>
var d = new Date('2018/01/28 15:35:00');
var s = d.toISOString().substr(0,19);
document.getElementById("start_time").value = s;
</script>

f:id:zakiyamatakashi:20180128160524p:plain
出来ました。と思ったんですが、9時間ずれてます。
toISOStringメソッドで取得した文字列の終端"Z" を取り除いた事で、UTC時刻の6時でなくただの(?)6時となってしまったためです。当たり前ですね。。。

メソッドを自作する

結局、stackoverflowを参考に、以下の様な関数を自作しました。

<script>
var d = new Date('2018/01/28 15:35:00');
document.getElementById("start_time").value = convetDateToIso(d);
function convetDateToIso(d){
  return d.getFullYear()+'-'
       + (("0"+(d.getMonth() + 1)).slice(-2))+'-'
       + ("0"+d.getDate()).slice(-2)+'T'
       + ("0"+d.getHours()).slice(-2)+':'
       + ("0"+d.getMinutes()).slice(-2)+':'
       + ("0"+d.getSeconds()).slice(-2);
}
</script>

期待通り表示出来ました。
f:id:zakiyamatakashi:20180128164352p:plain

2018/12/26 追記

tmさんからコメントをいただきました。ご指摘いただいたやり方で期待通りの結果を取得できました。こちらのほうが冗長でなく理解しやすいです。ありがとうございました。

<script>
var d = new Date('2018/01/28 15:35:00');
document.getElementById("start_time").value = convetDateToIso(d);
function convetDateToIso(d){
  const shift = d.getTime()+9*60*60*1000;
  const time = new Date(shift).toISOString().split('.')[0];
  return time;
}</script>