1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Date や 日時文字列の変換 Intl.DateTimeFormatを使った存在しないフォーマットの作り方

Last updated at Posted at 2025-01-19

最近は Intl.DateTimeFormat がとても便利なので 紹介します。

Intl.DateTimeFormat とは

Intl.DateTimeFormatDate を任意の文字列フォーマットに変換する為のクラスです。

通常は format(date) で フォーマットします。

ただ、必要なフォーマットが存在しない!今回はそういうときの話です。

formatToParts(date) の使い方

formatToParts(date) という 部品単位で どういう部品であるかの情報をつけて出力してくれるものがあります。

つまり、必要な部品を用意してくれるのです。

const from = new Date();
const options: Intl.DateTimeFormatOptions = {
  year: "numeric",
  month: "2-digit",
  day: "2-digit",
  hour: "2-digit",
  minute: "2-digit",
  second: "2-digit",
  calendar: "iso8601",
  fractionalSecondDigits: 3,
  timeZoneName: "shortOffset",
};
const format = new Intl.DateTimeFormat("ja-JP", options);
const { year, month, day, hour, minute, second, fractionalSecond, timeZoneName } = ((parts) => {
  return Object.fromEntries(parts.filter(({ type }) => type !== "literal").map(({ type, value }) => [type, value])) as {
    year: string;
    month: string;
    day: string;
    hour: string;
    minute: string;
    second: string;
    fractionalSecond: string;
    timeZoneName: string;
  };
})(format.formatToParts(from));
const formatted = `${year}-${month}-${day}T${hour}:${minute}:${second}.${fractionalSecond}`;
console.log(formatted);
// -> "2025-01-19T14:04:22.377

これを使いまわすなら次の様な関数を作るとよいでしょう。

const toLocal = makeToLocal();
{
  const date = new Date();
  console.log(`${date.toISOString()} -> ${toLocal(date)}`);
  // -> "2025-01-19T05:06:41.549Z -> 2025-01-19T14:06:41.549"
}
{
  const date = new Date().toISOString();
  console.log(`${date} -> ${toLocal(date)}`);
  // -> "2025-01-19T05:06:41.551Z -> 2025-01-19T14:06:41.551"
}
/**
 * timeZone を local に 変換する
 */
function makeToLocal() {
  let toLocalFormat: Intl.DateTimeFormat | undefined;
  return toLocal;
  /**
   * timeZone が local な 日付文字列を返す
   */
  function toLocal(from: string): string;
  /**
   * timeZone が local な Date を返す
   */
  function toLocal(from: Date): string;
  function toLocal(from: string | Date): string {
    const isString = typeof from === "string";
    if (isString) {
      from = new Date(from as string);
    }
    if (typeof from === "string") throw new Error();
    const { year, month, day, hour, minute, second, fractionalSecond } = ((parts) => {
      return Object.fromEntries(parts.filter(({ type }) => type !== "literal").map(({ type, value }) => [type, value])) as {
        year: string;
        month: string;
        day: string;
        hour: string;
        minute: string;
        second: string;
        fractionalSecond: string;
        timeZoneName: string;
      };
    })((toLocalFormat ??= initial()).formatToParts(from));
    const result = `${year}-${month}-${day}T${hour}:${minute}:${second}.${fractionalSecond}`;
    return result;
    function initial() {
      const options: Intl.DateTimeFormatOptions = {
        year: "numeric",
        month: "2-digit",
        day: "2-digit",
        hour: "2-digit",
        minute: "2-digit",
        second: "2-digit",
        calendar: "iso8601",
        fractionalSecondDigits: 3,
        timeZoneName: "shortOffset",
      };
      return new Intl.DateTimeFormat("ja-JP", options);
    }
  }
}

以上。

1
0
0

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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?