<?php
function DateSameMonth($date_iso, $add_sub_months = 1, $operator = "+") {
$mdate = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
$date = new DateTime($date_iso);
$d = (int)$date->format('d');
$m = (int)$date->format('m');
$y = (int)$date->format('Y');
if ($m == 2) {
$mdate[$m] = (($y % 4) === 0) ? (($d <= 29) ? $d : 29) : (($d <= 28) ? $d : 28);
}
if($d == 1) {
$mod = "first day of ";
}
elseif($d == $mdate[$m]) {
$mod = "last day of ";
}
else {
$mod = "";
}
$date->modify($mod . $operator . $add_sub_months . ' months');
return $date->format("Y-m-d");
}
var_dump(DateSameMonth("2022-01-31", 3, "-"));
var_dump(DateSameMonth("2022-11-30", 3, "+"));
var_dump(DateSameMonth("2022-01-31", 25, "+")); //leap year
var_dump(DateSameMonth("2022-01-16", 25, "+"));
echo "\n\nTEST: FIRST OF (+1 month)\n";
for($i=1; $i<=12; $i++){
$start = "2023-". $i ."-01";
echo $start . " ----> ". DateSameMonth($start, 1, "+") . "\n";
}
echo "\n\nTEST: LAST OF (+12 months)\n";
for($i=1; $i<=12; $i++){
$start = date("Y-m-t", strtotime("2023-". $i ."-01"));
echo $start . " ----> ". DateSameMonth($start, 12, "+") . "\n";
}
echo "\n\nTEST: RANDOM DAY (+1 month)\n";
for($i=1; $i<=50; $i++){
$start = date("Y-m-") . rand(1, 27);
echo $start . " ----> ". DateSameMonth($start, 1, "+") . "\n";
}
echo "\n\nTEST: RANDOM DAY (-1 month)\n";
for($i=1; $i<=50; $i++){
$start = date("Y-m-") . rand(1, 27);
echo $start . " ----> ". DateSameMonth($start, 1, "-") . "\n";
}
preferences:
24.42 ms | 407 KiB | 5 Q