10

hi i have script gives me list of days date between a week. i need the reverse the the order. alredy tried rsort, reverse_array, and much more some how all giving error.

thanks.

script

$date2 = "$lastweek2";
$date1 = "$lastweek1";

$start    = new DateTime($date2);
$end      = new DateTime($date1);
$interval = DateInterval::createFromDateString('1 day');
$period   = new DatePeriod($start, $interval, $end);

echo "<br>";
foreach ($period as $dt) {
    echo $dt->format("Y-m-d") . "<br>\n";
}

echo is like this

2014-08-09
2014-08-10
2014-08-11
2014-08-12
2014-08-13
2014-08-14
2014-08-15

reversed

2014-08-15
2014-08-14
2014-08-13
2014-08-12
2014-08-11
2014-08-10
2014-08-09
John Conde
  • 217,595
  • 99
  • 455
  • 496
sarabrownD
  • 125
  • 1
  • 7

5 Answers5

31
$period = array_reverse(iterator_to_array($period));
linktoahref
  • 7,812
  • 3
  • 29
  • 51
izupet
  • 1,529
  • 5
  • 20
  • 42
16

Using a negative one day interval and the difference of days between the two dates you can accomplish the same thing without needing to use array_reverse(iterator_to_array()) or build another array.

Example: https://3v4l.org/B3nNk

$start = new \DateTime('2014-08-15');
$end = new \DateTime('2014-08-09');
$diff = $end->diff($start);
$interval = \DateInterval::createFromDateString('-1 day');

/* 
//alternative usage

$interval = new \DateInterval('PT0S'); //0 duration
$interval->d = -1; //negative value
*/
    
$period = new \DatePeriod($start, $interval, $diff->days);
foreach ($period as $date) {
    echo $date->format('Y-m-d') . PHP_EOL;
}

Result:

2014-08-15
2014-08-14
2014-08-13
2014-08-12
2014-08-11
2014-08-10
2014-08-09

In this way it tells DatePeriod to subtract 1 day, for the number of days returned from the diff, instead of adding up until the end date.


Daylight Savings Time Bug (PHP < 8.1)

NOTE: This approach does not work for intervals less than a day with time-zones that recognize DST, due to a known issue with dates and the DST hour changes. https://bugs.php.net/bug.php?id=74274, which extends to DateTime::sub(), and similar usages. Fixed in PHP 8.1

Example https://3v4l.org/2DKBs

date_default_timezone_set('America/New_York');

$start = new DateTime('2020-03-08 04:00');
$interval = DateInterval::createFromDateString('-1 hour');

$period = new DatePeriod($start, $interval, 10);
foreach ($period as $date) {
    echo $date->format('Y-m-d h:i a') . PHP_EOL;
}

Result

2020-03-08 04:00 am
2020-03-08 03:00 am
2020-03-08 03:00 am
2020-03-08 03:00 am
2020-03-08 03:00 am
2020-03-08 03:00 am
2020-03-08 03:00 am
2020-03-08 03:00 am
2020-03-08 03:00 am
2020-03-08 03:00 am
2020-03-08 03:00 am

DST Workaround and Best-Practice

The workaround is to use a time-zone that does not recognize DST, such as UTC. Using the UTC time-zone for internal application dates and converting to the desired time-zone for display, is currently considered best-practice.

Example https://3v4l.org/3YflE

date_default_timezone_set('UTC');

$start = new DateTime('2020-03-08 04:00');
$interval = DateInterval::createFromDateString('-1 hour');

$period = new DatePeriod($start, $interval, 10);
foreach ($period as $date) {
    echo $date->format('Y-m-d h:i a') . PHP_EOL;
}

Result

2020-03-08 04:00 am
2020-03-08 03:00 am
2020-03-08 02:00 am
2020-03-08 01:00 am
2020-03-08 12:00 am
2020-03-07 11:00 pm
2020-03-07 10:00 pm
2020-03-07 09:00 pm
2020-03-07 08:00 pm
2020-03-07 07:00 pm
2020-03-07 06:00 pm
Will B.
  • 17,883
  • 4
  • 67
  • 69
  • doesnt work with dates and end – Puschie Jan 12 '23 at 18:07
  • Please reread the initial code example that demonstrates how to convert the end-date to the desired Interval using `DateTime::diff()` This is because the `DatePeriod` constructor requires the third argument to be either a `DateTimeInterface` object beyond the supplied start date or an integer. – Will B. Jan 13 '23 at 03:58
13

Just put the dates in an array and then reverse the order of the array using array_reverse()

$dates = array();
foreach ($period as $dt) {
    $dates[] = $dt->format("Y-m-d");
}

$dates = array_reverse($dates);
echo implode("<br>\n", $dates);
John Conde
  • 217,595
  • 99
  • 455
  • 496
2
$date1 = "2014-08-15";
$date2 = "2014-08-09";

$start    = new DateTime($date2);
$end      = new DateTime($date1);
$i = DateInterval::createFromDateString('1 day');
while ($end >= $start) {
  echo $end->format("Y-m-d") . "<br>\n";
  $end = $end->sub($i);
}
MrTux
  • 32,350
  • 30
  • 109
  • 146
0
$from_date = date("Y-m-01");
$to_date = date("Y-m-d");

while (strtotime($to_date) >=strtotime($from_date))
{
    $to_date = date ("Y-m-d", strtotime("-1 day", strtotime($to_date)));

    echo "From date: $to_date, to date: $to_date<br>";
}

Output is:

From date: 2021-08-24, to date: 2021-08-24

From date: 2021-08-23, to date: 2021-08-23

From date: 2021-08-22, to date: 2021-08-22

From date: 2021-08-21, to date: 2021-08-21

From date: 2021-08-20, to date: 2021-08-20

From date: 2021-08-19, to date: 2021-08-19

From date: 2021-08-18, to date: 2021-08-18

From date: 2021-08-17, to date: 2021-08-17

From date: 2021-08-16, to date: 2021-08-16

From date: 2021-08-15, to date: 2021-08-15

From date: 2021-08-14, to date: 2021-08-14

From date: 2021-08-13, to date: 2021-08-13

From date: 2021-08-12, to date: 2021-08-12

From date: 2021-08-11, to date: 2021-08-11

From date: 2021-08-10, to date: 2021-08-10

From date: 2021-08-09, to date: 2021-08-09

From date: 2021-08-08, to date: 2021-08-08

From date: 2021-08-07, to date: 2021-08-07

From date: 2021-08-06, to date: 2021-08-06

From date: 2021-08-05, to date: 2021-08-05

From date: 2021-08-04, to date: 2021-08-04

From date: 2021-08-03, to date: 2021-08-03

From date: 2021-08-02, to date: 2021-08-02

From date: 2021-08-01, to date: 2021-08-01

Zahid Gani
  • 169
  • 6