DevConf 2015

Die DatePeriod Klasse

(PHP 5 >= 5.3.0)

Einführung

Stellt einen Datumsbereich dar.

Ein Datumsbereich ermöglicht die Iteration über eine Reihe von Datumsangaben und Uhrzeiten, die sich in regelmäßigen Intervallen wiederholen, über einen bestimmten Zeitraum.

Klassenbeschreibung

DatePeriod implements Traversable {
/* Konstanten */
const integer EXCLUDE_START_DATE = 1 ;
/* Methoden */
public __construct ( DateTimeInterface $start , DateInterval $interval , int $recurrences [, int $options ] )
public __construct ( DateTimeInterface $start , DateInterval $interval , DateTimeInterface $end [, int $options ] )
public __construct ( string $isostr [, int $options ] )
}

Vordefinierte Konstanten

DatePeriod::EXCLUDE_START_DATE

Anfangsdatum ausschließen; verwendet mit DatePeriod::__construct().

Inhaltsverzeichnis

add a note add a note

User Contributed Notes 6 notes

up
27
josh dot love at verizon dot net
2 years ago
Just an example to include the end date using the DateTime method 'modify'

<?php

$begin
= new DateTime( '2012-08-01' );
$end = new DateTime( '2012-08-31' );
$end = $end->modify( '+1 day' );

$interval = new DateInterval('P1D');
$daterange = new DatePeriod($begin, $interval ,$end);

foreach(
$daterange as $date){
    echo
$date->format("Ymd") . "<br>";
}
?>
up
8
jkaatz at gmx dot de
5 years ago
Nice example from PHP Spring Conference (thanks to Johannes Schlüter and David Zülke)

<?php
$begin
= new DateTime( '2007-12-31' );
$end = new DateTime( '2009-12-31 23:59:59' );

$interval = DateInterval::createFromDateString('last thursday of next month');
$period = new DatePeriod($begin, $interval, $end, DatePeriod::EXCLUDE_START_DATE);

foreach (
$period as $dt )
  echo
$dt->format( "l Y-m-d H:i:s\n" );
?>

DateInterval specs could be found at http://en.wikipedia.org/wiki/ISO_8601#Time_intervals
up
7
logos-php at kith dot org
2 years ago
Thanks much to those of you who supplied sample code; that helps a lot.

I wanted to mention another thing that helped me: when you do that foreach ( $period as $dt ), the $dt values are DateTime objects.

That may be obvious to those of you with more experience, but I wasn't sure until I looked it up on Stack Overflow. So I figured it was worth posting here to help others like me who might've been confused or uncertain.
up
4
Memori
4 years ago
If you want to include the end-date, add one day to it:

<?php
$startDate
= new DateTime();
$endDate = new DateTime();

$startDateInt = new DateInterval( "P1Y" );
$endDateInt = new DateInterval( "P1D" );

$startDate->sub( $startDateInt );
$endDate->add( $endDateInt );

$periodInt = new DateInterval( "P1M" );
$period = new DatePeriod( $startDate, $periodInt, $endDate );

// At februari 2011:
// $period = (8,9,10,11,12,1,2)
?>
up
1
Aurelien Marchand
4 years ago
Warning About DatePeriod for Some Versions of PHP
*****************************************

Some versions of PHP had a bug so that caused DatePeriod to act strangely. For instance, the following code:

<?php
$start
= DateTime::createFromFormat("Y-m-d H:i:s","2011-01-01 00:00:00",new DateTimeZone("America/Toronto"));
$interval = new DateInterval("P1M"); // 1 month
$occurrences = 3;
$period = new DatePeriod($start,$interval,$occurrences);
foreach(
$period as $dt){
  echo
$dt->format("Y-m-d H:i:s") . "\n";
}
foreach(
$period as $dt){
  echo
$dt->format("Y-m-d H:i:s") . "\n";
}
?>

Would produce the following text:
2011-01-01 00:00:00
2011-02-01 00:00:00
2011-03-01 00:00:00
2011-04-01 00:00:00
2011-05-01 00:00:00
2011-06-01 00:00:00
2011-07-01 00:00:00
2011-08-01 00:00:00

Instead of:
2011-01-01 00:00:00
2011-02-01 00:00:00
2011-03-01 00:00:00
2011-04-01 00:00:00
2011-01-01 00:00:00
2011-02-01 00:00:00
2011-03-01 00:00:00
2011-04-01 00:00:00

5.3.2 fails
5.3.3 fails
5.3.4 -??-
5.3.5 works
up
2
patrick at adrichem dot nu
1 year ago
DatePeriod is not compatible with negative intervals.

To do so you can simply use DateInterval and loop through it yourself like this: (not start should be ahead of end if you use a negative interval

    class DateRange extends ArrayIterator
    {

        protected $oDate = null;
        protected $oStartDate = null;
        protected $oEndDate = null;
        protected $oInterval = null;

        public function __construct( DateTime $oStartDate, DateTime $oEndDate, DateInterval $oInterval = null )
        {
            $this->oStartDate = $oStartDate;
            $this->oDate = clone $oStartDate;
            $this->oEndDate = $oEndDate;
            $this->oInterval = $oInterval;
        }

        public function next()
        {
            $this->oDate->add($this->oInterval);
            return $this->oDate;
        }

        public function current()
        {
            return $this->oDate;
        }

        public function valid()
        {
            if ($this->oStartDate > $this->oEndDate)
            {
                return $this->oDate >= $this->oEndDate;
            }
            return $this->oDate <= $this->oEndDate;
        }

    }

$oRange = new DateRange(new DateTime("2013-10-01"), new DateTime("2013-01-01"), DateInterval::createFromDateString("-1 month") );
    foreach ($oRange as $oDate)
    {
        echo $oDate->format("Y-m-d") . "<br />";
    }
To Top