当年话下
我有这样的事情:<?phpfunction myDate(int $year, int $month, int $week): string { $firstDayDate = DateTime::createFromFormat('j-n-Y', '1-'.$month.'-'.$year); $firstDayDate->setTime(0,0); $firstMondayDate = (clone $firstDayDate)->modify('first monday of this month'); $modificator = $week - 2; if ($firstMondayDate->format('d') === $firstDayDate->format('d')) { $modificator++; } if ($modificator < 0) { return $firstDayDate->format('Y-m-d'); } $wantedWeekDate = (clone $firstMondayDate)->add(new DateInterval('P'.($modificator*7).'D')); return $wantedWeekDate->format('Y-m-d');}var_dump(myDate(2020, 7, 1),myDate(2020, 7, 2),myDate(2020, 7, 3),myDate(2020, 7, 4),myDate(2020, 7, 5),myDate(2020, 7, 6),myDate(2020, 8, 1),myDate(2020, 8, 2),myDate(2020, 8, 3),myDate(2020, 8, 4),myDate(2020, 8, 5),myDate(2020, 8, 6),myDate(2014, 12, 1),myDate(2014, 12, 2),myDate(2014, 12, 3));测试输出:string(10) "2020-07-01"string(10) "2020-07-06"string(10) "2020-07-13"string(10) "2020-07-20"string(10) "2020-07-27"string(10) "2020-08-03"string(10) "2020-08-01"string(10) "2020-08-03"string(10) "2020-08-10"string(10) "2020-08-17"string(10) "2020-08-24"string(10) "2020-08-31"string(10) "2014-12-01"string(10) "2014-12-08"string(10) "2014-12-15"
汪汪一只猫
这是我的解决方案:function firstDayOfWeekInMonth($year, $month, $week){ $firstOfMonth = strtotime("$year-$month-1"); $format = 'Y-m-d'; if ($week == 1) { return date($format, $firstOfMonth); } else { $secondsInOneDay = 60 * 60 * 24; $secondInOneWeek = $secondsInOneDay * 7; $dayNumberOfFirstOfMonth = date('w', $firstOfMonth); //eg Monday = 1, Tuesday = 2, etc. $offsetToStartOfWeek = ($dayNumberOfFirstOfMonth - 1) * $secondsInOneDay; // eg Monday is 0 days from Monday, Tuesday is 1 day from Monday etc. $startOfWeek1 = $firstOfMonth - $offsetToStartOfWeek; //could be in previous month $StartOfWeekN = $startOfWeek1 + ($week - 1) * $secondsInOneWeek; // week-2 is 1-week ahead of week-1's Monday return date($format, $StartOfWeekN); }}该算法使用自 Unix 纪元以来的秒数。这是一个整数,因此所有计算都是通过整数相加或相乘来完成的,这应该相当快。日期和整数之间的转换仅在函数开始和结束时发生一次。顺便说一句,当我指的是如此多不同的周/月的开始时,我发现为一周的开始找到有意义的名称是一个很大的挑战。为了进行比较,我使用了与布莱希的答案相同的测试:var_dump(firstDayOfWeekInMonth(2020, 7, 1),firstDayOfWeekInMonth(2020, 7, 2),firstDayOfWeekInMonth(2020, 7, 3),firstDayOfWeekInMonth(2020, 7, 4),firstDayOfWeekInMonth(2020, 7, 5),firstDayOfWeekInMonth(2020, 7, 6),firstDayOfWeekInMonth(2020, 8, 1),firstDayOfWeekInMonth(2020, 8, 2),firstDayOfWeekInMonth(2020, 8, 3),firstDayOfWeekInMonth(2020, 8, 4),firstDayOfWeekInMonth(2020, 8, 5),firstDayOfWeekInMonth(2020, 8, 6),firstDayOfWeekInMonth(2014, 12, 1),firstDayOfWeekInMonth(2014, 12, 2),firstDayOfWeekInMonth(2014, 12, 3));string(10) "2020-07-01"string(10) "2020-07-06"string(10) "2020-07-13"string(10) "2020-07-20"string(10) "2020-07-27"string(10) "2020-08-03"string(10) "2020-08-01"string(10) "2020-08-03"string(10) "2020-08-10"string(10) "2020-08-17"string(10) "2020-08-24"string(10) "2020-08-31"string(10) "2014-12-01"string(10) "2014-12-08"string(10) "2014-12-15"