Get current week start/end date with DST

2019-08-31 11:45发布

I was using the following code for some months now without any issue in order to get the current week start/end date (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

However, as of Today this for some reason has been offset by 1 day:

//Actual incorrect result:
2018-10-28
2018-11-03

Then I remembered that Yesterday the clock went back 1 hour due to DST, so I decided to change the timezone from Europe/Bucharest to Europe/Istanbul which still has a +3 hours advance against GMT:

date_default_timezone_set('Europe/Istanbul');

//Now the result is correct: 
2018-10-29
2018-11-04

Question is, how can I offset DST in the current code so that I could keep the relative week dates in accordance with Europe/Bucharest timezone? Any pointers or explanations would be appreciated. Thank you.

3条回答
一纸荒年 Trace。
2楼-- · 2019-08-31 12:28

I am aware that there is more than one way to skin a cat, but in this case I was interested in how to fix my current code and more importantly to find out what's wrong with it.

Thank you all for your suggestions, especially to @misorude for pointing out the obvious flaw in my initial code, whereas "not every day has 86400 seconds", which is especially true during DST.

So here's the updated working code using relative "days" instead of fixed seconds amount:

$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

Once again, thank you all for your inputs. Much appreciated!

查看更多
▲ chillily
3楼-- · 2019-08-31 12:30

I would do this using the DateTime class and keep everything in UTC so you never have to worry about daylight savings time:

$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');

Output:

2018-10-29 
2018-11-04

Demo on 3v4l.org

查看更多
▲ chillily
4楼-- · 2019-08-31 12:45

If you just want to fix your current Code, just replace your three "ugly" ;-) lines:

$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");

with those "nice" one, and it will work.

$monday = strtotime('monday this week');
$sunday = strtotime('sunday this week');

PHPs relative Date Expressions can handle this nice.

查看更多
登录 后发表回答