次の○曜日 や 来週の○曜日 を取得する JavaScript

Pocket

JavaScript の標準組込みオブジェクトは、日時関連の処理が非常に貧弱だ。

次の水曜日は何月何日? とか、 来週の月曜日は何月何日? といった値を取得しようと思ったら、タイムゾーン周りの処理と合わさって、思いのほか面倒だった。

とりあえず、動くコードができたので、記事にして紹介する。

次の○曜日 を取得する関数:

/**
 * 「次の○曜日」を取得する
 * @param {Date} date 元となる日時
 * @param {number} dayOfWeek 曜日を示す 0-6 の値。 Date.prototype.getDay() と同様、 0 は日曜日を表す。
 * @param {{?includeToday: boolean}} option includeToday: 本日を含めるかどうかを指定する。省略時は false。
 * @returns {Date}
 */
function getNextDayOfWeek(date, dayOfWeek, option) {
    option = option || {};
    const includeToday = 'includeToday' in option ? option.includeToday : false;
    const retDate = new Date(date.valueOf());
    retDate.setDate(retDate.getDate() + (includeToday ? 0 : 1));
    retDate.setDate(retDate.getDate() + (7 - retDate.getDay() + dayOfWeek) % 7);
    return retDate;
}

// 実行例
console.log(
    [19,20,21,22,23,24,25,26,27,28,29]
        .flatMap(i => [new Date(`2021-07-${i}T00:00:00.000`), new Date(`2021-07-${i}T23:59:59.999`)])
        .map(d => `${d.toLocaleString('en-CA')} => ${getNextDayOfWeek(d, 3 /* Wednesday */, null).toLocaleString('en-CA')}`)
);

来週の○曜日 を取得する関数:

/**
 * 「来週の○曜日」を取得する
 * @param {Date} date 元となる日時
 * @param {number} dayOfWeek 曜日を示す 0-6 の値。 Date.prototype.getDay() と同様、 0 は日曜日を表す。
 * @param {{?weekStartDay: number}} option weekStartDay: 週の始まりの曜日を指定する。省略時は 0 (日曜)。
 * @returns {Date}
 */
function getDayOfNextWeek(date, dayOfWeek, option) {
    option = option || {};
    const weekStartDay = 'weekStartDay' in option ? option.weekStartDay : 0;
    const retDate = new Date(date.valueOf());
    retDate.setDate(retDate.getDate() + 1);
    retDate.setDate(retDate.getDate() + (7 - retDate.getDay() + weekStartDay) % 7 + (7 + dayOfWeek - weekStartDay) % 7);
    return retDate;
}

// 実行例
console.log(
    [19,20,21,22,23,24,25,26,27,28,29]
        .flatMap(i => [new Date(`2021-07-${i}T00:00:00.000`), new Date(`2021-07-${i}T23:59:59.999`)])
        .map(d => `${d.toLocaleString('en-CA')} => ${getDayOfNextWeek(d, 5 /* Friday */, {weekStartDay: 1 /* Monday */}).toLocaleString('en-CA')}`)
);

引数などの使い方は、 JSDoc コメントを参照してのこと。

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください