date-fns の使い方

Modern JavaScript date utility library

v4.1.066.1M/週MITユーティリティ
AI生成コンテンツ

この記事はAIによって生成されました。内容の正確性は保証されません。最新の情報は公式ドキュメントをご確認ください。

date-fns の使い方 — JavaScript日付操作のモダンなユーティリティライブラリ

一言でいうと

date-fns は、JavaScript の Date オブジェクトを操作するための関数群を提供するユーティリティライブラリです。「日付版 Lodash」とも呼ばれ、200以上の純粋関数をツリーシェイキング可能な形で提供します。

どんな時に使う?

  • 日付のフォーマット・パース2024-01-152024年1月15日(月) のように表示したい、またはその逆の変換をしたい場合
  • 日付の計算・比較 — 「今日から30日後」「2つの日付の差分は何日か」「期間内かどうか」といった演算が必要な場合
  • 国際化(i18n)対応の日付表示 — 日本語・英語など複数ロケールで日付をフォーマットしたい場合

インストール

# npm
npm install date-fns

# yarn
yarn add date-fns

# pnpm
pnpm add date-fns

本記事は date-fns v4.1.0 を基に執筆しています。v4 では第一級のタイムゾーンサポートが追加されています。

基本的な使い方

date-fns は必要な関数だけを個別にインポートして使います。ネイティブの Date オブジェクトをそのまま受け取り、新しい Date を返す純粋関数として設計されています。

import { format, addDays, differenceInDays, isAfter } from "date-fns";
import { ja } from "date-fns/locale";

// 日付のフォーマット
const today = new Date(2024, 5, 15); // 2024年6月15日
console.log(format(today, "yyyy-MM-dd"));
//=> '2024-06-15'

// 日本語ロケールでフォーマット
console.log(format(today, "yyyy年M月d日(EEEE)", { locale: ja }));
//=> '2024年6月15日(土曜日)'

// 日付の加算
const nextWeek = addDays(today, 7);
console.log(format(nextWeek, "yyyy-MM-dd"));
//=> '2024-06-22'

// 日付の差分
const start = new Date(2024, 0, 1);
const end = new Date(2024, 11, 31);
console.log(differenceInDays(end, start));
//=> 365

// 日付の比較
console.log(isAfter(end, start));
//=> true

よく使うAPIと使い方

1. format — 日付を文字列にフォーマット

最も使用頻度の高い関数です。フォーマットトークンは Unicode Technical Standard #35 に準拠しています。

import { format } from "date-fns";
import { ja } from "date-fns/locale";

const date = new Date(2024, 5, 15, 14, 30, 0);

// 基本的なフォーマット
format(date, "yyyy-MM-dd");           //=> '2024-06-15'
format(date, "yyyy/MM/dd HH:mm:ss"); //=> '2024/06/15 14:30:00'
format(date, "HH:mm");               //=> '14:30'

// 曜日・月名を含むフォーマット(英語)
format(date, "EEEE, MMMM do, yyyy"); //=> 'Saturday, June 15th, 2024'

// 日本語ロケール
format(date, "M月d日(E)", { locale: ja }); //=> '6月15日(土)'

// ISO 8601 週番号
format(date, "yyyy-'W'II");           //=> '2024-W24'

注意: DDddYYyy は意味が異なります。dd は月の日、DD は年の日(1〜366)です。多くの場合 ddyyyy を使います。

2. parse / parseISO — 文字列を Date に変換

import { parse, parseISO } from "date-fns";

// ISO 8601 文字列のパース
const isoDate = parseISO("2024-06-15T14:30:00+09:00");
console.log(isoDate);
//=> Date オブジェクト(ローカルタイムゾーンに変換される)

// 任意のフォーマット文字列をパース
const parsed = parse("2024年06月15日", "yyyy年MM月dd日", new Date());
console.log(format(parsed, "yyyy-MM-dd"));
//=> '2024-06-15'

// 第3引数は参照日(パース結果に不足する情報を補完する基準)
const timeOnly = parse("14:30", "HH:mm", new Date(2024, 5, 15));
console.log(timeOnly);
//=> 2024-06-15T14:30:00 のDateオブジェクト

3. addDays / addMonths / subDays など — 日付の加減算

date-fns はイミュータブルなので、元の Date オブジェクトは変更されません。

import {
  addDays,
  addMonths,
  addYears,
  addHours,
  subDays,
  subMonths,
} from "date-fns";

const base = new Date(2024, 0, 31); // 2024-01-31

addDays(base, 1);    //=> 2024-02-01
addMonths(base, 1);  //=> 2024-02-29(うるう年を考慮)
addYears(base, 1);   //=> 2025-01-31
addHours(base, 3);   //=> 2024-01-31T03:00:00

subDays(base, 10);   //=> 2024-01-21
subMonths(base, 1);  //=> 2023-12-31

// 元のオブジェクトは変更されない
console.log(base);   //=> 2024-01-31(そのまま)

4. differenceInDays / differenceInMonths など — 日付の差分計算

import {
  differenceInDays,
  differenceInMonths,
  differenceInYears,
  differenceInHours,
  differenceInBusinessDays,
  intervalToDuration,
} from "date-fns";

const start = new Date(2024, 0, 1);
const end = new Date(2024, 11, 31);

differenceInDays(end, start);         //=> 365
differenceInMonths(end, start);       //=> 11
differenceInYears(end, start);        //=> 0

// 営業日(土日を除く)の差分
differenceInBusinessDays(end, start); //=> 261

// 時間単位の差分
const morning = new Date(2024, 5, 15, 9, 0);
const evening = new Date(2024, 5, 15, 18, 30);
differenceInHours(evening, morning);  //=> 9

// 年・月・日・時・分・秒に分解
const duration = intervalToDuration({ start, end });
console.log(duration);
//=> { years: 0, months: 11, days: 30, hours: 0, minutes: 0, seconds: 0 }

5. isValid / isBefore / isAfter / isWithinInterval — 日付の検証・比較

import {
  isValid,
  isBefore,
  isAfter,
  isEqual,
  isWithinInterval,
  isWeekend,
  isFuture,
  isPast,
} from "date-fns";

// バリデーション
isValid(new Date(2024, 5, 15));     //=> true
isValid(new Date("invalid"));       //=> false
isValid(new Date(NaN));             //=> false

// 比較
const dateA = new Date(2024, 0, 1);
const dateB = new Date(2024, 11, 31);

isBefore(dateA, dateB);  //=> true
isAfter(dateA, dateB);   //=> false
isEqual(dateA, dateA);   //=> true

// 範囲内チェック
const target = new Date(2024, 5, 15);
isWithinInterval(target, { start: dateA, end: dateB }); //=> true

// ユーティリティ
isWeekend(new Date(2024, 5, 15));   //=> true(土曜日)
isFuture(new Date(2099, 0, 1));     //=> true
isPast(new Date(2000, 0, 1));       //=> true

類似パッケージとの比較

特徴date-fnsDay.jsLuxonMoment.js
バンドルサイズ(最小構成)関数単位で極小~2KB~23KB~72KB
ツリーシェイキング✅ 完全対応⚠️ プラグイン単位
イミュータブル
TypeScript✅ ネイティブ⚠️ @types
ネイティブ Date 使用❌(ラッパー)❌(ラッパー)❌(ラッパー)
タイムゾーン(v4)✅ 組み込みプラグイン✅ 組み込みプラグイン
メンテナンス状況✅ 活発✅ 活発✅ 活発⛔ 非推奨
関数数200+少なめ中程度多い

選定の指針:

  • バンドルサイズを最小化したい → date-fns(ツリーシェイキングで使う関数だけバンドル)
  • チェーンメソッドが好み → Day.js / Luxon
  • ネイティブ Date をそのまま扱いたい → date-fns

注意点・Tips

フォーマットトークンの大文字・小文字に注意

import { format } from "date-fns";

const date = new Date(2024, 0, 7);

// ❌ よくある間違い
format(date, "YYYY-MM-DD"); // 意図しない結果になる可能性あり

// ✅ 正しい
format(date, "yyyy-MM-dd"); // '2024-01-07'

yyyy は暦年、YYYY はISO週番号年です。年末年始で値がずれることがあります。同様に dd は月の日、DD は年の日です。

ロケールはバンドルサイズに影響する

// ❌ 全ロケールをインポートしない
// import * as locales from "date-fns/locale";

// ✅ 必要なロケールだけインポート
import { ja } from "date-fns/locale";
import { enUS } from "date-fns/locale";

v4 のタイムゾーンサポート

v4 からは date-fns/tz でタイムゾーン操作が組み込みでサポートされています。

import { TZDate } from "date-fns/tz";
import { format, addHours } from "date-fns";

// タイムゾーン付きの日付を作成
const tokyoDate = new TZDate(2024, 5, 15, 12, 0, 0, "Asia/Tokyo");
const nyDate = new TZDate(2024, 5, 15, 12, 0, 0, "America/New_York");

// 通常の date-fns 関数がそのまま使える
console.log(format(tokyoDate, "yyyy-MM-dd HH:mm:ss zzz"));
console.log(format(addHours(tokyoDate, 3), "HH:mm"));

month は 0 始まり

JavaScript の Date コンストラクタと同様に、月は 0 始まり(0 = 1月、11 = 12月)です。

// 2024年6月15日を作る場合
new Date(2024, 5, 15); // 月は 5(= 6月)

Invalid Date のハンドリング

import { isValid, parse } from "date-fns";

const result = parse("not-a-date", "yyyy-MM-dd", new Date());
if (!isValid(result)) {
  console.error("無効な日付です");
}

パースに失敗すると Invalid Date が返ります。必ず isValid でチェックしてから後続処理に渡しましょう。

まとめ

date-fns は、ネイティブの Date オブジェクトをイミュータブルかつ関数型のスタイルで操作できる、JavaScript 日付操作ライブラリの決定版です。ツリーシェイキングによるバンドルサイズの最適化、完全な TypeScript サポート、そして v4 で追加されたタイムゾーンの組み込みサポートにより、モダンなWebアプリケーション開発において最も実用的な選択肢の一つといえます。

比較記事