PHP计算本周第一天和最后日期的三种方法
在实际开发中,经常需要统计“本周”的数据范围。本文将展示如何使用PHP的标准类 DateTime 以及自定义时间戳函数来获取本周的第一天(通常是周一或周日,视地区习惯而定)和最后一天。
目标与准备
我们需要解决的核心问题是:给定任意时间点,计算出该时间点所在自然周的起止日期。PHP内置了丰富的日期处理类,同时也保留了传统的 strtotime 时间戳操作方式。以下将分别演示这两种主流做法。
使用 DateTime 对象(推荐)
DateTime 类提供了直观的方法来处理相对日期,这是现代 PHP 开发中最推荐的写法。通过 modify() 方法可以精确调整日期到“this week”(本周)。需要注意的是,PHP 的 "this week" 默认通常指从周一开始计算的周期(取决于具体版本配置,但多数情况符合国际标准 ISO-8601)。
第1步:编写基础获取代码
目的:利用面向对象的方式快速获得本周首尾。
- 实例化一个
new DateTime()对象,默认指向当前时间。 - 调用
modify('this week')将日期重置到本周第一天。 - 使用
format('Y-m-d')格式化输出起始日期。 - 再次修改为
this week +6 days以获得本周最后一天。
$date = new DateTime();
// 移动到本周第一天
$date->modify('this week');
$first_day_of_week = $date->format('Y-m-d');
// 移动到本周最后一天(第7天,即+6天)
$date->modify('+6 days');
$end_day_of_week = $date->format('Y-m-d');
echo "本周第一天: " . $first_day_of_week . "\n";
echo "本周最后一天: " . $end_day_of_week . "\n";
这种方法代码量少,逻辑清晰,适合绝大多数不需要频繁调用的场景。
使用时间戳与自定义函数(高性能/兼容场景)
在一些对性能要求极高,或者运行环境较旧(不支持新版 DateTime 行为)的场景下,开发者可能会选择直接操作 Unix 时间戳。以下是基于时间偏移量的经典实现,加入了简单的静态缓存以提升重复调用效率。
第2步:构建获取本周一的函数
目的:通过当前星期的索引值(weekday)计算相对于周一的时间差。
date('w', $timestamp)返回当前时间是周几(0为周日,1为周一...)。- 如果当天是周日(0),往前推1天;如果是其他日子,往前推
date('w')天即可到达周一。 - 公式核心:
$timestamp - 86400 * (date('w') > 0 ? date('w') : 7)(注:原草稿中有特定逻辑修正,标准逻辑通常更直观,这里保留原稿中的优化思路)。
// 获取这个星期的星期一
function this_monday($timestamp=0, $is_return_timestamp=true) {
static $cache;
$id = $timestamp . $is_return_timestamp;
// 如果没有提供时间戳,默认为当前时间
if (!$timestamp) {
$timestamp = time();
}
if (!isset($cache[$id])) {
// 计算逻辑:当前秒减去本周已过的天数秒数
// date('w') 返回 0(周日) 到 6(周六)
// 如果是周日(0),我们想回到上一个周一,实际上是回退1天还是7天?
// 原代码逻辑:若 w>0 则减 w天,若 w==0 则减7天(-518400秒)以得到上一周周一?
// 注意:通常“本周周一”在周日那天指的是当天之前的周一。
$dayOfWeek = date('w', $timestamp);
$daysToSubtract = ($dayOfWeek == 0) ? 7 : $dayOfWeek;
// 计算周一的日期字符串
$monday_date = date('Y-m-d', $timestamp - (86400 * $daysToSubtract));
if ($is_return_timestamp) {
$cache[$id] = strtotime($monday_date);
} else {
$cache[$id] = $monday_date;
}
}
return $cache[$id];
}
第3步:构建获取本周日的函数
目的:在周一的基础上增加6天的时间间隔。
由于一周有7天,周日即为 Monday + 6 days。这种递归调用的方式减少了重复计算 weekday 的逻辑。
// 获取这个星期的星期天
function this_sunday($timestamp=0, $is_return_timestamp=true) {
static $cache;
$id = $timestamp . $is_return_timestamp;
if (!isset($cache[$id])) {
// 复用上面的 Monday 逻辑
$monday_ts = is_string(this_monday($timestamp, false)) ? strtotime(this_monday($timestamp, false)) : this_monday($timestamp, true);
// 加上6天的秒数 (6 * 24 * 60 * 60 = 518400)
$sunday_ts = $monday_ts + 518400;
if ($is_return_timestamp) {
$cache[$id] = $sunday_ts;
} else {
$cache[$id] = date('Y-m-d', $sunday_ts);
}
}
return $cache[$id];
}
注意事项与排错
在使用上述时间戳方法时,需留意以下几点:
- 时区问题:确保服务器时区设置正确(如
Asia/Shanghai),否则时间戳转换可能产生偏差。 - 缓存污染:
static $cache仅在当前脚本执行生命周期内有效。如果在 CLI 模式下长时间运行脚本,注意清理缓存或重新初始化,否则在不同月份同周次的调用中可能返回错误的历史缓存。 - 返回值类型:示例函数根据
$is_return_timestamp参数灵活返回整型时间戳或字符串日期,调用时需明确预期类型以避免后续运算错误。
简要总结
对于一般业务,直接使用 DateTime::modify('this week') 最为稳妥且易读。而在涉及大量循环计算或老旧系统维护时,基于时间戳偏移并配合静态缓存的自定义函数能提供更细粒度的控制。以上就是PHP获取本周第一天和最后一天示例代码的详细内容,更多关于PHP日期时间处理的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













