2017/10/11
PHPの日付演算を改良してみる
はじめに
PHPの日付演算に於いて、下記のような言語仕様があります。
1月31日の一ヶ月後 → 3月2日
1月31日の一ヶ月後は2月31日、、、ですが存在しません。
なので自動的に足りない2日間を翌月の繰り越すというふうになっています。
しかし、これでは月末処理などの際にとても困る!と言ったことがあることへの対応です。
対応策
ただしこれは未来の日付なので加減算ではなく加算に対してのみ有効です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public static function addMonth($dd, $int) { // 初日 $first = date('Y-m-1', strtotime($dd)); // 加算した初日 $calc_first = date('Y-m-d', strtotime($first." +".$int." month")); // 月のみ計算した仮の日にち $kari_yy = date('Y', strtotime($calc_first)); $kari_mm = date('m', strtotime($calc_first)); $kari_date_str = $kari_yy."-".$kari_mm."-".date('d', strtotime($dd)); $ret = $kari_date_str; if ($kari_date_str != date('Y-m-d', strtotime($kari_date_str))) { $ff = date('Y-m-1', strtotime($dd.' +'.$int.' month')); $last = date('Y-m-d', strtotime($ff.' -1 day')); $ret = $last; } return $ret; } |
どういう仕組みか
処理する日付を “YYYY-mm-dd” 形式の文字列で渡します。
それに対して何ヶ月足すかを一緒に関数に渡します。
前述で受け取った日付をAとします。何ヶ月後をzとします。
そのAを一旦ついたちにした日付Bを生成。
Bからzヶ月後をまず算出。1日は加算時はズレることがないので確実に正確なものが演算で取得出来ます。
これをCとする。
このCの日付のみAの日付に置き換えます。これをDとします。
例)
A : 2017-01-31
z : 1
B : 2017-01-01
C : 2017-02-01
D : 2017-02-31
この場合Dが存在しない日付となります。
PHPの演算を中継すると “2017-03-02” となってしまいますが、、、
このDと、演算後の2017-03-02が異なる場合だけ
「誤っているであろう”算出後の日付の前月末”」に設定するようにします。
今回の “2017-03-02” が求めるものではなかったため
“2017-03″の前月である”2017-02″の月末、、、つまり”2017-02-28″を求めることが出来ました。
概念としての抜け
ただし、この加算処理を繰り返していくことで
「月末がズレていってしまう!」
という「末日」という概念にまでは対応しきれていません。
これを考慮するには日付演算を使わずに「月末」というステータスを持つしかないのでは、といった所感です。
Author Profile
スターフィールド編集部
SHARE