LoginSignup
1
1

More than 3 years have passed since last update.

(つらいけど) JavaScript 生で RFC3339 な文字列を生成する方法

Posted at

RFC3339 という日時の記法があります。

1985-04-12T23:20:50.52Z

こういった書き方で日時を割り出します。

これを、ライブラリなしの JavaScript で表現しようとすると、実は大変です。

// Unixtime で指定したい場合はミリ秒で渡すこと
const date = new Date(1619505636 * 1000);
const timezoneOffset = date.getTimezoneOffset();
const timezoneHours = timezoneOffset / 60;
const timezoneMinutes = timezoneOffset % 60;
const rfc3339 = [
    date.getFullYear(),
    '-',
    (`0${(date.getMonth() + 1)}`).slice(-2),
    '-',
    (`0${date.getDate()}`).slice(-2),
    'T',
    (`0${date.getHours()}`).slice(-2),
    ':',
    (`0${date.getMinutes()}`).slice(-2),
    ':',
    (`0${date.getSeconds()}`).slice(-2),
    (-timezoneHours < 0 ? '' : '+'),
    (`0${-timezoneHours}`).slice(-2),
    ':',
    (`0${timezoneMinutes}`).slice(-2),
].join('');

console.log(rfc3339);
// outputs: 2021-04-27T06:40:36+00:00
// https://ideone.com/4OzmFl

つらいなあ。

タイムゾーンは Date クラスでは「現在のランタイムのロケール」に依存します。

Intl.DateTimeFormat を用いればロケール対応が可能らしいです。

ちなみに、 moment.js は開発をストップしメンテナンスモードとなっているため、後発の LuxonDay.js などのより軽量で安全なライブラリを使うことが推奨されています。


ちなみに PHP で同じことを実現しようとすると...

<?php

// Unixtime で指定したい場合は @ を最初につけること
$now = new DateTime('@1619505636');
echo $now->format('Y-m-d\TH:i:sP');
// outputs: 2021-04-27T06:40:36+00:00
// https://ideone.com/hwVWqJ

まあこれくらいは一行でできて当然よね...?

1
1
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1