首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 獲取某年週數及每週起止日期的兩種實現方法

     編輯:PHP 綜合知識

需求分析

根據 ISO-8601 標準,一年有 52 或 53 週,週一為每週第一天。需求:獲取指定年份總週數、指定週的起止日期、當前日期所屬週範圍。

方法一:date('W') + strtotime(簡潔實用)

function getYearWeeks($year) {
    // 12 月 28 日必在該年第 52 或 53 週
    return (int)date('W', strtotime("$year-12-28"));
}

function getWeekRange($year, $week) {
    $weeks = getYearWeeks($year);
    if ($week < 1 || $week > $weeks) $week = 1;
    $week = str_pad($week, 2, '0', STR_PAD_LEFT);

    // ISO 週日期格式:YYYY-Www
    $start = strtotime("$year-W$week");           // 週一 00:00:00
    $end   = strtotime("+6 days", $start);        // 週日 23:59:59

    return [
        'start_ts' => $start,
        'end_ts'   => $end,
        'start'    => date('Y-m-d', $start),
        'end'      => date('Y-m-d', $end),
    ];
}

// 示例
echo "2023 年共 " . getYearWeeks(2023) . " 週\n"; // 52
print_r(getWeekRange(2023, 1));
/* Array(
    [start_ts] => 1672502400
    [end_ts]   => 1673020799
    [start]    => 2023-01-02
    [end]      => 2023-01-08
) */

方法二:DateTime 面向對象(更健壯、支持時區)

function getIsoWeeksInYear($year) {
    $dt = new DateTime();
    $dt->setISODate($year, 53); // 嘗試設置第 53 週
    return $dt->format('W') === '53' ? 53 : 52;
}

function getWeekRangeDT($year, $week, $timezone = 'Asia/Shanghai') {
    $dt = new DateTime(null, new DateTimeZone($timezone));
    $dt->setISODate($year, $week); // 自動校正週數
    $dt->setTime(0, 0, 0);
    $start = clone $dt;
    $end = clone $dt;
    $end->modify('+6 days')->setTime(23, 59, 59);

    return [
        'start' => $start->format('Y-m-d'),
        'end'   => $end->format('Y-m-d'),
        'start_ts' => $start->getTimestamp(),
        'end_ts'   => $end->getTimestamp(),
    ];
}

// 獲取當前日期所屬週範圍
function getCurrentWeekRange($timezone = 'Asia/Shanghai') {
    $dt = new DateTime(null, new DateTimeZone($timezone));
    $year = (int)$dt->format('o'); // ISO 年份
    $week = (int)$dt->format('W');
    return getWeekRangeDT($year, $week, $timezone);
}

關鍵差異對比

特性date/strtotimeDateTime
時區處理依賴 date_default_timezone_set對象級時區,互不干擾
跨年週處理需手動邏輯setISODate 自動處理
性能極快略慢(對象開銷)
可讀性字符串魔法語義清晰
推薦場景簡單腳本、高頻調用框架項目、多時區、國際化

完整工具類封裝

class WeekHelper {
    public static function weeksInYear($year) {
        $dt = new DateTime();
        $dt->setISODate($year, 53);
        return $dt->format('W') === '53' ? 53 : 52;
    }

    public static function range($year, $week, $tz = 'Asia/Shanghai') {
        $dt = new DateTime(null, new DateTimeZone($tz));
        $dt->setISODate($year, $week);
        $dt->setTime(0,0,0);
        $s = clone $dt;
        $e = clone $dt;
        $e->modify('+6 days')->setTime(23,59,59);
        return [
            'year' => $year, 'week' => $week,
            'start' => $s->format('Y-m-d'), 'end' => $e->format('Y-m-d'),
            'start_ts' => $s->getTimestamp(), 'end_ts' => $e->getTimestamp(),
        ];
    }

    public static function current($tz = 'Asia/Shanghai') {
        $dt = new DateTime(null, new DateTimeZone($tz));
        return self::range((int)$dt->format('o'), (int)$dt->format('W'), $tz);
    }
}

// 使用
print_r(WeekHelper::current());
print_r(WeekHelper::range(2024, 1));
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved