logo Ribbit's works

Dateオブジェクトを任意の文字列でフォーマットする(yyyy-MM-ddなど)【JavaScript, TypeScript両対応】

#TypeScript #JavaScript
にメンテナンス済み
記事のトップ画像

今回は JavaScript の Date オブジェクトを、指定した文字列(yyyy-MM-dd など)でフォーマットする方法を紹介します。

標準機能で解決するかも

Date オブジェクトには様々なフォーマット関数が用意されています。

任意の文字列で変換せずとも解決する可能性がありますので、要件に合うものがないか確認してみてください。

JavaScript

const getFormattedDate = (date) => date.toLocaleDateString(); // → 2021/12/8
const getFormattedDate = (date) => date.toISOString().split('T')[0]; // → 2021-12-08
const getFormattedDate = (date) => date.toLocaleString(); // → 2021/12/8 10:29:30
const getFormattedDate = (date) => date.toLocaleTimeString(); // → 6:00:00
const getFormattedDate = (date) => date.toJSON(); // → 2021-12-08T01:29:30.811Z
const getFormattedDate = (date) => date.toString(); // → Wed Dec 08 2021 10:29:30 GMT+0900 (日本標準時)
const getFormattedDate = (date) => date.toISOString(); // → 2021-12-08T01:29:30.811Z
const getFormattedDate = (date) => date.toDateString(); // → Wed Dec 08 2021

TypeScript

const getFormattedDate = (date: Date): string => date.toLocaleDateString(); // → 2021/12/8
const getFormattedDate = (date: Date): string => date.toISOString().split('T')[0]; // → 2021-12-08
const getFormattedDate = (date: Date): string => date.toLocaleString(); // → 2021/12/8 10:29:30
const getFormattedDate = (date: Date): string => date.toLocaleTimeString(); // → 6:00:00
const getFormattedDate = (date: Date): string => date.toJSON(); // → 2021-12-08T01:29:30.811Z
const getFormattedDate = (date: Date): string => date.toString(); // → Wed Dec 08 2021 10:29:30 GMT+0900 (日本標準時)
const getFormattedDate = (date: Date): string => date.toISOString(); // → 2021-12-08T01:29:30.811Z
const getFormattedDate = (date: Date): string => date.toDateString(); // → Wed Dec 08 2021

ES2015以降で推奨される方法: Intl.DateTimeFormat

ES2015以降、より柔軟で国際化に対応したIntl.DateTimeFormatを使用することが推奨されています。

const date = new Date('2024-01-19');

// 基本的な使用方法
new Intl.DateTimeFormat('ja-JP').format(date); // → 2024/1/19
new Intl.DateTimeFormat('en-US').format(date); // → 1/19/2024

// オプションを指定したフォーマット
const options = {
  year: 'numeric',
  month: '2-digit', 
  day: '2-digit'
};
new Intl.DateTimeFormat('ja-JP', options).format(date); // → 2024/01/19
new Intl.DateTimeFormat('en-US', options).format(date); // → 01/19/2024

// より詳細なフォーマット
const detailOptions = {
  year: 'numeric',
  month: 'long',
  day: 'numeric',
  weekday: 'long'
};
new Intl.DateTimeFormat('ja-JP', detailOptions).format(date); // → 2024年1月19日金曜日
new Intl.DateTimeFormat('en-US', detailOptions).format(date); // → Friday, January 19, 2024

// 時間を含む場合
const timeOptions = {
  year: 'numeric',
  month: '2-digit',
  day: '2-digit',
  hour: '2-digit',
  minute: '2-digit',
  second: '2-digit'
};
new Intl.DateTimeFormat('ja-JP', timeOptions).format(new Date()); // → 2024/01/19 10:30:45

Intl.DateTimeFormatの利点:

  • 国際化対応(多言語サポート)
  • タイムゾーン処理
  • より読みやすいコード
  • ブラウザネイティブサポート

任意の文字列でフォーマットするコード

ES2015以降であれば、前述のIntl.DateTimeFormatを使用することが推奨されますが、どうしても任意の文字列でフォーマットしたい場合は、以下のコードを参考にしてください。

任意の日付と時間に対応しています。

JavaScript

const getFormattedDate = (date, format) => {
  const symbol = {
    M: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    m: date.getMinutes(),
    s: date.getSeconds(),
  };

  const formatted = format.replace(/(M+|d+|h+|m+|s+)/g, (v) =>
    ((v.length > 1 ? '0' : '') + symbol[v.slice(-1)]).slice(-2)
  );

  return formatted.replace(/(y+)/g, (v) => date.getFullYear().toString().slice(-v.length));
};

TypeScript

const getFormattedDate = (date: Date, format: string) => {
  const symbol = {
    M: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    m: date.getMinutes(),
    s: date.getSeconds(),
  };

  const formatted = format.replace(/(M+|d+|h+|m+|s+)/g, (v) =>
    ((v.length > 1 ? "0" : "") + symbol[v.slice(-1) as keyof typeof symbol]).slice(-2)
  );

  return formatted.replace(/(y+)/g, (v) =>
    date.getFullYear().toString().slice(-v.length)
  );
};

デモ

今回紹介したプログラムをお試しいただけます。

解説

まず最初の replace 関数で、年を除くすべての文字を対応する時刻に変換しています。

const formatted = format.replace(/(M+|d+|h+|m+|s+)/g, (v) =>
  ((v.length > 1 ? '0' : '') + symbol[v.slice(-1)]).slice(-2)
);

それぞれについて、文字数が 2 つ(月であれば MM)指定されていた場合は、先頭を 0 で埋めた値が返却されます。

return formatted.replace(/(y+)/g, (v) => date.getFullYear().toString().slice(-v.length));

年については最大 4 桁になる可能性があるため、処理を分けています。 4 桁未満の場合は、先頭から桁を削っていきます。