LoginSignup
0
0

More than 1 year has passed since last update.

JavaScript/PHP 月末付近でも月を繰り上げずに○か月増減した日付を取得

Last updated at Posted at 2021-08-17

例えばJavaScriptで8月31日の1か月後を取得しようとして

const date = new Date('2021/08/31');
date.setMonth(date.getMonth() + 1);

としても、9月は30日までしかないので月が繰り上がり、実際に得られる日付は10月1日になってしまいますが、そのような日数の異なる月を目標月とした場合でも末日で丸めた9月30日として取得できるようにした関数です。

JavaScript/PHP版ともに、目標月+1月の0日を指定することで一旦目標月の末日にし、得られた末日と元の日付の「日」のうち小さいほうで「日」を再設定することで求めたい日付を取得しています。

JavaScript版

function addMonth(date, num) {
  const d = new Date(date);
  d.setMonth(d.getMonth() + num + 1, 0);
  d.setDate(Math.min(d.getDate(), date.getDate()));
  return d;
}

// sample
const baseDate = new Date('2021/08/31');
console.log('base date :', baseDate.toLocaleDateString('ja'), "\n");

for(let i = -12; i <= 12; i++) {
  const r = addMonth(baseDate, i);
  console.log('%s month : %s',
    `${(i < 0 ? i : `+${i}`)}`.padStart(3), r.toLocaleDateString('ja'));
}

/*
  base date : 2021/8/31

  -12 month : 2020/8/31
  -11 month : 2020/9/30
  -10 month : 2020/10/31
   -9 month : 2020/11/30
   -8 month : 2020/12/31
   -7 month : 2021/1/31
   -6 month : 2021/2/28
   -5 month : 2021/3/31
   -4 month : 2021/4/30
   -3 month : 2021/5/31
   -2 month : 2021/6/30
   -1 month : 2021/7/31
   +0 month : 2021/8/31
   +1 month : 2021/9/30
   +2 month : 2021/10/31
   +3 month : 2021/11/30
   +4 month : 2021/12/31
   +5 month : 2022/1/31
   +6 month : 2022/2/28
   +7 month : 2022/3/31
   +8 month : 2022/4/30
   +9 month : 2022/5/31
  +10 month : 2022/6/30
  +11 month : 2022/7/31
  +12 month : 2022/8/31
*/

PHP版

<?php
function addMonth($date, $num) {
  $d = (new DateTime)->setTimestamp($date->getTimestamp());
  $d->setDate($d->format('Y'), $d->format('m') + $num + 1, 0)
    ->setDate($d->format('Y'), $d->format('m'), min($d->format('d'), $date->format('d')));
  return (new DateTimeImmutable)->setTimestamp($d->getTimestamp());
}

// sample
$baseDate = (new DateTimeImmutable)->setDate(2021, 8, 31);
echo "base date : {$baseDate->format('Y-m-d')}\n\n";

for($i = -12; $i <= 12; $i++) {
  $r = addMonth($baseDate, $i);
  printf("%+3d month : %s\n", $i, $r->format('Y-m-d'));
}

// result
/*
  base date : 2021-08-31

  -12 month : 2020-08-31
  -11 month : 2020-09-30
  -10 month : 2020-10-31
   -9 month : 2020-11-30
   -8 month : 2020-12-31
   -7 month : 2021-01-31
   -6 month : 2021-02-28
   -5 month : 2021-03-31
   -4 month : 2021-04-30
   -3 month : 2021-05-31
   -2 month : 2021-06-30
   -1 month : 2021-07-31
   +0 month : 2021-08-31
   +1 month : 2021-09-30
   +2 month : 2021-10-31
   +3 month : 2021-11-30
   +4 month : 2021-12-31
   +5 month : 2022-01-31
   +6 month : 2022-02-28
   +7 month : 2022-03-31
   +8 month : 2022-04-30
   +9 month : 2022-05-31
  +10 month : 2022-06-30
  +11 month : 2022-07-31
  +12 month : 2022-08-31
*/

引き数
addMonth(日付オブジェクト, 月の増減値)

戻り値
指定した値で月を増減された日付オブジェクト

引き数チェックは入れていませんので必要に応じて追加してください。


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0