php - Check if it is the first monday of a quarter

I want to run a script every 1st monday of a month in the windows scheduler. The script itself should check if it is the 1st monday of a quarter (not month). I know that I can somehow do it with date() or more like the DateTime-object, but I have no idea how to approach this.

An approach I had, even though I don't think that this is very reliable or "clean", is to put the specific months in an array like

// might as well use the numeric month representation...
$quarters = array("January", "April", "July", "October");

and check if it is the first monday of a month and check afterwards, if the current month is in the array quarters. However, feels like this isn't real clean.

If the script runs, it should simply print either: Today is the 1st monday of a quarter or do nothing. If I would run this job everyday, it should ~90 days do nothing and only once trigger with the given string. If I run it every monday, it should do 12 times nothing and also, only once, trigger.

Hope you can point me in the right direction.

Answer

Solution:

There are a few stages in this solution, I've added comments as they are probably useful in the end code...

$date = new DateTime();

// Calculate start month of quarter from date
$quarterMonth = (floor(($date->format('m') - 1) / 3) * 3) + 1;
// Set date from year, start quarter month and the 1st of the month
$date->setDate($date->format('Y'), $quarterMonth, 1);
// Set result to the first Monday on or after the date
$date->modify('first monday of this month');

echo $date->format('Y-m-d');

running that will give (as of date of answer)...

2021-01-04

Answer

Solution:

I would suggest building a relative date string such as first monday of january 2024 to construct the date:

$s1 = "2024-03-31";
$d1 = new DateTime($s1);

// the floor(...) expression below maps 1/2/3 to 0, 4/5/6 to 1 and so on
$yy = $d1->format("Y");
$mm = ["january", "april", "july", "october"][floor(($d1->format("n") - 1) / 3)];

$d2 = new DateTime("first monday of $mm $yy");
echo $d2->format("D Y-m-d H:i:s");

// result:
// Mon 2024-01-01 00:00:00

Answer

Solution:

Old school solution with date() and strtotime():

function isFirstMondayOfQuarter($date = 'today'){
  $ts = strtotime($date);
  if(date('n',$ts)%3 != 1) return false;
  return $ts === strtotime('first monday of this month',$ts);
}

var_dump(isFirstMondayOfQuarter());              //bool(false) at 10 Feb 2021
var_dump(isFirstMondayOfQuarter('2021-01-04'));  // bool(true)

Source