2 回答

TA貢獻1890條經驗 獲得超9個贊
我有這樣的事情:
<?php
function 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"

TA貢獻1898條經驗 獲得超8個贊
這是我的解決方案:
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"
- 2 回答
- 0 關注
- 162 瀏覽
添加回答
舉報