I'm trying to write a bit of php to determine the date (Y-m-d format) for the next occurrence of a given weekday.
date('Y-m-d', strtotime('next monday'));
is returning
2011-08-29
instead of
2011-08-22
on my server. Not sure why. My server is an EC2 instance in Amazon's US East-Coast data center and it's currently 2011-08-21 9:40:00.
EDIT 1
Also date('Y-m-d', strtotime('next sunday')); returns 2011-08-28 instead of today. I tried out this code on http://writecodeonline.com/php/ ... beginning to think that tester is inaccurate.
Just because your server is set to a certain timezone doesn't necessarily mean PHP will be acting on the same timezone. It is already Monday, August 22, 2011 in Europe, which also includes UTC. If your PHP is acting on this timezone, "next Monday" would be Aug. 29.
You should double-check your timezone settings in PHP. You can either run date_default_timezone_get() to check what settings your installation is using, or try forcing your PHP script to use the timezone you expect with date_default_timezone_set("America/New_York"); and seeing if you get the result you expect.
I just tested this:
date_default_timezone_set("America/New York");
echo date('Y-m-d', strtotime('next monday')); // prints 2011-08-22
date_default_timezone_set("UTC");
echo date('Y-m-d', strtotime('next monday')); // prints 2011-08-29
I think that's the expected behaviour, since Monday hasn't passed strtotime sees it as the Next Monday.
Which version of PHP are you using? In some versions of PHP strtotime does have a buggy behavior.
I found that in strtotime manual page:
5.0.2 In PHP 5 up to 5.0.2, "now" and other relative times are wrongly computed from today's midnight. This differs from other versions where it is correctly computed from current time.
5.0.0 Microseconds began to be allowed, but they are ignored.
4.4.0 In PHP versions prior to 4.4.0, "next" is incorrectly computed as +2. A typical solution to this is to use "+1".
Your described behavior suggests that you have a version between 5.0 and 5.0.2.
I suggest you to check whether the difference between today and the computed "next monday" is higher than 7 days. If it is, subtract 7 days and you have the actual date.
Try using that code:
$days = ((strtotime('next monday') - time()) / 60 / 60 / 24);
if ($days >= 8) {
$days -= 7;
}
I know there is date_diff function, but if your PHP version is so low as I think, it isn't available for you (sorry, only 5.3.0 and higher).
"Next", when used with weekdays, generally means the first one after the next closest one. For example if today is Sunday the 21st then the "next" Monday is not tomorrow the 22nd but the following Monday the 29th.
I know this is not necessarily intuitive and not recognized universally but I believe that that is how strtotime() interprets "next".
EDIT: I have confirmed via my own tests that I am incorrect and that "next" should return the first upcoming weekday (the 22nd in my example above). I will leave this answer here unedited as it and the comment below may be helpful to others.
Related
I'm working on a PHP function which calculates holidays:
function holidays($country = 1, $timespan_start = 0, $timespan_end = 0)
The holidays are returned as timestamps in an array.
Since I have to calculate dates like the first Monday of February, I tried strtotime("first monday february $year") and I've discovered that this does not work for 2010, since 02/01/2010 is a Monday - I get February 8th instead.
This bug is actually mentioned in the change log:
In PHP 5 prior to 5.2.7, requesting a given occurrence of a given weekday in a month where that weekday was the first day of the month would incorrectly add one week to the returned timestamp. This has been corrected in 5.2.7 and later versions.
But I'm using PHP 5.3.8.
Why am I experiencing this error?
Looks like you are just missing an "of":
echo date('Y-m-d', strtotime('first monday of february 2010'));
will give the expected result. See the PHP Manual on Relative dates for the various input formats.
Depending on your version of PHP the 'of' statement may or may not work. As another solution try:
echo date('Y-m-d',strtotime('monday February 2010'));
will return the first monday of February 2010. Works for all days as well.
Currently I am using the following to get the date of monday and friday of this and next week.
$curWeekStart = date('d.m', strtotime('monday this week'));
$curWeekEnd = date('d.m', strtotime('friday this week'));
$nextWeekStart = date('d.m', strtotime('monday next week'));
$nextWeekEnd = date('d.m', strtotime('friday next week'));
All works fine until the day "sunday" comes, like today.. then this things above only show me monday and not other days. Tuesday, Wednesday, Thursday, Friday ecc are not working, it is only returning me monday. This error happens only on sundays and not on other days.
That's the output:
$curWeekStart == 13.03;
$curWeekEnd == 13.03;
$nextWeekStart == 20.03;
$nextWeekEnd == 20.03;
Does anyone have an idea how to solve this? Or do you know an alternative to this?
This is likely the result of a bug that affected PHP versions 5.6.23 to 5.6.30, 7.0.8 to 7.0.16, and 7.1.0 to 7.1.2. It also affects the DateTime class.
The bug was resolved in PHP 7.0.17 and 7.1.3, but is still present in the latest release of PHP 5.6 (5.6.30 at the time of writing), which now receives only security fixes and therefore probably won't ever receive a fix.
Upgrading PHP to an unaffected version is probably the best solution, but if you need a workaround for an affected version you should be able to add a DateInterval to a Datetime and get the result you want.
strtotime() in PHP is quite powerfull function. One of it's features is relative dates.
For example this command:
echo date('Y-m-d', strtotime('Sunday this week'));
produces 2016-02-14 on my machine (today is "2016-02-12", Friday). Thus it supposes that first day of week is Monday. However in different locales countries first day of week is different.
Is there a way to change this behaviour and make strtotime() think that first week day is Sunday?
As discussed in the comments of the question, it may be better to rely on a custom function, which is tested and will most probably produce the same result on every machine.
A function like this could be:
<?php
function x() {
return date('Y-m-d', date('N')==7 ? strtotime('today') : strtotime('last sunday'));
}
echo x();
You find a demo here.
If you have many machines to deploy your code to, you could additionally include a test script in the installation process which tests if it gets correct results from this (and other things that may vary depending on installation).
PHP 5.5 introduced the Internationalization extension, which among many useful functions provides and IntCalendar class. It has a static function getFirstDayOfWeek which can be used to get the first day of the week, based a locale.
Straight from the docs:
ini_set('date.timezone', 'UTC');
$cal1 = IntlCalendar::createInstance(NULL, 'es_ES');
var_dump($cal1->getFirstDayOfWeek()); // Monday
I try to find an answer but without result
the problem is:
in sunday function return date for Monday next week
$date = new DateTime();
$date->setTimezone(new DateTimeZone('Europe/Moscow'));
$date->setTimestamp(strtotime('Monday this week'));
echo $date->format("d.m.Y");
but in other days (except Sunday) its return correct value of Monday.
I ever set locale manualy , which has a monday - the first day of week, but PHP "think" the Sunday is still firs day. is it bug ?? or i do some wrong ?
There seem to be known idiosyncrasies with strtotime. It's mentioned in the comments:
http://www.php.net/manual/en/datetime.formats.relative.php#108317
They don't mention different locales specifically but it would be extremely unsurprising if strtotime() does not correctly behave for next/this week under different locales.
Try this Monday or next Monday and see if one of those gets what you want.
strtotime("third Saturday October 2011")
Should be 10/15/2011. However, it's coming up at 10/22/2011. I assume this is because October 2011 starts on a Saturday and PHP is looking at the first full week. Since 10/1/2011 is a Saturday not a full week it ignores it.
Some research suggested putting "of" between the day of the week and the month should fix it but that doesn't work.
Any suggestions on why this is happening and what I can do to correct it?
This is a documented flaw in PHP <5.2.7 (see strtotime):
In PHP 5 prior to 5.2.7, requesting a given occurrence of a given
weekday in a month where that weekday was the first day of the month
would incorrectly add one week to the returned timestamp. This has
been corrected in 5.2.7 and later versions.
You'll need to upgrade PHP, or use a work around like Jonathan Kuhn suggests.
I was getting the same results as you on php 5.2.6. This works for me although not ideal.
echo date('Y-m-d', strtotime('Saturday October 2011 +2 weeks'));
<?php echo date('Y-m-d', strtotime('third Saturday of October 2011')); ?>
Works fine for me. Output is 2011-10-15.