知らなきゃ損!date-fns の Year Helpers で過去の日付を効率的に操作する方法

2024-06-13

date-fns の Year Helpers における subYears 関数の詳細解説

date-fns ライブラリに搭載されている subYears 関数は、指定された日付から指定された年数分の期間を減算する機能を提供します。具体的には、以下の操作を行います。

  1. 入力された日付を受け取り、内部的に JavaScript の Date オブジェクトに変換します。
  2. 指定された年数分のミリ秒数を計算します。
  3. 計算されたミリ秒数を Date オブジェクトから減算します。
  4. 減算後の新しい日付を Date オブジェクトとして返します。

具体的な使い方

import { subYears } from 'date-fns';

const startDate = new Date(2024, 5, 12); // 2024年6月12日
const subtractedDate = subYears(startDate, 2); // 2022年6月12日

console.log(subtractedDate); // 2022-06-12T00:00:00.000Z

上記コードでは、startDate という変数に 2024年6月12日の日付を代入し、subYears 関数を使用して 2 年前の日付を計算しています。結果として、subtractedDate 変数には 2022年6月12日の日付が格納されます。

オプションパラメータ

subYears 関数は、オプションパラメータとして baseDate を受け取ることができます。baseDate は、減算の基点となる日付を指定します。デフォルトでは、現在の日付が使用されます。

import { subYears } from 'date-fns';

const startDate = new Date(2024, 5, 12);
const baseDate = new Date(2023, 1, 1); // 2023年1月1日
const subtractedDate = subYears(startDate, 2, baseDate); // 2021年1月1日

console.log(subtractedDate); // 2021-01-01T00:00:00.000Z

補足

  • subYears 関数は、日付の加減算のみを行うため、時間や分などの情報はそのままで維持されます。
  • 閏年を考慮した計算が行われます。
  • 無効な日付や不正なパラメータが渡された場合は、TypeError 例外がスローされます。
    • date-fns ライブラリには、addYearssetYear などの Year Helpers 関数が用意されています。これらの関数は、それぞれ異なる操作を行うため、用途に合わせて使い分けることができます。
    • date-fns ライブラリは、npm や yarn などのパッケージマネージャーを使用してインストールすることができます。


    subYears 関数の応用例

    特定の年の1月1日を計算

    import { subYears, startOfYear } from 'date-fns';
    
    const targetYear = 2020;
    const targetDate = subYears(startOfYear(new Date()), targetYear - 2024);
    
    console.log(targetDate); // 2020-01-01T00:00:00.000Z
    

    このコードでは、targetYear 変数に 2020 という値を代入し、subYears 関数と startOfYear 関数を使用して、2020年の1月1日の日付を計算しています。

    import { subYears, lastDayOfMonth } from 'date-fns';
    
    const targetYear = 2022;
    const targetMonth = 12; // 12 = 12月
    const targetDate = subYears(lastDayOfMonth(new Date(targetYear, targetMonth - 1)), 1);
    
    console.log(targetDate); // 2021-12-31T00:00:00.000Z
    

    このコードでは、targetYear 変数に 2022 という値を代入し、targetMonth 変数に 12 (12月は12番目の月) という値を代入し、subYears 関数と lastDayOfMonth 関数を使用して、2022年12月31日の日付を計算しています。

    特定の曜日の日付を計算

    import { subYears, getDay } from 'date-fns';
    
    const targetDay = 3; // 3 = 火曜日
    const targetDate = subYears(new Date(), 1);
    const desiredDate = subYears(targetDate, getDay(targetDate) - targetDay);
    
    console.log(desiredDate); // 2023-06-06T00:00:00.000Z
    


    以下に、subYears 関数の代替方法として考えられる選択肢をいくつかご紹介します。

    JavaScript の組み込み関数を使用する

    JavaScript には、日付を操作するための組み込み関数がいくつか用意されています。例えば、以下のコードは subYears 関数と同等の処理を setDate 関数を使用して実現しています。

    const startDate = new Date(2024, 5, 12);
    const subtractedDate = new Date(startDate.setDate(startDate.getDate() - 365 * 2));
    
    console.log(subtractedDate); // 2022-06-12T00:00:00.000Z
    

    上記コードでは、startDate オブジェクトから 2 年前の日付を計算するために、setDate メソッドを使用して startDate オブジェクトの日付を 2 年分減算しています。

    Moment.js などのライブラリを使用する

    date-fns ライブラリ以外にも、Moment.js などの日付操作ライブラリは数多く存在します。これらのライブラリは、date-fns ライブラリにはない機能を提供している場合もあるため、状況に合わせて使い分けることができます。

    Moment.js で subYears 関数と同等の処理を行う場合は、以下のコードのように subtract メソッドを使用することができます。

    const moment = require('moment');
    
    const startDate = moment('2024-06-12');
    const subtractedDate = startDate.subtract(2, 'years');
    
    console.log(subtractedDate.format('YYYY-MM-DD')); // 2022-06-12
    

    カスタムロジックを実装する

    上記の方法で解決できない場合は、カスタムロジックを実装する方法も考えられます。例えば、以下のように for ループを使用して 1 日ずつ減算していく方法があります。

    const startDate = new Date(2024, 5, 12);
    const subtractedDate = new Date(startDate);
    
    for (let i = 0; i < 365 * 2; i++) {
      subtractedDate.setDate(subtractedDate.getDate() - 1);
    }
    
    console.log(subtractedDate); // 2022-06-12T00:00:00.000Z
    

    最適な方法の選択

    どの方法が最適かは、状況によって異なります。以下の点を考慮して選択してください。

    • シンプルさ: コードのシンプルさを重視する場合は、JavaScript の組み込み関数を使用するのがおすすめです。
    • 機能: より多くの機能が必要な場合は、Moment.js などのライブラリを使用する方が良いかもしれません。
    • パフォーマンス: 処理速度が重要な場合は、カスタムロジックを実装する方が効率的な場合があります。
    • 具体的な状況を教えていただければ、より適切な代替方法を提案することができます。