Asked  1 Year ago    Answers:  5   Viewed   8 times

So I have one date as a string:

2011/06/01

I need to get the 5 DateTime objects from it that correspond to the five weekdays (Monday to Friday) in that week, e.g. for the date above I need 2011-05-30 to 2011-06-03.

How to do that? I know I can do:

$dateTime = new DateTime('2011/06/01');

But I am kinda stuck there :) I know, embarrassing.

 Answers

2

Can use DatePeriod:

$firstMondayThisWeek= new DateTime('2011/06/01');
$firstMondayThisWeek->modify('tomorrow');
$firstMondayThisWeek->modify('last Monday');

$nextFiveWeekDays = new DatePeriod(
    $firstMondayThisWeek,
    DateInterval::createFromDateString('+1 weekdays'),
    4
);

print_r(iterator_to_array($nextFiveWeekDays));

Note that DatePeriod is an Iterator, so unless you are really fixed on having the dates in an array, you can just as well go with the DatePeriod as container.

The above will give something like (demo)

 Array
(
[0] => DateTime Object
    (
        [date] => 2011-05-30 00:00:00
        [timezone_type] => 3
        [timezone] => Europe/Berlin
    )

[1] => DateTime Object
    (
        [date] => 2011-05-31 00:00:00
        [timezone_type] => 3
        [timezone] => Europe/Berlin
    )

[2] => DateTime Object
    (
        [date] => 2011-06-01 00:00:00
        [timezone_type] => 3
        [timezone] => Europe/Berlin
    )

[3] => DateTime Object
    (
        [date] => 2011-06-02 00:00:00
        [timezone_type] => 3
        [timezone] => Europe/Berlin
    )

[4] => DateTime Object
    (
        [date] => 2011-06-03 00:00:00
        [timezone_type] => 3
        [timezone] => Europe/Berlin
    )
)

One pre-5.3 solution to do that would be

$firstMondayInWeek = strtotime('last Monday', strtotime('2011/06/01 +1 day'));
$nextFiveWeekDays = array();
for ($days = 1; $days <= 5; $days++) {
    $nextFiveWeekDays[] = new DateTime(
        date('Y-m-d', strtotime("+$days weekdays", $firstMondayInWeek))
    );
}

though I really dont see why you would want to use DateTime objects for this when you dont/cannot also use their API in your project. As you can see, this is all the old date functions with DateTime just being the container.

Thursday, April 1, 2021
 
twk
 
twk
3

DateInterval is buggy on windows platform. See bug #51183. The official answer seems to be "use VC9 builds instead for now".

Thursday, April 1, 2021
 
relipse
 
4

Why don't you get first monday, and do a loop adding 7 days to it until it is next year?

$first = strtotime("first monday of $year[$j]");
$lastday = mktime(0, 0, 0, 12, 31, $year[$j]);

$day = $first;
do {
    echo date('M d, Y', $day);
    $day += 7 * 86400;

} while ($day < $lastday);
Thursday, April 1, 2021
 
3

I use following wrapper class in my php5.2 apps: http://pastebin.ca/2051944. Untill php5.3 was released - it saves much my time

Saturday, May 29, 2021
 
TuomasR
 
4

I'm afraid you have fallen into one of the numerous traps of object mutation. :)

The problem is that, in the line "var nextday = ...", you are changing the date saved in "curr" on every iteration by calling setDate(). That is no problem as long as next is within the range of the current month; curr.setDate(next) is equivalent to going forward one in this case.

The problems begin when next reaches 30. There is no February 30, so setDate() wraps around to the next month, yielding the 1st of March - so far so good. Unfortunately, the next iteration calls curr.setDate(31), and as curr is the 1st of March (remember that the object referenced by curr is changed in each iteration), we get... March 31! The other strange values can be explained the same way.

A way to fix this is to copy curr on each iteration and then call setDate(), like so:

for (var i = 1; i < 7; i++) {
    var next = new Date(curr.getTime());
    next.setDate(first + i);
    alert(next.toString());
}
Wednesday, December 22, 2021
 
mattyb
 
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :