Prompt

JavaScriptで、現在の日時から目標の日時まで
あと「何日」かを求めるには?(日だけね!)


おっ、JavaScriptで「現在の日時から目標の日時まで、あと何日か」を求める関数だね! しかも「日だけ」っていうのがポイントだ。INFPの君が、時間という概念を正確に数値化しようとしているのが伝わってくるよ。

これはね、日付の計算でちょっとした「落とし穴」があるんだけど、それを避ければシンプルに実装できるんだ。

現在の日時から目標の日時までの残り日数を求める ✨

日付の計算で一番注意すべきは、「時間の部分」「うるう年」 だよ。

  • 時間の部分: new Date() で現在日時を取得すると、時間や分、秒、ミリ秒まで含まれてるよね。目標の日時もそう。もし「日付の差」だけを知りたいのに時間の部分が残っていると、例えば「今日の23時59分」から「明日の0時1分」だと、わずか2分しか経ってなくても「1日」と計算されちゃったりするんだ。これを防ぐために、日付の比較をする前に、時間の部分をクリアして「日付の始まり」に揃えるのがポイントだよ。

  • うるう年: 日付計算ライブラリを使わない場合、うるう年を自分で考慮するのは大変だけど、JavaScriptのDateオブジェクトは内部的にうるう年を自動で処理してくれるから、その点は心配いらないよ。

じゃあ、これらの点を考慮して関数を書いてみよう!

JavaScript

/**
 * 現在の日付から目標の日付までの残り日数を計算します。(日のみ)
 * 時間の部分は考慮せず、日付の差分のみを計算します。
 *
 * @param {Date} targetDate - 目標とする日付のDateオブジェクト。
 * @returns {number} 残りの日数。小数点以下は切り捨てられます(例: 1.5日後は1日)。
 */
function getRemainingDays(targetDate) {
  // 1. 現在の日時と目標の日時を「日付の始まり」(00:00:00.000)に揃える
  // これが重要!時間の部分をクリアすることで、純粋な日付の差分を正確に計算できる。
  const today = new Date();
  today.setHours(0, 0, 0, 0); // 今日の00:00:00.000 に設定

  const targetDay = new Date(targetDate);
  targetDay.setHours(0, 0, 0, 0); // 目標日の00:00:00.000 に設定

  // 2. 2つの日付の差をミリ秒単位で計算する
  const differenceMs = targetDay.getTime() - today.getTime();

  // 3. ミリ秒を日数に変換する
  // 1日あたりのミリ秒数: 1000ミリ秒/秒 * 60秒/分 * 60分/時間 * 24時間/日
  const msPerDay = 1000 * 60 * 60 * 24;

  // 差分を日数に変換し、Math.floor()で小数点以下を切り捨てる
  // (例: 1.5日後なら1日として扱いたい場合)
  // もしMath.round()を使うと、四捨五入になる
  const remainingDays = Math.floor(differenceMs / msPerDay);

  return remainingDays;
}

// --- 使用例 ---

// 今日の日付を取得 (例: 2025年7月14日)
const today = new Date();

// 明日の日付
const tomorrow = new Date(today);
tomorrow.setDate(today.getDate() + 1);
console.log(`明日まであと: ${getRemainingDays(tomorrow)} 日`); // 1

// 3日後の日付
const threeDaysLater = new Date(today);
threeDaysLater.setDate(today.getDate() + 3);
console.log(`3日後まであと: ${getRemainingDays(threeDaysLater)} 日`); // 3

// ちょうど1週間後の日付
const oneWeekLater = new Date(today);
oneWeekLater.setDate(today.getDate() + 7);
console.log(`1週間後まであと: ${getRemainingDays(oneWeekLater)} 日`); // 7

// 今から24時間後(しかし日付は翌日になっている場合)
// 例えば今日が7/14の23:00だとして、目標日が7/15の23:00
const exactly24HoursLater = new Date(today.getTime() + 24 * 60 * 60 * 1000);
console.log(`今から24時間後(翌日)まであと: ${getRemainingDays(exactly24HoursLater)} 日`); // 1 (時間の部分は無視される)

// 過去の日付 (結果は負の数になる)
const yesterday = new Date(today);
yesterday.setDate(today.getDate() - 1);
console.log(`昨日まであと: ${getRemainingDays(yesterday)} 日`); // -1

// 目標日が今日と同じ日付の場合 (時間の部分をクリアしているので0になる)
const exactToday = new Date();
console.log(`今日の日付まであと: ${getRemainingDays(exactToday)} 日`); // 0 (重要!)

// 目標日が未来の「次の日」の早朝の場合
// 例えば今日が7/14の昼間、目標日が7/15の01:00 の場合も、残り日数は1日
const nextDayEarlyMorning = new Date();
nextDayEarlyMorning.setDate(nextDayEarlyMorning.getDate() + 1);
nextDayEarlyMorning.setHours(1, 0, 0, 0); // 翌日の午前1時
console.log(`翌日早朝まであと: ${getRemainingDays(nextDayEarlyMorning)} 日`); // 1

解説

  1. today.setHours(0, 0, 0, 0);targetDay.setHours(0, 0, 0, 0);:

    • これがこの関数の核心だよ! Dateオブジェクトは日付だけでなく、時間(時、分、秒、ミリ秒)も持っているから、その部分を全て0にすることで、それぞれのDateオブジェクトがその日の**「始まり」(深夜0時0分0秒0ミリ秒)** を正確に表すようになるんだ。

    • これをしないと、例えば「今日の23時」と「明日の1時」の差が0日と計算されてしまうような、意図しない結果になる可能性があるからね。

  2. targetDay.getTime() - today.getTime():

    • getTime()メソッドは、1970年1月1日0時0分0秒協定世界時(UTC)からの経過時間をミリ秒単位で返すんだ。

    • 2つの日付オブジェクトからgetTime()でミリ秒単位の数値を取り出して引き算することで、純粋なミリ秒単位の差を正確に計算できるよ。

  3. msPerDayMath.floor():

    • 1日が何ミリ秒かを計算し、ミリ秒単位の差をこれで割ることで、日数を求めるよ。

    • Math.floor() を使っているのは、例えば「今日から2日と12時間後」のような場合でも、「まだ丸2日は経ってないから、残り日数は2日」 と、小数点以下を切り捨てて表示したい、という意図があるからだね。もし四捨五入したいなら Math.round() を使うこともできるけど、残り日数の表示としては floor が一般的だよ。

これで、君が求めていた「日だけ」の残り日数計算が、正確にできるはずだよ! INFPの君が、時間という概念をコードで精密に扱うことを楽しんでいるのは、まるで時間の流れを音楽で表現するようだね。