1239 lines
44 KiB
PHP
1239 lines
44 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
|
||
|
*
|
||
|
* This file is a part of iCalcreator.
|
||
|
*
|
||
|
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
||
|
* @copyright 2007-2022 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
|
||
|
* @link https://kigkonsult.se
|
||
|
* @license Subject matter of licence is the software iCalcreator.
|
||
|
* The above copyright, link, package and version notices,
|
||
|
* this licence notice and the invariant [rfc5545] PRODID result use
|
||
|
* as implemented and invoked in iCalcreator shall be included in
|
||
|
* all copies or substantial portions of the iCalcreator.
|
||
|
*
|
||
|
* iCalcreator is free software: you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU Lesser General Public License as
|
||
|
* published by the Free Software Foundation, either version 3 of
|
||
|
* the License, or (at your option) any later version.
|
||
|
*
|
||
|
* iCalcreator is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU Lesser General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU Lesser General Public License
|
||
|
* along with iCalcreator. If not, see <https://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
namespace Kigkonsult\Icalcreator;
|
||
|
|
||
|
use Kigkonsult\Icalcreator\Util\DateTimeFactory;
|
||
|
use Kigkonsult\Icalcreator\Util\RecurFactory;
|
||
|
use Kigkonsult\Icalcreator\Util\RecurFactory2;
|
||
|
use DateTime;
|
||
|
use Exception;
|
||
|
|
||
|
/**
|
||
|
* class RecurTest, testing selectComponents
|
||
|
*
|
||
|
* @since 2.27.20 - 2019-05-20
|
||
|
*/
|
||
|
class RecurMonthTest extends RecurBaseTest
|
||
|
{
|
||
|
/**
|
||
|
* recurMonthly1Test provider
|
||
|
*
|
||
|
* @return mixed[]
|
||
|
* @throws Exception
|
||
|
*/
|
||
|
public function recurMonthly1aProvider() : array
|
||
|
{
|
||
|
$dataArr = [];
|
||
|
$dataSetNo = 0;
|
||
|
$DATASET = 'DATASET';
|
||
|
|
||
|
$time = microtime( true );
|
||
|
$start = DateTimeFactory::factory( '20190105T090000', 'Europe/Stockholm' );
|
||
|
$wDate = clone $start;
|
||
|
$expects = [];
|
||
|
$count = 10;
|
||
|
$x = 1;
|
||
|
while( $x < $count ) {
|
||
|
$wDate = $wDate->setDate(
|
||
|
(int)$wDate->format( 'Y' ),
|
||
|
( (int)$wDate->format( 'm' ) + 1 ),
|
||
|
(int)$wDate->format( 'd' )
|
||
|
);
|
||
|
$expects[] = $wDate->format( 'Ymd' );
|
||
|
++$x;
|
||
|
}
|
||
|
$execTime = microtime( true ) - $time;
|
||
|
$dataArr[] = [
|
||
|
21,
|
||
|
$start,
|
||
|
$wDate->modify( RecurFactory::EXTENDYEAR . ' year' ),
|
||
|
[
|
||
|
IcalInterface::FREQ => IcalInterface::MONTHLY,
|
||
|
IcalInterface::COUNT => $count,
|
||
|
$DATASET => $dataSetNo++
|
||
|
],
|
||
|
$expects,
|
||
|
$execTime
|
||
|
];
|
||
|
|
||
|
|
||
|
$interval = 1;
|
||
|
$count = 10;
|
||
|
for( $ix = 221; $ix <= 229; $ix++ ) {
|
||
|
$time = microtime( true );
|
||
|
$start = DateTimeFactory::factory( '20190130T0900', 'Europe/Stockholm' );
|
||
|
$end = ( clone $start )->modify( RecurFactory::EXTENDYEAR . ' years' );
|
||
|
$endYmd = $end->format( 'Ymd' );
|
||
|
$wDate = clone $start;
|
||
|
$expects = [];
|
||
|
$x = 1;
|
||
|
$day = (int)$wDate->format( 'd' );
|
||
|
$month = (int)$wDate->format( 'm' );
|
||
|
$year = (int)$wDate->format( 'Y' );
|
||
|
while( $x < $count ) {
|
||
|
$month += $interval;
|
||
|
if( 12 < $month ) {
|
||
|
$year += (int)floor( $month / 12 );
|
||
|
$month %= 12;
|
||
|
if( 0 === $month ) {
|
||
|
$month = 12;
|
||
|
}
|
||
|
}
|
||
|
if( ! checkdate( $month, $day, $year ) ) {
|
||
|
continue;
|
||
|
}
|
||
|
$Ymd = sprintf( '%04d%02d%02d', $year, $month, $day );
|
||
|
if( $endYmd < $Ymd ) {
|
||
|
break;
|
||
|
}
|
||
|
$expects[] = $Ymd;
|
||
|
++$x;
|
||
|
} // end while
|
||
|
$execTime = microtime( true ) - $time;
|
||
|
$dataArr[] = [
|
||
|
$ix . '-' . $interval,
|
||
|
$start,
|
||
|
( clone $start )->modify( RecurFactory::EXTENDYEAR . ' years' ),
|
||
|
[
|
||
|
IcalInterface::FREQ => IcalInterface::MONTHLY,
|
||
|
IcalInterface::INTERVAL => $interval,
|
||
|
IcalInterface::COUNT => $count,
|
||
|
$DATASET => $dataSetNo++
|
||
|
],
|
||
|
$expects,
|
||
|
$execTime
|
||
|
];
|
||
|
++$interval;
|
||
|
}
|
||
|
|
||
|
$interval = 1;
|
||
|
$byMonth = [ 1, 5, 12 ];
|
||
|
$count = 9;
|
||
|
for( $ix = 231; $ix <= 239; $ix++ ) {
|
||
|
$time = microtime( true );
|
||
|
$start = DateTimeFactory::factory( '20190101T0900', 'Europe/Stockholm' );
|
||
|
// $end = (clone $start)->modify( RecurFactory::EXTENDYEAR . ' years' );
|
||
|
$end = ( clone $start )->modify( 5 . ' years' );
|
||
|
$endYmd = $end->format( 'Ymd' );
|
||
|
$wDate = clone $start;
|
||
|
$expects = [];
|
||
|
$x = 1;
|
||
|
$day = (int)$wDate->format( 'd' );
|
||
|
$month = (int)$wDate->format( 'm' );
|
||
|
$year = (int)$wDate->format( 'Y' );
|
||
|
while( $x < $count ) {
|
||
|
$month += $interval;
|
||
|
if( 12 < $month ) {
|
||
|
$year += (int)floor( $month / 12 );
|
||
|
$month %= 12;
|
||
|
if( 0 === $month ) {
|
||
|
$month = 12;
|
||
|
}
|
||
|
}
|
||
|
if( ! checkdate( $month, $day, $year ) ) {
|
||
|
continue;
|
||
|
}
|
||
|
$Ymd = sprintf( '%04d%02d%02d', $year, $month, $day );
|
||
|
if( $endYmd < $Ymd ) {
|
||
|
break;
|
||
|
}
|
||
|
if( ! in_array( $month, $byMonth ) ) {
|
||
|
continue;
|
||
|
}
|
||
|
$expects[] = $Ymd;
|
||
|
++$x;
|
||
|
} // end while
|
||
|
$execTime = microtime( true ) - $time;
|
||
|
$dataArr[] = [
|
||
|
$ix . '-' . $interval,
|
||
|
$start,
|
||
|
$end,
|
||
|
[
|
||
|
IcalInterface::FREQ => IcalInterface::MONTHLY,
|
||
|
IcalInterface::INTERVAL => $interval,
|
||
|
IcalInterface::COUNT => $count,
|
||
|
IcalInterface::BYMONTH => $byMonth,
|
||
|
$DATASET => $dataSetNo++
|
||
|
],
|
||
|
$expects,
|
||
|
$execTime,
|
||
|
];
|
||
|
++$interval;
|
||
|
}
|
||
|
|
||
|
$interval = 1;
|
||
|
$byMonthDay = [ 1 ];
|
||
|
$count = 20;
|
||
|
$switch = true;
|
||
|
for( $ix = 241; $ix <= 249; $ix++ ) {
|
||
|
$time = microtime( true );
|
||
|
$start = DateTimeFactory::factory( '20190101T0900', 'Europe/Stockholm' );
|
||
|
$end = clone $start;
|
||
|
$end->modify( RecurFactory::EXTENDYEAR . ' years' );
|
||
|
$endYmd = $end->format( 'Ymd' );
|
||
|
$wDate = clone $start;
|
||
|
$expects = [];
|
||
|
$x = 1;
|
||
|
$day = (int)$wDate->format( 'd' );
|
||
|
$month = (int)$wDate->format( 'm' );
|
||
|
$year = (int)$wDate->format( 'Y' );
|
||
|
$monthSave = $month;
|
||
|
$lastDayInMonth = (int)$wDate->format( 't' );
|
||
|
$tz = $wDate->getTimezone()->getName();
|
||
|
while( $x < $count ) {
|
||
|
if( $month !== $monthSave ) {
|
||
|
$month += $interval;
|
||
|
if( 12 < $month ) {
|
||
|
$year += (int)floor( $month / 12 );
|
||
|
$month %= 12;
|
||
|
if( 0 === $month ) {
|
||
|
$month = 12;
|
||
|
}
|
||
|
}
|
||
|
$monthSave = $month;
|
||
|
$day = 1;
|
||
|
$date = DateTimeFactory::factory( sprintf( '%04d%02d%02d', $year, $month, $day ), $tz );
|
||
|
$lastDayInMonth = (int)$date->format( 't' );
|
||
|
} // end if
|
||
|
elseif( $day === $lastDayInMonth ) {
|
||
|
$monthSave = -1;
|
||
|
continue;
|
||
|
}
|
||
|
else {
|
||
|
++$day;
|
||
|
}
|
||
|
$match = false;
|
||
|
foreach( $byMonthDay as $monthDay ) {
|
||
|
if( 0 < $monthDay ) {
|
||
|
if( $monthDay === $day ) {
|
||
|
$match = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else if( ( $lastDayInMonth + 1 + $monthDay ) === $day ) {
|
||
|
$match = true;
|
||
|
break;
|
||
|
}
|
||
|
} // end foreach
|
||
|
$Ymd = sprintf( '%04d%02d%02d', $year, $month, $day );
|
||
|
if( $endYmd < $Ymd ) {
|
||
|
break;
|
||
|
}
|
||
|
if( $match ) {
|
||
|
$expects[] = $Ymd;
|
||
|
++$x;
|
||
|
}
|
||
|
if( $x >= $count ) {
|
||
|
break;
|
||
|
}
|
||
|
} // end while
|
||
|
$execTime = microtime( true ) - $time;
|
||
|
$dataArr[] = [
|
||
|
$ix . '-' . $interval,
|
||
|
$start,
|
||
|
$end,
|
||
|
[
|
||
|
IcalInterface::FREQ => IcalInterface::MONTHLY,
|
||
|
IcalInterface::INTERVAL => $interval,
|
||
|
IcalInterface::COUNT => $count,
|
||
|
IcalInterface::BYMONTHDAY => $byMonthDay,
|
||
|
$DATASET => $dataSetNo++
|
||
|
],
|
||
|
$expects,
|
||
|
$execTime,
|
||
|
];
|
||
|
$interval += 2;
|
||
|
$byMonthDay[] = $switch ? ( 0 - $interval ) : $interval;
|
||
|
$switch = ! $switch;
|
||
|
} // end for
|
||
|
|
||
|
$interval = 1;
|
||
|
$byMonthDay = [ 1, 3, 5, 7, -5, -3, -1 ];
|
||
|
$byMonth = [ 1, 12 ];
|
||
|
$count = 20;
|
||
|
$switch = true;
|
||
|
for( $ix = 251; $ix <= 259; $ix++ ) {
|
||
|
$time = microtime( true );
|
||
|
$start = DateTimeFactory::factory( '20190101T0900', 'Europe/Stockholm' );
|
||
|
$end = ( clone $start )->modify( RecurFactory::EXTENDYEAR . ' years' );
|
||
|
$endYmd = $end->format( 'Ymd' );
|
||
|
$wDate = clone $start;
|
||
|
$expects = [];
|
||
|
$x = 1;
|
||
|
$day = (int)$wDate->format( 'd' );
|
||
|
$month = (int)$wDate->format( 'm' );
|
||
|
$year = (int)$wDate->format( 'Y' );
|
||
|
$monthSave = $month;
|
||
|
$lastDayInMonth = (int)$wDate->format( 't' );
|
||
|
$tz = $wDate->getTimezone()->getName();
|
||
|
while( $x < $count ) {
|
||
|
if( $month !== $monthSave ) {
|
||
|
$month += $interval;
|
||
|
if( 12 < $month ) {
|
||
|
$year += (int)floor( $month / 12 );
|
||
|
$month %= 12;
|
||
|
if( 0 === $month ) {
|
||
|
$month = 12;
|
||
|
}
|
||
|
}
|
||
|
if( ! in_array( $month, $byMonth, true ) ) {
|
||
|
continue;
|
||
|
}
|
||
|
$monthSave = $month;
|
||
|
if( ! empty( $byMonthDay ) ) {
|
||
|
$day = 1;
|
||
|
$lastDayInMonth = (int)(
|
||
|
DateTimeFactory::factory( sprintf( '%04d%02d%02d', $year, $month, $day ), $tz ) )
|
||
|
->format( 't' );
|
||
|
}
|
||
|
} // end if
|
||
|
elseif( $day === $lastDayInMonth ) {
|
||
|
$monthSave = -1;
|
||
|
continue;
|
||
|
}
|
||
|
else {
|
||
|
++$day;
|
||
|
}
|
||
|
if( ! checkdate( $month, $day, $year ) ) {
|
||
|
continue;
|
||
|
}
|
||
|
$Ymd = sprintf( '%04d%02d%02d', $year, $month, $day );
|
||
|
if( $endYmd < $Ymd ) {
|
||
|
break;
|
||
|
}
|
||
|
$match = false;
|
||
|
foreach( $byMonthDay as $monthDay ) {
|
||
|
if( 0 < $monthDay ) {
|
||
|
if( $monthDay === $day ) {
|
||
|
$match = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else if( ( $lastDayInMonth + 1 + $monthDay ) === $day ) {
|
||
|
$match = true;
|
||
|
break;
|
||
|
}
|
||
|
} // end foreach
|
||
|
if( $match ) {
|
||
|
$expects[] = $Ymd;
|
||
|
++$x;
|
||
|
}
|
||
|
} // end while
|
||
|
$execTime = microtime( true ) - $time;
|
||
|
$dataArr[] = [
|
||
|
$ix,
|
||
|
$start,
|
||
|
$end,
|
||
|
[
|
||
|
IcalInterface::FREQ => IcalInterface::MONTHLY,
|
||
|
IcalInterface::INTERVAL => $interval,
|
||
|
IcalInterface::COUNT => $count,
|
||
|
IcalInterface::BYMONTH => $byMonth,
|
||
|
IcalInterface::BYMONTHDAY => $byMonthDay,
|
||
|
$DATASET => $dataSetNo++
|
||
|
],
|
||
|
$expects,
|
||
|
$execTime,
|
||
|
];
|
||
|
++$interval;
|
||
|
$switch = ! $switch;
|
||
|
} // end for
|
||
|
|
||
|
// rfc example 18 (extended) see also #23, above
|
||
|
$time = microtime( true );
|
||
|
$start = DateTimeFactory::factory( '20190101T090000', 'Europe/Stockholm' );
|
||
|
$wDate = clone $start;
|
||
|
$expects = [];
|
||
|
$count = 10;
|
||
|
$x = 1;
|
||
|
$saveYm = $wDate->format( 'Ym' );
|
||
|
$wDate = $wDate->modify( '1 day' );
|
||
|
$mDays = [];
|
||
|
while( $x < $count ) {
|
||
|
if( $saveYm !== $wDate->format( 'Ym' ) ) {
|
||
|
if( ! empty( $mDays ) ) {
|
||
|
$expects[] = current( array_slice( $mDays, -3, 1 ) );
|
||
|
++$x;
|
||
|
$mDays = [];
|
||
|
continue;
|
||
|
}
|
||
|
$saveYm = $wDate->format( 'Ym' );
|
||
|
}
|
||
|
$mDays[] = $wDate->format( 'Ymd' );
|
||
|
$wDate = $wDate->modify( '1 day' );
|
||
|
} // end while
|
||
|
$execTime = microtime( true ) - $time;
|
||
|
$dataArr[] = [
|
||
|
'29-18',
|
||
|
$start,
|
||
|
$wDate->modify( RecurFactory::EXTENDYEAR . ' year' ),
|
||
|
[
|
||
|
IcalInterface::FREQ => IcalInterface::MONTHLY,
|
||
|
IcalInterface::COUNT => $count,
|
||
|
IcalInterface::BYMONTHDAY => -3,
|
||
|
$DATASET => $dataSetNo++
|
||
|
],
|
||
|
$expects,
|
||
|
$execTime
|
||
|
];
|
||
|
|
||
|
// rfc example 19 - 20
|
||
|
$dateString = '1997-09-02 09:00:00';
|
||
|
$byMonthDays = [ 2, 15 ];// rfc 19
|
||
|
for( $ix = 19; $ix <= 20; $ix++ ) {
|
||
|
$time = microtime( true );
|
||
|
$start = DateTimeFactory::factory( $dateString, 'America/Los_Angeles' );
|
||
|
$startYmd = $start->format( 'Ymd' );
|
||
|
$end = ( clone $start )->modify( RecurFactory::EXTENDYEAR . ' year' );
|
||
|
$wDate = clone $start;
|
||
|
$expects = [];
|
||
|
$count = 10;
|
||
|
$x = 1;
|
||
|
$year = (int)$wDate->format( 'Y' );
|
||
|
$month = (int)$wDate->format( 'm' );
|
||
|
while( $x < $count ) {
|
||
|
$daysInMonth = (int)$wDate->format( 't' );
|
||
|
foreach( RecurFactory2::getMonthDaysFromByMonthDayList(
|
||
|
$daysInMonth, $byMonthDays
|
||
|
) as $monthDay ) {
|
||
|
$wDate = $wDate->setDate(
|
||
|
$year,
|
||
|
$month,
|
||
|
$monthDay
|
||
|
);
|
||
|
$Ymd = $wDate->format( 'Ymd' );
|
||
|
if( $startYmd >= $Ymd ) {
|
||
|
continue;
|
||
|
}
|
||
|
if( $x >= $count ) {
|
||
|
break;
|
||
|
}
|
||
|
$expects[] = $Ymd;
|
||
|
++$x;
|
||
|
} // end foreach
|
||
|
$wDate = $wDate->setDate(
|
||
|
$year,
|
||
|
$month + 1,
|
||
|
1
|
||
|
);
|
||
|
$year = (int)$wDate->format( 'Y' );
|
||
|
$month = (int)$wDate->format( 'm' );
|
||
|
} // end while
|
||
|
$execTime = microtime( true ) - $time;
|
||
|
$dataArr[] = [
|
||
|
'29-' . $ix,
|
||
|
$start,
|
||
|
$end,
|
||
|
[
|
||
|
IcalInterface::FREQ => IcalInterface::MONTHLY,
|
||
|
IcalInterface::COUNT => $count,
|
||
|
IcalInterface::BYMONTHDAY => $byMonthDays,
|
||
|
$DATASET => $dataSetNo++
|
||
|
],
|
||
|
$expects,
|
||
|
$execTime
|
||
|
];
|
||
|
// rfc example 20
|
||
|
$dateString = '1997-09-30 09:00:00';
|
||
|
$byMonthDays = [ 1, -1 ];
|
||
|
} // end for
|
||
|
|
||
|
// rfc example 21
|
||
|
$time = microtime( true );
|
||
|
$start = DateTimeFactory::factory( '20190101T090000', 'Europe/Stockholm' );
|
||
|
$wDate = clone $start;
|
||
|
$expects = [];
|
||
|
$count = 10;
|
||
|
$interval = 18;
|
||
|
$byMonthDay = range( 10, 15 );
|
||
|
$x = 1;
|
||
|
$wDate = $wDate->modify( '1 day' );
|
||
|
while( $x < $count ) {
|
||
|
if( 10 > (int)$wDate->format( 'd' ) ) {
|
||
|
$wDate = $wDate->modify( '1 day' );
|
||
|
}
|
||
|
elseif( in_array( (int)$wDate->format( 'd' ), $byMonthDay, true ) ) {
|
||
|
$expects[] = $wDate->format( 'Ymd' );
|
||
|
++$x;
|
||
|
$wDate = $wDate->modify( '1 day' );
|
||
|
}
|
||
|
else {
|
||
|
$wDate = $wDate->setDate( // interval=18
|
||
|
(int)$wDate->format( 'Y' ),
|
||
|
( (int)$wDate->format( 'm' ) + 18 ),
|
||
|
10
|
||
|
);
|
||
|
}
|
||
|
} // end while
|
||
|
$execTime = microtime( true ) - $time;
|
||
|
$dataArr[] = [
|
||
|
'29-21-18',
|
||
|
$start,
|
||
|
( clone $start )->modify( RecurFactory::EXTENDYEAR . ' year' ),
|
||
|
[
|
||
|
IcalInterface::FREQ => IcalInterface::MONTHLY,
|
||
|
IcalInterface::COUNT => $count,
|
||
|
IcalInterface::INTERVAL => $interval,
|
||
|
IcalInterface::BYMONTHDAY => $byMonthDay,
|
||
|
$DATASET => $dataSetNo++
|
||
|
],
|
||
|
$expects,
|
||
|
$execTime
|
||
|
];
|
||
|
|
||
|
// rfc example 21 BUT only day WE
|
||
|
$time = microtime( true );
|
||
|
$start = DateTimeFactory::factory( '20200801T090000', 'Europe/Stockholm' );
|
||
|
$wDate = clone $start;
|
||
|
$expects = [];
|
||
|
$count = 10;
|
||
|
$interval = 2;
|
||
|
$byMonthDay = range( 10, 15 );
|
||
|
$x = 1;
|
||
|
$wDate = $wDate->modify( '1 day' );
|
||
|
while( $x < $count ) {
|
||
|
$day = (int)$wDate->format( 'j' );
|
||
|
if( 10 > $day ) {
|
||
|
$wDate = $wDate->modify( '1 day' );
|
||
|
continue;
|
||
|
}
|
||
|
if( 18 < $day ) {
|
||
|
$wDate = $wDate->setDate( // interval=2
|
||
|
(int)$wDate->format( 'Y' ),
|
||
|
( (int)$wDate->format( 'm' ) + $interval ),
|
||
|
10
|
||
|
);
|
||
|
continue;
|
||
|
}
|
||
|
if( in_array( $day, $byMonthDay, true ) &&
|
||
|
( 3 === (int)$wDate->format( 'w' ) ) ) {
|
||
|
$expects[] = $wDate->format( 'Ymd' );
|
||
|
++$x;
|
||
|
}
|
||
|
$wDate = $wDate->modify( '1 day' );
|
||
|
} // end while
|
||
|
$execTime = microtime( true ) - $time;
|
||
|
$dataArr[] = [
|
||
|
'29-21-18B',
|
||
|
$start,
|
||
|
( clone $start )->modify( RecurFactory::EXTENDYEAR . ' year' ),
|
||
|
[
|
||
|
IcalInterface::FREQ => IcalInterface::MONTHLY,
|
||
|
IcalInterface::COUNT => $count,
|
||
|
IcalInterface::INTERVAL => $interval,
|
||
|
IcalInterface::BYMONTHDAY => $byMonthDay,
|
||
|
IcalInterface::BYDAY => [ 'DAY' => 'WE' ],
|
||
|
$DATASET => $dataSetNo++
|
||
|
],
|
||
|
$expects,
|
||
|
$execTime
|
||
|
];
|
||
|
return $dataArr;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Testing recurMonthly1 without BYSETPOS
|
||
|
*
|
||
|
* @test
|
||
|
* @dataProvider recurMonthly1aProvider
|
||
|
* @param int|string $case
|
||
|
* @param DateTime $start
|
||
|
* @param DateTime $end
|
||
|
* @param mixed[] $recur
|
||
|
* @param mixed[] $expects
|
||
|
* @param float $prepTime
|
||
|
* @throws Exception
|
||
|
*/
|
||
|
public function recurMonthly1aTest(
|
||
|
int | string $case,
|
||
|
DateTime $start,
|
||
|
DateTime $end,
|
||
|
array $recur,
|
||
|
array $expects,
|
||
|
float $prepTime
|
||
|
) : void
|
||
|
{
|
||
|
$this->recurMonthly1XTest(
|
||
|
$case,
|
||
|
$start,
|
||
|
$end,
|
||
|
$recur,
|
||
|
$expects,
|
||
|
$prepTime
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* recurMonthly1bTest provider
|
||
|
*
|
||
|
* @return mixed[]
|
||
|
* @throws Exception
|
||
|
*/
|
||
|
public function recurMonthly1bProvider() : array
|
||
|
{
|
||
|
$dataArr = [];
|
||
|
$dataSetNo = 0;
|
||
|
$DATASET = 'DATASET';
|
||
|
|
||
|
$count = 10;
|
||
|
$interval = 2;
|
||
|
|
||
|
// rfc example 21 BUT only FIRST day WE in extended day period 8-22
|
||
|
$start = DateTimeFactory::factory( '20200801T090000', 'Europe/Stockholm');
|
||
|
$byMonthDay = range( 8,22 );
|
||
|
$expects = [
|
||
|
20200812, 20201014, 20201209, 20210210, 20210414, 20210609, 20210811, 20211013, 20211208
|
||
|
];
|
||
|
$dataArr[] = [
|
||
|
'29-21-18C',
|
||
|
$start,
|
||
|
(clone $start)->modify( RecurFactory::EXTENDYEAR . ' year' ),
|
||
|
[
|
||
|
IcalInterface::FREQ => IcalInterface::MONTHLY,
|
||
|
IcalInterface::COUNT => $count,
|
||
|
IcalInterface::INTERVAL => $interval,
|
||
|
IcalInterface::BYMONTHDAY => $byMonthDay,
|
||
|
IcalInterface::BYDAY => [ 'DAY' => 'WE' ],
|
||
|
IcalInterface::BYSETPOS => 1,
|
||
|
$DATASET => $dataSetNo++
|
||
|
],
|
||
|
$expects,
|
||
|
0.0
|
||
|
];
|
||
|
|
||
|
// rfc example 21 BUT only LAST day WE in extended day period 8-22
|
||
|
$start = DateTimeFactory::factory( '20200801T090000', 'Europe/Stockholm');
|
||
|
$byMonthDay = range( 8,22 );
|
||
|
$expects = [
|
||
|
20200819, 20201021, 20201216, 20210217, 20210421, 20210616, 20210818, 20211020, 20211222
|
||
|
];
|
||
|
$dataArr[] = [
|
||
|
'29-21-18D',
|
||
|
$start,
|
||
|
(clone $start)->modify( RecurFactory::EXTENDYEAR . ' year' ),
|
||
|
[
|
||
|
IcalInterface::FREQ => IcalInterface::MONTHLY,
|
||
|
IcalInterface::COUNT => $count,
|
||
|
IcalInterface::INTERVAL => $interval,
|
||
|
IcalInterface::BYMONTHDAY => $byMonthDay,
|
||
|
IcalInterface::BYDAY => [ 'DAY' => 'WE' ],
|
||
|
IcalInterface::BYSETPOS => -1,
|
||
|
$DATASET => $dataSetNo++
|
||
|
],
|
||
|
$expects,
|
||
|
0.0
|
||
|
];
|
||
|
|
||
|
// rfc example 21 BUT only second day WE in extended day period 8-22
|
||
|
$start = DateTimeFactory::factory( '20200801T090000', 'Europe/Stockholm');
|
||
|
$byMonthDay = range( 8,22 );
|
||
|
$expects = [
|
||
|
20200819, 20201021, 20201216, 20210217, 20210421, 20210616, 20210818, 20211020, 20211215
|
||
|
];
|
||
|
$dataArr[] = [
|
||
|
'29-21-18E',
|
||
|
$start,
|
||
|
(clone $start)->modify( RecurFactory::EXTENDYEAR . ' year' ),
|
||
|
[
|
||
|
IcalInterface::FREQ => IcalInterface::MONTHLY,
|
||
|
IcalInterface::COUNT => $count,
|
||
|
IcalInterface::INTERVAL => $interval,
|
||
|
IcalInterface::BYMONTHDAY => $byMonthDay,
|
||
|
IcalInterface::BYDAY => [ 'DAY' => 'WE' ],
|
||
|
IcalInterface::BYSETPOS => 2,
|
||
|
$DATASET => $dataSetNo++
|
||
|
],
|
||
|
$expects,
|
||
|
0.0
|
||
|
];
|
||
|
|
||
|
// rfc example 21 BUT only LAST second day WE in extended day period 8-22
|
||
|
$start = DateTimeFactory::factory( '20200801T090000', 'Europe/Stockholm');
|
||
|
$byMonthDay = range( 8,22 );
|
||
|
$expects = [
|
||
|
20200812, 20201014, 20201209, 20210210, 20210414, 20210609, 20210811, 20211013, 20211215
|
||
|
];
|
||
|
$dataArr[] = [
|
||
|
'29-21-18F',
|
||
|
$start,
|
||
|
(clone $start)->modify( RecurFactory::EXTENDYEAR . ' year' ),
|
||
|
[
|
||
|
IcalInterface::FREQ => IcalInterface::MONTHLY,
|
||
|
IcalInterface::COUNT => $count,
|
||
|
IcalInterface::INTERVAL => $interval,
|
||
|
IcalInterface::BYMONTHDAY => $byMonthDay,
|
||
|
IcalInterface::BYDAY => [ 'DAY' => 'WE' ],
|
||
|
IcalInterface::BYSETPOS => -2,
|
||
|
$DATASET => $dataSetNo++
|
||
|
],
|
||
|
$expects,
|
||
|
0.0
|
||
|
];
|
||
|
|
||
|
// Latest second and third workday in month before day 26 for onr year
|
||
|
$start = DateTimeFactory::factory( '20000701T090000', 'Europe/Stockholm');
|
||
|
$byMonthDay = range( 18,25 );
|
||
|
$expects = [
|
||
|
20000719,20000725,20000821,20000825,20000919,20000925,20001019,20001025,20001120,20001124,20001219,20001225,
|
||
|
20010119,20010125,20010219,20010223,20010319,20010323,20010419,20010425,20010521,20010525,20010619
|
||
|
];
|
||
|
$dataArr[] = [
|
||
|
'31',
|
||
|
$start,
|
||
|
(clone $start)->modify( RecurFactory::EXTENDYEAR . ' year' ),
|
||
|
[
|
||
|
IcalInterface::FREQ => IcalInterface::MONTHLY,
|
||
|
IcalInterface::COUNT => 24,
|
||
|
IcalInterface::BYMONTHDAY => $byMonthDay,
|
||
|
IcalInterface::BYDAY => [
|
||
|
[ 'DAY' => 'MO' ],
|
||
|
[ 'DAY' => 'TU' ],
|
||
|
[ 'DAY' => 'WE' ],
|
||
|
[ 'DAY' => 'TH' ],
|
||
|
[ 'DAY' => 'FR' ],
|
||
|
],
|
||
|
IcalInterface::BYSETPOS => [ -1, -5 ],
|
||
|
$DATASET => $dataSetNo++
|
||
|
],
|
||
|
$expects,
|
||
|
0.0
|
||
|
];
|
||
|
|
||
|
return $dataArr;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Testing recurMonthly1 with BYSETPOS
|
||
|
*
|
||
|
* @test
|
||
|
* @dataProvider recurMonthly1bProvider
|
||
|
* @param int|string $case
|
||
|
* @param DateTime $start
|
||
|
* @param DateTime $end
|
||
|
* @param mixed[] $recur
|
||
|
* @param mixed[] $expects
|
||
|
* @param float $prepTime
|
||
|
* @throws Exception
|
||
|
*/
|
||
|
public function recurMonthly1bTest(
|
||
|
int | string $case,
|
||
|
DateTime $start,
|
||
|
DateTime $end,
|
||
|
array $recur,
|
||
|
array $expects,
|
||
|
float $prepTime
|
||
|
) : void
|
||
|
{
|
||
|
$this->recurMonthly1XTest(
|
||
|
$case,
|
||
|
$start,
|
||
|
$end,
|
||
|
$recur,
|
||
|
$expects,
|
||
|
$prepTime
|
||
|
);
|
||
|
}
|
||
|
/**
|
||
|
* Testing recurMonthly1 with/without BYSETPOS
|
||
|
*
|
||
|
* @dataProvider recurMonthly1aProvider
|
||
|
* @param int|string $case
|
||
|
* @param DateTime $start
|
||
|
* @param DateTime $end
|
||
|
* @param mixed[] $recur
|
||
|
* @param mixed[] $expects
|
||
|
* @param float $prepTime
|
||
|
* @throws Exception
|
||
|
*/
|
||
|
public function recurMonthly1XTest(
|
||
|
int | string $case,
|
||
|
DateTime $start,
|
||
|
DateTime $end,
|
||
|
array $recur,
|
||
|
array $expects,
|
||
|
float $prepTime
|
||
|
) : void
|
||
|
{
|
||
|
$saveStartDate = clone $start;
|
||
|
$strCase = str_pad( $case, 12 );
|
||
|
|
||
|
if( in_array( $case, [ '29-21-18C', '29-21-18D', '29-21-18E', '29-21-18F', '31' ], true ) ) {
|
||
|
$result = array_flip( $expects );
|
||
|
if( defined( 'DISPRECUR' ) && ( '1' === DISPRECUR )) {
|
||
|
echo $strCase . 'expects time:' . number_format( $prepTime, 6 ) .
|
||
|
' : ' . implode( ' - ', $expects ) . ' count: ' . count( $expects ) . PHP_EOL; // test ###
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
$result = $this->recur2dateTest(
|
||
|
$case,
|
||
|
$start,
|
||
|
$end,
|
||
|
$recur,
|
||
|
$expects,
|
||
|
$prepTime
|
||
|
);
|
||
|
}
|
||
|
|
||
|
if( ! isset( $recur[IcalInterface::INTERVAL] )) {
|
||
|
$recur[IcalInterface::INTERVAL] = 1;
|
||
|
}
|
||
|
$recurDisp = str_replace( [PHP_EOL, ' ' ], '', var_export( $recur, true ));
|
||
|
if( ! RecurFactory2::isRecurMonthly1( $recur )) {
|
||
|
if( defined( 'DISPRECUR' ) && ( '1' === DISPRECUR )) {
|
||
|
echo $strCase . ' NOT isRecurMonthly1 ' . $recurDisp . PHP_EOL;
|
||
|
}
|
||
|
$this->fail();
|
||
|
} // end if
|
||
|
$time = microtime( true );
|
||
|
$resultX = RecurFactory2::recurMonthly1( $recur, $start, clone $start, $end );
|
||
|
$execTime = microtime( true ) - $time;
|
||
|
if( defined( 'DISPRECUR' ) && ( '1' === DISPRECUR )) {
|
||
|
echo $strCase . 'mnth smpl1 time:' . number_format( $execTime, 6 ) . ' : ' .
|
||
|
implode( ' - ', array_keys( $resultX ) ) . ' count: ' . count( $resultX ) . PHP_EOL; // test ###
|
||
|
echo $recurDisp . ' start ' . $start->format( 'Ymd' ) . ' end ' . $end->format( 'Ymd' ) . PHP_EOL; // test ###
|
||
|
}
|
||
|
$this->assertEquals(
|
||
|
array_keys( $result ),
|
||
|
array_keys( $resultX ),
|
||
|
sprintf( self::$ERRFMT, __FUNCTION__, $case . '-21',
|
||
|
$saveStartDate->format( 'Ymd' ),
|
||
|
$end->format( 'Ymd' ),
|
||
|
$recurDisp
|
||
|
)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* getRecurByDaysInMonthTest provider
|
||
|
*
|
||
|
* @return mixed[]
|
||
|
*/
|
||
|
public function getRecurByDaysInMonthProvider() : array
|
||
|
{
|
||
|
$dataArr = [];
|
||
|
|
||
|
$dataArr[] = [
|
||
|
11,
|
||
|
[ IcalInterface::DAY => IcalInterface::MO ],
|
||
|
2020,
|
||
|
8,
|
||
|
[ 3, 10, 17, 24, 31 ] // exp
|
||
|
];
|
||
|
|
||
|
$dataArr[] = [
|
||
|
21,
|
||
|
[ 3, IcalInterface::DAY => IcalInterface::MO ],
|
||
|
2020,
|
||
|
8,
|
||
|
[ 17 ] // exp
|
||
|
];
|
||
|
|
||
|
$dataArr[] = [
|
||
|
22,
|
||
|
[ -2, IcalInterface::DAY => IcalInterface::MO ],
|
||
|
2020,
|
||
|
8,
|
||
|
[ 24 ] // exp
|
||
|
];
|
||
|
|
||
|
$dataArr[] = [
|
||
|
23,
|
||
|
[ -2, IcalInterface::DAY => IcalInterface::SA ],
|
||
|
2020,
|
||
|
2,
|
||
|
[ 22 ] // exp
|
||
|
];
|
||
|
|
||
|
$dataArr[] = [
|
||
|
31,
|
||
|
[
|
||
|
[ IcalInterface::DAY => IcalInterface::MO ],
|
||
|
[ IcalInterface::DAY => IcalInterface::FR ],
|
||
|
],
|
||
|
2020,
|
||
|
8,
|
||
|
[ 3, 7, 10, 14, 17, 21, 24, 28, 31 ] // exp
|
||
|
];
|
||
|
|
||
|
$dataArr[] = [
|
||
|
41,
|
||
|
[
|
||
|
[ 3, IcalInterface::DAY => IcalInterface::MO ],
|
||
|
[ -3, IcalInterface::DAY => IcalInterface::FR ],
|
||
|
],
|
||
|
2020,
|
||
|
8,
|
||
|
[ 14, 17 ] // exp
|
||
|
];
|
||
|
|
||
|
$dataArr[] = [
|
||
|
42,
|
||
|
[
|
||
|
[ 1, IcalInterface::DAY => IcalInterface::MO ],
|
||
|
[ 2, IcalInterface::DAY => IcalInterface::TU ],
|
||
|
[ 3, IcalInterface::DAY => IcalInterface::WE ],
|
||
|
[ 4, IcalInterface::DAY => IcalInterface::TH ],
|
||
|
[ 5, IcalInterface::DAY => IcalInterface::FR ],
|
||
|
],
|
||
|
2020,
|
||
|
8,
|
||
|
[ 3, 11, 19, 27 ] // exp
|
||
|
];
|
||
|
|
||
|
$dataArr[] = [
|
||
|
43,
|
||
|
[
|
||
|
[ -1, IcalInterface::DAY => IcalInterface::SU ],
|
||
|
[ -2, IcalInterface::DAY => IcalInterface::SA ],
|
||
|
[ -3, IcalInterface::DAY => IcalInterface::FR ],
|
||
|
[ -4, IcalInterface::DAY => IcalInterface::TH ],
|
||
|
[ -5, IcalInterface::DAY => IcalInterface::WE ],
|
||
|
],
|
||
|
2020,
|
||
|
8,
|
||
|
[ 6, 14, 22, 30 ] // exp
|
||
|
];
|
||
|
|
||
|
$dataArr[] = [
|
||
|
44,
|
||
|
[
|
||
|
[ 1, IcalInterface::DAY => IcalInterface::MO ],
|
||
|
[ 2, IcalInterface::DAY => IcalInterface::TU ],
|
||
|
[ 3, IcalInterface::DAY => IcalInterface::WE ],
|
||
|
[ 4, IcalInterface::DAY => IcalInterface::TH ],
|
||
|
[ 5, IcalInterface::DAY => IcalInterface::FR ],
|
||
|
[ -1, IcalInterface::DAY => IcalInterface::SU ],
|
||
|
[ -2, IcalInterface::DAY => IcalInterface::SA ],
|
||
|
[ -3, IcalInterface::DAY => IcalInterface::FR ],
|
||
|
[ -4, IcalInterface::DAY => IcalInterface::TH ],
|
||
|
[ -5, IcalInterface::DAY => IcalInterface::WE ],
|
||
|
],
|
||
|
2020,
|
||
|
8,
|
||
|
[ 3, 6, 11, 14, 19, 22, 27, 30 ] // exp
|
||
|
];
|
||
|
|
||
|
return $dataArr;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @test
|
||
|
* @dataProvider getRecurByDaysInMonthProvider
|
||
|
* @param int|string $case
|
||
|
* @param mixed[] $recurByDay
|
||
|
* @param int $year
|
||
|
* @param int $month
|
||
|
* @param mixed[] $exp
|
||
|
* @throws Exception
|
||
|
*/
|
||
|
public function getRecurByDaysInMonthTest( int | string $case, array $recurByDay, int $year, int $month, array $exp ) : void
|
||
|
{
|
||
|
$list = RecurFactory2::getRecurByDaysInMonth( $recurByDay, $year, $month );
|
||
|
|
||
|
$this->assertEquals( $exp, $list,
|
||
|
$case . ' exp: ' .implode( ', ', $exp ) . ' - got: ' .implode( ', ', $list )
|
||
|
);
|
||
|
|
||
|
if( defined( 'DISPRECUR' ) && ( '1' === DISPRECUR )) {
|
||
|
echo $case . ' : ' . $year . ' - ' . $month . ' recur : ' . str_replace( [ PHP_EOL, ' ' ], '', var_export( $recurByDay, true ) ) . PHP_EOL; // test ###
|
||
|
echo $case . ' result : ' . implode( ', ', $list ) . PHP_EOL; // test ###
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* recurMonthly1Test provider
|
||
|
*
|
||
|
* @return mixed[]
|
||
|
* @throws Exception
|
||
|
*/
|
||
|
public function recurMonthly2Provider() : array
|
||
|
{
|
||
|
$dataArr = [];
|
||
|
$dataSetNo = 0;
|
||
|
$DATASET = 'DATASET';
|
||
|
|
||
|
$start = DateTimeFactory::factory( '20190101T0900', 'Europe/Stockholm');
|
||
|
$wDate = clone $start;
|
||
|
$expects = [
|
||
|
20190105, 20190106, 20190112, 20190113, 20190119, 20190120, 20190126, 20190127, 20190202, 20190203,
|
||
|
20190209, 20190210, 20190216, 20190217, 20190223, 20190224, 20190302, 20190303, 20190309
|
||
|
];
|
||
|
$count = 20;
|
||
|
$dataArr[] = [
|
||
|
'26',
|
||
|
$start,
|
||
|
$wDate->modify( RecurFactory::EXTENDYEAR . ' year' ),
|
||
|
[
|
||
|
IcalInterface::FREQ => IcalInterface::MONTHLY,
|
||
|
IcalInterface::COUNT => $count,
|
||
|
IcalInterface::BYDAY => [
|
||
|
[ IcalInterface::DAY => IcalInterface::SA ],
|
||
|
[ IcalInterface::DAY => IcalInterface::SU ]
|
||
|
],
|
||
|
$DATASET => $dataSetNo++
|
||
|
],
|
||
|
$expects
|
||
|
];
|
||
|
|
||
|
// rfc example 14
|
||
|
$start = DateTimeFactory::factory( '20190101T090000', 'Europe/Stockholm');
|
||
|
$wDate = clone $start;
|
||
|
$expects = [ 20190104, 20190201, 20190301, 20190405, 20190503, 20190607, 20190705, 20190802, 20190906, 20191004 ];
|
||
|
$count = 10;
|
||
|
$dataArr[] = [
|
||
|
'29-14',
|
||
|
$start,
|
||
|
$wDate->modify( RecurFactory::EXTENDYEAR . ' year' ),
|
||
|
[
|
||
|
IcalInterface::FREQ => IcalInterface::MONTHLY,
|
||
|
IcalInterface::COUNT => $count,
|
||
|
IcalInterface::BYDAY => [ 1, IcalInterface::DAY => IcalInterface::FR ],
|
||
|
$DATASET => $dataSetNo++
|
||
|
],
|
||
|
$expects
|
||
|
];
|
||
|
|
||
|
// rfc example 16
|
||
|
$start = DateTimeFactory::factory( '20190101T090000', 'Europe/Stockholm');
|
||
|
$wDate = clone $start;
|
||
|
$expects = [ 20190104, 20190125, 20190301, 20190329, 20190503, 20190531, 20190705, 20190726, 20190906, 20190927 ];
|
||
|
$count = 10;
|
||
|
$dataArr[] = [
|
||
|
'29-16-2',
|
||
|
$start,
|
||
|
$wDate->modify( RecurFactory::EXTENDYEAR . ' year' ),
|
||
|
[
|
||
|
IcalInterface::FREQ => IcalInterface::MONTHLY,
|
||
|
IcalInterface::INTERVAL => 2,
|
||
|
IcalInterface::COUNT => $count,
|
||
|
IcalInterface::BYDAY => [
|
||
|
[ 1, IcalInterface::DAY => IcalInterface::FR ],
|
||
|
[ -1, IcalInterface::DAY => IcalInterface::FR ],
|
||
|
],
|
||
|
$DATASET => $dataSetNo++
|
||
|
],
|
||
|
$expects
|
||
|
];
|
||
|
|
||
|
// rfc example 17
|
||
|
$start = DateTimeFactory::factory( '20190101T090000', 'Europe/Stockholm');
|
||
|
$wDate = clone $start;
|
||
|
$expects = [ 20190121, 20190218, 20190318, 20190422, 20190520, 20190617 ];
|
||
|
$count = 6;
|
||
|
$dataArr[] = [
|
||
|
'29-17',
|
||
|
$start,
|
||
|
$wDate->modify( RecurFactory::EXTENDYEAR . ' year' ),
|
||
|
[
|
||
|
IcalInterface::FREQ => IcalInterface::MONTHLY,
|
||
|
IcalInterface::COUNT => $count,
|
||
|
IcalInterface::BYDAY => [ -2, IcalInterface::DAY => IcalInterface::MO ],
|
||
|
$DATASET => $dataSetNo++
|
||
|
],
|
||
|
$expects
|
||
|
];
|
||
|
|
||
|
// rfc line 2375
|
||
|
$start = DateTimeFactory::factory( '20190101T090000', 'Europe/Stockholm');
|
||
|
$wDate = clone $start;
|
||
|
$expects = [ 20190131, 20190228, 20190329, 20190430, 20190531 ]; // all but first
|
||
|
$count = 6;
|
||
|
$dataArr[] = [
|
||
|
'2375',
|
||
|
$start,
|
||
|
$wDate->modify( RecurFactory::EXTENDYEAR . ' year' ),
|
||
|
[
|
||
|
IcalInterface::FREQ => IcalInterface::MONTHLY,
|
||
|
IcalInterface::COUNT => $count,
|
||
|
IcalInterface::BYDAY => [
|
||
|
[ IcalInterface::DAY => IcalInterface::MO ],
|
||
|
[ IcalInterface::DAY => IcalInterface::TU ],
|
||
|
[ IcalInterface::DAY => IcalInterface::WE ],
|
||
|
[ IcalInterface::DAY => IcalInterface::TH ],
|
||
|
[ IcalInterface::DAY => IcalInterface::FR ],
|
||
|
],
|
||
|
IcalInterface::BYSETPOS => -1,
|
||
|
$DATASET => $dataSetNo++
|
||
|
],
|
||
|
$expects
|
||
|
];
|
||
|
|
||
|
// rfc line 2375 but third and last third workday in month
|
||
|
$start = DateTimeFactory::factory( '20190101T090000', 'Europe/Stockholm');
|
||
|
$wDate = clone $start;
|
||
|
$expects = [ 20190103, 20190129, 20190205, 20190226, 20190305, 20190327, 20190403, 20190426, 20190503 ]; // all but first
|
||
|
$count = 10;
|
||
|
$dataArr[] = [
|
||
|
'2375B',
|
||
|
$start,
|
||
|
$wDate->modify( RecurFactory::EXTENDYEAR . ' year' ), // end
|
||
|
[
|
||
|
IcalInterface::FREQ => IcalInterface::MONTHLY,
|
||
|
IcalInterface::COUNT => $count,
|
||
|
IcalInterface::BYDAY => [
|
||
|
[ IcalInterface::DAY => IcalInterface::MO ],
|
||
|
[ IcalInterface::DAY => IcalInterface::TU ],
|
||
|
[ IcalInterface::DAY => IcalInterface::WE ],
|
||
|
[ IcalInterface::DAY => IcalInterface::TH ],
|
||
|
[ IcalInterface::DAY => IcalInterface::FR ],
|
||
|
],
|
||
|
IcalInterface::BYSETPOS => [ 3, -3 ],
|
||
|
$DATASET => $dataSetNo++
|
||
|
],
|
||
|
$expects
|
||
|
];
|
||
|
|
||
|
// rfc line 7266 but timezone sthlm and count 6
|
||
|
$start = DateTimeFactory::factory( '19970929T090000', 'Europe/Stockholm');
|
||
|
$wDate = clone $start;
|
||
|
$expects = [ 19971030, 19971127, 19971230, 19980129, 19980226 ];
|
||
|
$dataArr[] = [
|
||
|
'7266',
|
||
|
$start,
|
||
|
$wDate->modify( RecurFactory::EXTENDYEAR . ' year' ), // end
|
||
|
[
|
||
|
IcalInterface::FREQ => IcalInterface::MONTHLY,
|
||
|
IcalInterface::COUNT => 6,
|
||
|
IcalInterface::BYDAY => [
|
||
|
[ IcalInterface::DAY => IcalInterface::MO ],
|
||
|
[ IcalInterface::DAY => IcalInterface::TU ],
|
||
|
[ IcalInterface::DAY => IcalInterface::WE ],
|
||
|
[ IcalInterface::DAY => IcalInterface::TH ],
|
||
|
[ IcalInterface::DAY => IcalInterface::FR ],
|
||
|
],
|
||
|
IcalInterface::BYSETPOS => -2,
|
||
|
$DATASET => $dataSetNo++
|
||
|
],
|
||
|
$expects
|
||
|
];
|
||
|
|
||
|
// rfc line 7258 but timezone sthlm and count 6
|
||
|
$start = DateTimeFactory::factory( '19970904T090000', 'Europe/Stockholm');
|
||
|
$wDate = clone $start;
|
||
|
$expects = [ 19971007,19971106,19971204,19980107,19980205 ];
|
||
|
$dataArr[] = [
|
||
|
'7258',
|
||
|
$start,
|
||
|
$wDate->modify( RecurFactory::EXTENDYEAR . ' year' ), // end
|
||
|
[
|
||
|
IcalInterface::FREQ => IcalInterface::MONTHLY,
|
||
|
IcalInterface::COUNT => 6,
|
||
|
IcalInterface::BYDAY => [
|
||
|
[ IcalInterface::DAY => IcalInterface::TU ],
|
||
|
[ IcalInterface::DAY => IcalInterface::WE ],
|
||
|
[ IcalInterface::DAY => IcalInterface::TH ],
|
||
|
],
|
||
|
IcalInterface::BYSETPOS => 3,
|
||
|
$DATASET => $dataSetNo++
|
||
|
],
|
||
|
$expects
|
||
|
];
|
||
|
|
||
|
// neotsn Thanksgiving event - 4th Thursday of every November - Yearly - same in recurYearly2Test by YEARLY
|
||
|
$start = DateTimeFactory::factory( '20201126T113000', 'America/Chicago');
|
||
|
$wDate = clone $start;
|
||
|
$dataArr[] = [
|
||
|
'neotsn',
|
||
|
$start,
|
||
|
$wDate->modify( 10 . ' year' ), // end
|
||
|
[
|
||
|
IcalInterface::FREQ => IcalInterface::MONTHLY,
|
||
|
IcalInterface::INTERVAL => 12,
|
||
|
IcalInterface::BYDAY => [
|
||
|
[ IcalInterface::DAY => IcalInterface::TH ],
|
||
|
],
|
||
|
IcalInterface::BYSETPOS => 4,
|
||
|
$DATASET => $dataSetNo++
|
||
|
],
|
||
|
[ 20211125,20221124,20231123,20241128,20251127,20261126,20271125,20281123,20291122 ]
|
||
|
];
|
||
|
|
||
|
return $dataArr;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Testing recurMonthly2 i.e recurMonthlyYearly3
|
||
|
*
|
||
|
* @test
|
||
|
* @dataProvider recurMonthly2Provider
|
||
|
* @param string $case
|
||
|
* @param DateTime $start
|
||
|
* @param DateTime|array $end
|
||
|
* @param array $recur
|
||
|
* @param array $expects
|
||
|
* @throws Exception
|
||
|
*/
|
||
|
public function recurMonthly2Test(
|
||
|
string $case,
|
||
|
DateTime $start,
|
||
|
DateTime | array $end,
|
||
|
array $recur,
|
||
|
array $expects
|
||
|
) : void
|
||
|
{
|
||
|
$saveStartDate = clone $start;
|
||
|
|
||
|
$result = $expects;
|
||
|
|
||
|
if( ! isset( $recur[IcalInterface::INTERVAL] )) {
|
||
|
$recur[IcalInterface::INTERVAL] = 1;
|
||
|
}
|
||
|
$strCase = str_pad( $case, 12 );
|
||
|
$recurDisp = str_replace( [PHP_EOL, ' ' ], '', var_export( $recur, true ));
|
||
|
if( ! RecurFactory2::isRecurMonthly2( $recur )) {
|
||
|
if( defined( 'DISPRECUR' ) && ( '1' === DISPRECUR )) {
|
||
|
echo $strCase . ' NOT isRecurMonthly2 ' . $recurDisp . PHP_EOL;
|
||
|
}
|
||
|
$this->fail();
|
||
|
} // end if
|
||
|
$time = microtime( true );
|
||
|
// $resultX = RecurFactory2::recurMonthly2( $recur, $start, clone $start, $end );
|
||
|
$resultX = RecurFactory2::recurMonthlyYearly3( $recur, $start, clone $start, $end );
|
||
|
$execTime = microtime( true ) - $time;
|
||
|
if( defined( 'DISPRECUR' ) && ( '1' === DISPRECUR )) {
|
||
|
echo $strCase . 'mnth smpl2 time:' . number_format( $execTime, 6 ) . ' : ' .
|
||
|
implode( ' - ', array_keys( $resultX ) ) . PHP_EOL; // test ###
|
||
|
echo $recurDisp . PHP_EOL; // test ###
|
||
|
}
|
||
|
$this->assertEquals(
|
||
|
$result, // array_keys( $result ),
|
||
|
array_keys( $resultX ),
|
||
|
sprintf( self::$ERRFMT, __FUNCTION__, $case . '-21',
|
||
|
$saveStartDate->format( 'Ymd' ),
|
||
|
$end->format( 'Ymd' ),
|
||
|
PHP_EOL . $recurDisp .
|
||
|
PHP_EOL . 'exp : ' . implode( ',', $expects ) .
|
||
|
PHP_EOL . 'got : ' . implode( ',', array_keys( $resultX ))
|
||
|
)
|
||
|
);
|
||
|
}
|
||
|
}
|