I have such a code:
private function validatePeriodArrayYear()
{
$this->time->setTimestamp( self::$data['to'] );
$year1 = $this->time->format('Y');
$this->time->setTimestamp( self::$data['from'] );
$year2 = $this->time->format('Y');
$overlap = $year1 - $year2;
if( $overlap > 0 ){
$end = clone $this->time;
$end->setTimestamp( self::$data['to'] );
$overlap++;
$interval = new DateInterval('P1Y');
$period = new DatePeriod( $this->time, $interval, $end );
var_dump($period);
$iteration = -1;
foreach( $period as $onePeriod ){
var_dump($onePeriod);
$iteration++;
if( $iteration > 0 ){
$onePeriod->setDate( $onePeriod->format('Y'), 1, 1 );
}
$from = $onePeriod->getTimestamp();
$onePeriod->setDate( $onePeriod->format('Y'), 12, 31 );
$onePeriod->setTime( 23, 59, 59 );
self::$data['zone'][$iteration] = array( 'from' => $from, 'to' => $onePeriod->getTimestamp() );
}
self::$data['zone'][$iteration]['to'] = self::$data['to'];
} else {
self::$data['zone'][] = array( 'from' => self::$data['from'], 'to' => self::$data['to'] );
}
}
Variables
$this->time = new DateTime(),
self::$data['from'] = 1354316400,
self::$data['to'] = 1389653999
var_dump() output function is the following:
<pre>
object(DatePeriod)[337]
public start =>
object(DateTime)[336]
public date => string 2012-12-01 00:00:00 (length=19)
public timezone_type => int 3
public timezone => string Europe/Prague (length=13)
public current => null
public end =>
object(DateTime)[48]
public date => string 2014-01-13 23:59:59 (length=19)
public timezone_type => int 3
public timezone => string Europe/Prague (length=13)
public interval =>
object(DateInterval)[331]
public y => int 1
public m => int 0
public d => int 0
public h => int 0
public i => int 0
public s => int 0
public weekday => int 0
public weekday_behavior => int 0
public first_last_day_of => int 0
public invert => int 0
public days => boolean false
public special_type => int 0
public special_amount => int 0
public have_weekday_relative => int 0
public have_special_relative => int 0
public recurrences => int 1
public include_start_date => boolean true
object(DateTime)[326]
public date => string 2012-12-01 00:00:00 (length=19)
public timezone_type => int 3
public timezone => string Europe/Prague (length=13)
object(DateTime)[47]
public date => string 2013-12-01 00:00:00 (length=19)
public timezone_type => int 3
public timezone => string Europe/Prague (length=13)
After executing the code is stored in the variable self::$data['zone']
is this:
array (size=2)
0 =>
array (size=2)
from => int 1354316400
to => int 1356994799
1 =>
array (size=2)
from => int 1356994800
to => int 1389653999
converted to dates:
01.12.2012 - 31.12.2012
01.01.2013 - 13.01.2014
Now, please correct me if it would not generate this and where is the error in this case:
01.12.2012 - 31.12.2012
01.01.2013 - 31.12.2013
01.01.2014 - 13.01.2014
Additional information
$ php -v
PHP 5.5.6-1+debphp.org~raring+2 (cli) (built: Nov 21 2013 14:39:09)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2013 Zend Technologies
with Zend OPcache v7.0.3-dev, Copyright (c) 1999-2013, by Zend Technologies
with Xdebug v2.2.3, Copyright (c) 2002-2013, by Derick Rethans
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 13.10
Release: 13.10
Codename: saucy
$ uname -a
Linux userName-K55VJ 3.11.0-15-generic #23-Ubuntu SMP Mon Dec 9 18:17:04 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
Thank you for answers.
Edit
@Glavić: thanks for the information, now i fully understand
It struck me that, if starting and end year were the same, and i changed only months or days in that year, it sometimes brought the correct result, and sometimes lacked the last year.
Let me therefore a little further break down the problem.
For clarification i will use a different input variables for a better understanding.
Variables
self::$data['from'] = 1354316400 //1.12.2012 00:00:00
self::$data['to'] = 1417388400 //1.12.2014 00:00:00
Please note that the self::$data['to']
is just missing one second that the difference was over 3 years.
Code
$start = new DateTime()->setTimestamp( self::$data['from'] );
$end = new DateTime()->setTimestamp( self::$data['to'] );
$interval = new DateInterval('P1Y');
$period = new DatePeriod( $start, $interval, $end );
foreach( $period as $onePeriod ){
var_dump($onePeriod);
}
Output
object(DateTime)
public date => string 2012-12-01 00:00:00 (length=19)
public timezone_type => int 3
public timezone => string Europe/Prague (length=13)
object(DateTime)
public date => string 2013-12-01 00:00:00 (length=19)
public timezone_type => int 3
public timezone => string Europe/Prague (length=13)
In this case, three dates are created inside DatePeriod
class:
2012-12-01 00:00:00
2013-12-01 00:00:00
2014-12-01 00:00:00
But the last date is removed, therefore class returns only two DateTime
objects.
Now we add a second to the variable self::$data['to']
and run the code again.
Variable
self::$data['from'] = 1354316400 //1.12.2012 00:00:00
self::$data['to'] = 1417388401 //1.12.2014 00:00:01
Output
object(DateTime)
public date => string 2012-12-01 00:00:00 (length=19)
public timezone_type => int 3
public timezone => string Europe/Prague (length=13)
object(DateTime)
public date => string 2013-12-01 00:00:00 (length=19)
public timezone_type => int 3
public timezone => string Europe/Prague (length=13)
object(DateTime)
public date => string 2014-12-01 00:00:00 (length=19)
public timezone_type => int 3
public timezone => string Europe/Prague (length=13)
In this case, four dates are created inside DatePeriod
class:
2012-12-01 00:00:00
2013-12-01 00:00:00
2014-12-01 00:00:00
2014-12-01 00:00:01
Last date is again removed.
Mathematically expressed
{ x | a ≤ x < b }
a = starting date
b = end date
initialized x is equal to a
the creation of each period is then
x = x + Period (in my case P1Y belonging {365,366})