strftime gets wrong date
Asked Answered
L

5

6

I'm using strftime to display future date.

But while using

strftime('%a., %d. %B %Y',time()+60*60*24*4)

I'm getting Mo., 01. April 2013 instead of Su., 31. March 2013 while using this today.

(Unix timestamp is 1364423120)

strftime('%a., %d. %B %Y',time()+60*60*24*3)

displays the correct Sa., 30. March 2013

What is wrong here with the last day of March?

Libb answered 27/3, 2013 at 22:29 Comment(5)
what is your server timezone :)? Look closer at this function/setting: php.net/manual/en/function.date-default-timezone-set.phpCurbing
@tkoomzaaskz is there any timezone where March 31st is missing? I don't think so ;)Chino
@Chino lousy Smarch weather...Barham
@tkoomzaaskz: server timezone is set to Europe/Berlin, but as gronostaj pointed out as well that is not important (check the Sa., 30. March against the Mo., 01. April).Libb
Bottom line: When adding days, do not forget that the length of the day is only 24 hours ON AVERAGE, with the occasional 23 or 25 hours for a day when daylight saving time is switched.Freestyle
G
5

The timestamp represents 23:25:20 local time. As daylight savings time comes into effect on March 31th, adding 96 h will give 00:25:20 as local time, thus a date one day later than expected. Using gmstrftime instead of strftime avoids this problem.

<?php

$timestamp = 1364423120;

echo strftime('%a., %d. %B %Y (%c %Z)', $timestamp)."\n";
echo strftime('%a., %d. %B %Y (%c %Z)', $timestamp +60*60*24*4)."\n";
echo gmstrftime('%a., %d. %B %Y (%c %Z)', $timestamp)."\n";
echo gmstrftime('%a., %d. %B %Y (%c %Z)', $timestamp +60*60*24*4)."\n";

gives

Wed., 27. March 2013 (Wed Mar 27 23:25:20 2013 CET)
Mon., 01. April 2013 (Mon Apr  1 00:25:20 2013 CEST)
Wed., 27. March 2013 (Wed Mar 27 22:25:20 2013 GMT)
Sun., 31. March 2013 (Sun Mar 31 22:25:20 2013 GMT)
Garda answered 27/3, 2013 at 22:52 Comment(2)
D: Thats's it: it's the daylight savings time that brought this confusion. Thanks a lot :)Libb
and thanks for suggesting gmstrftime(). Always sth. new to learn.Libb
B
1

Check your timezones.

Use the below code to see the time, timestamp, and timezone of the date produced by your code.

echo strftime('%s %H:%M:%S %z %Z %a., %d. %B %Y',time()+60*60*24*4);
//Output: 1364769859 15:44:19 -0700 PDT Sun., 31. March 2013

edit:

If this is indeed a problem with DST in your area [North America's change was a couple weeks ago], and you're only interested in the 'day' part of the date then I would advise using date_add() instead of simple arithmetic since it will take into account DST changes, and other peculiarities of timekeeping.

Barham answered 27/3, 2013 at 22:44 Comment(5)
He said tomorrow so I got confused.Charades
@Charades I have a habit of not really reading the wordy bits of questions. It seems to work out better more often than not.Barham
However, this basically is the same code as the OP has tried out. Does not answer the problem, except 'Check your timezones' which is really a comment.Charades
@Starx: Thanks for mentioning date_add(). That it helpful as well.Libb
Sorry, I meant @Sammitch: thanks for mentioning date_add(). It was a DST problem over here in europe/germany.Libb
C
1

According to the manual

strftime — Format a local time/date according to locale settings

Its better if you specify a locale while you are using it, to avoid such problem.

setlocale(LC_TIME, "de_DE");
strftime('%a., %d. %B %Y',time()+60*60*24*4)
Charades answered 27/3, 2013 at 22:51 Comment(0)
C
1

When I ran

echo strftime('%a., %d. %B %Y',time()+60*60*12*7)

I got

Sun., 31. March 2013

So this day truly exists :) I think it's connected to the daylight saving time change that happens on that day. And when you're using whole day (24 hours multiplying), you're skipping the timezone change.

Curbing answered 27/3, 2013 at 22:52 Comment(2)
Thank you for your effort. It was the daylight saving time. A quick fix for anyone reading this here is to use strtotime('12:00:00') instead of time().Libb
@Libb glad I could help. When dealing with time, you have to pay great attention to timezones ALWAYS. Even now - when you know what was the problem - remember that your timezone is - by default - the one set on your server. You can also set different timezone for logged in users (if your app provides such thing)Curbing
P
0

Terje D. correctly mentions the confusion that you were getting with DST. But I also wanted to mention a way to do it with DateTime, which in my personal opinion is easier to understand and use

$dt = new DateTime('now', new DateTimeZone('UTC')); // creates a datetime object representing the current time in UTC
$dt->modify('+3 days'); // add 3 days to the datetime object
echo $dt->format('Y-m-d H:i:s')."\n"; // This will give you the time in english independent of the locale settings on your server
echo strftime('%a., %d. %B %Y', $dt->getTimeStamp()); // this will give you the time in your locale, which as mentioned before, will include DST
Pulchia answered 24/9, 2015 at 15:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.