使用 DST 获取当前周 start/end 日期
Get current week start/end date with DST
为了获取本周 start/end 日期 (Monday/Sunday),我使用以下代码几个月没有任何问题:
date_default_timezone_set('Europe/Bucharest'); //this is the default in php.ini
$monday = strtotime('next Monday -1 week');
$monday = date('w', $monday)==date('w') ? $monday+7*86400 : $monday;
$sunday = strtotime(date("Y-m-d",$monday)." +6 days");
echo "Current week start/end date:<br>";
echo $this_week_sd = date("Y-m-d",$monday)."<br>";
echo $this_week_ed = date("Y-m-d",$sunday)."<br>";
//Expected result:
2018-10-29
2018-11-04
但是,截至今天,由于某种原因,这已被抵消 1 天:
//Actual incorrect result:
2018-10-28
2018-11-03
然后我想起昨天由于夏令时时钟倒退了 1 小时,所以我决定将时区从 Europe/Bucharest 更改为 Europe/Istanbul,这仍然比格林威治标准时间提前 +3 小时:
date_default_timezone_set('Europe/Istanbul');
//Now the result is correct:
2018-10-29
2018-11-04
问题是,如何在当前代码中偏移 DST,以便使相对周日期与 Europe/Bucharest 时区保持一致?任何指示或解释将不胜感激。谢谢。
我会使用 DateTime
class 并将所有内容保存在 UTC
中,这样您就不必担心夏令时了:
$today = new DateTime('now', new DateTimeZone('UTC'));
$day_of_week = $today->format('w');
$today->modify('- ' . (($day_of_week - 1 + 7) % 7) . 'days');
$sunday = clone $today;
$sunday->modify('+ 6 days');
echo $today->format('Y-m-d') . "\n";
echo $sunday->format('Y-m-d');
输出:
2018-10-29
2018-11-04
如果您只想修复当前的代码,只需替换您的三个 "ugly" ;-) 行:
$monday = strtotime('next Monday -1 week');
$monday = date('w', $monday)==date('w') ? strtotime(date("Y-m-d",$monday)." +7 days") : $monday;
$sunday = strtotime(date("Y-m-d",$monday)." +6 days");
使用那些 "nice" 一个,它会起作用。
$monday = strtotime('monday this week');
$sunday = strtotime('sunday this week');
PHP 的相关日期表达式可以很好地处理这个问题。
我知道给猫剥皮的方法不止一种,但在这种情况下,我感兴趣的是如何修复我当前的代码,更重要的是找出它有什么问题。
感谢大家的建议,特别是@misorude 指出了我初始代码中的明显缺陷,而 "not every day has 86400 seconds",夏令时期间尤其如此。
所以这是使用相对 "days" 而不是固定秒数的更新工作代码:
$monday = strtotime('next Monday -1 week');
$monday = date('w', $monday)==date('w') ? strtotime(date("Y-m-d",$monday)." +7 days") : $monday;
$sunday = strtotime(date("Y-m-d",$monday)." +6 days");
echo "This week start/end date:<br>";
echo $this_week_sd = date("Y-m-d",$monday)."<br>";
echo $this_week_ed = date("Y-m-d",$sunday)."<br>";
//output:
This week start/end date:
2018-10-29
2018-11-04
再次感谢大家的投入。非常感谢!
为了获取本周 start/end 日期 (Monday/Sunday),我使用以下代码几个月没有任何问题:
date_default_timezone_set('Europe/Bucharest'); //this is the default in php.ini
$monday = strtotime('next Monday -1 week');
$monday = date('w', $monday)==date('w') ? $monday+7*86400 : $monday;
$sunday = strtotime(date("Y-m-d",$monday)." +6 days");
echo "Current week start/end date:<br>";
echo $this_week_sd = date("Y-m-d",$monday)."<br>";
echo $this_week_ed = date("Y-m-d",$sunday)."<br>";
//Expected result:
2018-10-29
2018-11-04
但是,截至今天,由于某种原因,这已被抵消 1 天:
//Actual incorrect result:
2018-10-28
2018-11-03
然后我想起昨天由于夏令时时钟倒退了 1 小时,所以我决定将时区从 Europe/Bucharest 更改为 Europe/Istanbul,这仍然比格林威治标准时间提前 +3 小时:
date_default_timezone_set('Europe/Istanbul');
//Now the result is correct:
2018-10-29
2018-11-04
问题是,如何在当前代码中偏移 DST,以便使相对周日期与 Europe/Bucharest 时区保持一致?任何指示或解释将不胜感激。谢谢。
我会使用 DateTime
class 并将所有内容保存在 UTC
中,这样您就不必担心夏令时了:
$today = new DateTime('now', new DateTimeZone('UTC'));
$day_of_week = $today->format('w');
$today->modify('- ' . (($day_of_week - 1 + 7) % 7) . 'days');
$sunday = clone $today;
$sunday->modify('+ 6 days');
echo $today->format('Y-m-d') . "\n";
echo $sunday->format('Y-m-d');
输出:
2018-10-29
2018-11-04
如果您只想修复当前的代码,只需替换您的三个 "ugly" ;-) 行:
$monday = strtotime('next Monday -1 week');
$monday = date('w', $monday)==date('w') ? strtotime(date("Y-m-d",$monday)." +7 days") : $monday;
$sunday = strtotime(date("Y-m-d",$monday)." +6 days");
使用那些 "nice" 一个,它会起作用。
$monday = strtotime('monday this week');
$sunday = strtotime('sunday this week');
PHP 的相关日期表达式可以很好地处理这个问题。
我知道给猫剥皮的方法不止一种,但在这种情况下,我感兴趣的是如何修复我当前的代码,更重要的是找出它有什么问题。
感谢大家的建议,特别是@misorude 指出了我初始代码中的明显缺陷,而 "not every day has 86400 seconds",夏令时期间尤其如此。
所以这是使用相对 "days" 而不是固定秒数的更新工作代码:
$monday = strtotime('next Monday -1 week');
$monday = date('w', $monday)==date('w') ? strtotime(date("Y-m-d",$monday)." +7 days") : $monday;
$sunday = strtotime(date("Y-m-d",$monday)." +6 days");
echo "This week start/end date:<br>";
echo $this_week_sd = date("Y-m-d",$monday)."<br>";
echo $this_week_ed = date("Y-m-d",$sunday)."<br>";
//output:
This week start/end date:
2018-10-29
2018-11-04
再次感谢大家的投入。非常感谢!