From 70e30e14e0b23b6cf909f9d13652ae0d7ce0bbab Mon Sep 17 00:00:00 2001 From: Owen Leibman Date: Thu, 18 Mar 2021 17:49:34 -0700 Subject: [PATCH 01/12] Complete Breakup Of Calculation/DateTime Functions In conjunction with parallel breakups happening in other areas of Calculation, this change breaks up all the DateTime functions into their own classes. All methods remaining in DateTime itself have a doc block deprecation notice, and consist only of stub code to call the replacement methods. Coverage of DateTime itself and all the replacement methods is 100%. There is only one substantive change to the code (see next paragraph). Among the non-substantive changes, it now adopts the same parsing technique (throwing and catching exceptions) already in use in Engineering and MathTrig. Boolean parameters are allowed in lieu of numbers when Excel allows them. Most of the code changes involve refactoring due to the need to avoid Scrutinizer "complexity" failures in what it will consider to be new methods. Issue #1936 was opened just as I was staging this. It is now fixed. One existing WORKDAY test was wrong (noted in a comment in the test data file), and a bunch of new tests are added. I found it confusing to use DateTime as a node of the the class name since most of the methods invoke native DateTime methods. So, everything is moved to directory DateTimeExcel, and that is what is used in the class names. There are several follow-up activities that I am planning to undertake if this PR is merged. - ODS supports dates well before 1900. There are exactly 2 assertions for this functionality. More are needed (and some functions might have to change to accept this). - WEEKDAY has some poorly documented extra options for "style" which are not yet implemented. - Most tests have been changed to use a formula as entered on a spreadsheet rather than a direct call to the method which implements the formula. There are 3 exceptions at this time. WORKDAY and NETWORKDAYS, which include arrays as part of their parameters, are more complicated than most. YEARFRAC was just too large to deal with now. - There are direct calls to the now-deprecated methods in both source code and tests, mostly in Financial code, but possibly in others as well. These need to be changed. - Some constants, none "officially" documented, remain in the original class. These should be either deleted or marked deprecated. I wasn't sure if deprecation was even possible (or desirable), and did not want that to be something which would cause Scrutinizer to fail the change. --- .../Calculation/Calculation.php | 46 +- src/PhpSpreadsheet/Calculation/DateTime.php | 1148 ++--------------- .../Calculation/DateTimeExcel/Datedif.php | 152 +++ .../Calculation/DateTimeExcel/Datefunc.php | 168 +++ .../Calculation/DateTimeExcel/Datevalue.php | 151 +++ .../Calculation/DateTimeExcel/Day.php | 62 + .../Calculation/DateTimeExcel/Days.php | 48 + .../Calculation/DateTimeExcel/Days360.php | 106 ++ .../Calculation/DateTimeExcel/Edate.php | 45 + .../Calculation/DateTimeExcel/Eomonth.php | 47 + .../Calculation/DateTimeExcel/Helpers.php | 287 +++++ .../Calculation/DateTimeExcel/Hour.php | 44 + .../Calculation/DateTimeExcel/IsoWeeknum.php | 55 + .../Calculation/DateTimeExcel/Minute.php | 44 + .../Calculation/DateTimeExcel/Month.php | 40 + .../Calculation/DateTimeExcel/Networkdays.php | 102 ++ .../Calculation/DateTimeExcel/Now.php | 34 + .../Calculation/DateTimeExcel/Second.php | 44 + .../Calculation/DateTimeExcel/Time.php | 116 ++ .../Calculation/DateTimeExcel/Timevalue.php | 61 + .../Calculation/DateTimeExcel/Today.php | 34 + .../Calculation/DateTimeExcel/Weekday.php | 80 ++ .../Calculation/DateTimeExcel/Weeknum.php | 160 +++ .../Calculation/DateTimeExcel/Workday.php | 182 +++ .../Calculation/DateTimeExcel/Year.php | 40 + .../Calculation/DateTimeExcel/Yearfrac.php | 97 ++ .../Functions/DateTime/AllSetupTeardown.php | 71 + .../Functions/DateTime/DateDifTest.php | 26 +- .../Functions/DateTime/DateTest.php | 56 +- .../Functions/DateTime/DateValueTest.php | 53 +- .../Functions/DateTime/DayTest.php | 59 +- .../Functions/DateTime/Days360Test.php | 27 +- .../Functions/DateTime/DaysTest.php | 35 +- .../Functions/DateTime/EDateTest.php | 33 +- .../Functions/DateTime/EoMonthTest.php | 36 +- .../Functions/DateTime/HourTest.php | 24 +- .../Functions/DateTime/IsoWeekNumTest.php | 44 +- .../Functions/DateTime/MinuteTest.php | 24 +- .../Functions/DateTime/MonthTest.php | 24 +- .../Functions/DateTime/MovedFunctionsTest.php | 63 + .../Functions/DateTime/NetworkDaysTest.php | 16 +- .../Functions/DateTime/NowTest.php | 8 +- .../Functions/DateTime/SecondTest.php | 24 +- .../Functions/DateTime/TimeTest.php | 52 +- .../Functions/DateTime/TimeValueTest.php | 28 +- .../Functions/DateTime/TodayTest.php | 34 + .../Functions/DateTime/WeekDayTest.php | 35 +- .../Functions/DateTime/WeekNumTest.php | 51 +- .../Functions/DateTime/WorkDayTest.php | 12 +- .../Functions/DateTime/YearFracTest.php | 16 +- .../Functions/DateTime/YearTest.php | 24 +- tests/data/Calculation/DateTime/DATE.php | 393 ++---- tests/data/Calculation/DateTime/DATEDIF.php | 528 ++------ tests/data/Calculation/DateTime/DATEVALUE.php | 379 ++---- tests/data/Calculation/DateTime/DAY.php | 81 +- .../Calculation/DateTime/DAYOpenOffice.php | 19 + tests/data/Calculation/DateTime/DAYS.php | 97 +- tests/data/Calculation/DateTime/DAYS360.php | 174 +-- tests/data/Calculation/DateTime/EDATE.php | 80 +- tests/data/Calculation/DateTime/EOMONTH.php | 92 +- tests/data/Calculation/DateTime/HOUR.php | 65 +- .../data/Calculation/DateTime/ISOWEEKNUM.php | 69 +- .../Calculation/DateTime/ISOWEEKNUM1904.php | 33 + tests/data/Calculation/DateTime/MINUTE.php | 65 +- tests/data/Calculation/DateTime/MONTH.php | 68 +- tests/data/Calculation/DateTime/SECOND.php | 65 +- tests/data/Calculation/DateTime/TIME.php | 112 +- tests/data/Calculation/DateTime/TIMEVALUE.php | 70 +- tests/data/Calculation/DateTime/WEEKDAY.php | 156 +-- tests/data/Calculation/DateTime/WEEKNUM.php | 275 ++-- .../data/Calculation/DateTime/WEEKNUM1904.php | 92 ++ tests/data/Calculation/DateTime/WORKDAY.php | 18 +- tests/data/Calculation/DateTime/YEAR.php | 62 +- tests/data/Calculation/DateTime/YEARFRAC.php | 1 + 74 files changed, 3540 insertions(+), 3722 deletions(-) create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/Datefunc.php create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/Datevalue.php create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/Day.php create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/Days.php create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/Days360.php create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/Edate.php create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/Eomonth.php create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/Hour.php create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/IsoWeeknum.php create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/Minute.php create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/Month.php create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/Networkdays.php create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/Now.php create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/Second.php create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/Time.php create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/Timevalue.php create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/Today.php create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/Weekday.php create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/Weeknum.php create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/Workday.php create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/Year.php create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php create mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/AllSetupTeardown.php create mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MovedFunctionsTest.php create mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TodayTest.php create mode 100644 tests/data/Calculation/DateTime/DAYOpenOffice.php create mode 100644 tests/data/Calculation/DateTime/ISOWEEKNUM1904.php create mode 100644 tests/data/Calculation/DateTime/WEEKNUM1904.php diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index e114a00d19..5f38d8b551 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -754,17 +754,17 @@ class Calculation ], 'DATE' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTime::class, 'DATE'], + 'functionCall' => [DateTimeExcel\Datefunc::class, 'funcDate'], 'argumentCount' => '3', ], 'DATEDIF' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTime::class, 'DATEDIF'], + 'functionCall' => [DateTimeExcel\Datedif::class, 'funcDatedif'], 'argumentCount' => '2,3', ], 'DATEVALUE' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTime::class, 'DATEVALUE'], + 'functionCall' => [DateTimeExcel\DateValue::class, 'funcDateValue'], 'argumentCount' => '1', ], 'DAVERAGE' => [ @@ -774,17 +774,17 @@ class Calculation ], 'DAY' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTime::class, 'DAYOFMONTH'], + 'functionCall' => [DateTimeExcel\Day::class, 'funcDay'], 'argumentCount' => '1', ], 'DAYS' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTime::class, 'DAYS'], + 'functionCall' => [DateTimeExcel\Days::class, 'funcDays'], 'argumentCount' => '2', ], 'DAYS360' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTime::class, 'DAYS360'], + 'functionCall' => [DateTimeExcel\Days360::class, 'funcDays360'], 'argumentCount' => '2,3', ], 'DB' => [ @@ -919,7 +919,7 @@ class Calculation ], 'EDATE' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTime::class, 'EDATE'], + 'functionCall' => [DateTimeExcel\Edate::class, 'funcEdate'], 'argumentCount' => '2', ], 'EFFECT' => [ @@ -934,7 +934,7 @@ class Calculation ], 'EOMONTH' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTime::class, 'EOMONTH'], + 'functionCall' => [DateTimeExcel\Eomonth::class, 'funcEomonth'], 'argumentCount' => '2', ], 'ERF' => [ @@ -1236,7 +1236,7 @@ class Calculation ], 'HOUR' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTime::class, 'HOUROFDAY'], + 'functionCall' => [DateTimeExcel\Hour::class, 'funcHour'], 'argumentCount' => '1', ], 'HYPERLINK' => [ @@ -1500,7 +1500,7 @@ class Calculation ], 'ISOWEEKNUM' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTime::class, 'ISOWEEKNUM'], + 'functionCall' => [DateTimeExcel\IsoWeeknum::class, 'funcIsoWeeknum'], 'argumentCount' => '1', ], 'ISPMT' => [ @@ -1680,7 +1680,7 @@ class Calculation ], 'MINUTE' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTime::class, 'MINUTE'], + 'functionCall' => [DateTimeExcel\Minute::class, 'funcMinute'], 'argumentCount' => '1', ], 'MINVERSE' => [ @@ -1720,7 +1720,7 @@ class Calculation ], 'MONTH' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTime::class, 'MONTHOFYEAR'], + 'functionCall' => [DateTimeExcel\Month::class, 'funcMonth'], 'argumentCount' => '1', ], 'MROUND' => [ @@ -1760,7 +1760,7 @@ class Calculation ], 'NETWORKDAYS' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTime::class, 'NETWORKDAYS'], + 'functionCall' => [DateTimeExcel\Networkdays::class, 'funcNetworkdays'], 'argumentCount' => '2-3', ], 'NETWORKDAYS.INTL' => [ @@ -1820,7 +1820,7 @@ class Calculation ], 'NOW' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTime::class, 'DATETIMENOW'], + 'functionCall' => [DateTimeExcel\Now::class, 'funcNow'], 'argumentCount' => '0', ], 'NPER' => [ @@ -2173,7 +2173,7 @@ class Calculation ], 'SECOND' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTime::class, 'SECOND'], + 'functionCall' => [DateTimeExcel\Second::class, 'funcSecond'], 'argumentCount' => '1', ], 'SEQUENCE' => [ @@ -2419,12 +2419,12 @@ class Calculation ], 'TIME' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTime::class, 'TIME'], + 'functionCall' => [DateTimeExcel\Time::class, 'funcTime'], 'argumentCount' => '3', ], 'TIMEVALUE' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTime::class, 'TIMEVALUE'], + 'functionCall' => [DateTimeExcel\Timevalue::class, 'funcTimevalue'], 'argumentCount' => '1', ], 'TINV' => [ @@ -2444,7 +2444,7 @@ class Calculation ], 'TODAY' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTime::class, 'DATENOW'], + 'functionCall' => [DateTimeExcel\Today::class, 'funcToday'], 'argumentCount' => '0', ], 'TRANSPOSE' => [ @@ -2569,12 +2569,12 @@ class Calculation ], 'WEEKDAY' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTime::class, 'WEEKDAY'], + 'functionCall' => [DateTimeExcel\Weekday::class, 'funcWeekday'], 'argumentCount' => '1,2', ], 'WEEKNUM' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTime::class, 'WEEKNUM'], + 'functionCall' => [DateTimeExcel\Weeknum::class, 'funcWeeknum'], 'argumentCount' => '1,2', ], 'WEIBULL' => [ @@ -2589,7 +2589,7 @@ class Calculation ], 'WORKDAY' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTime::class, 'WORKDAY'], + 'functionCall' => [DateTimeExcel\Workday::class, 'funcWorkday'], 'argumentCount' => '2-3', ], 'WORKDAY.INTL' => [ @@ -2624,12 +2624,12 @@ class Calculation ], 'YEAR' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTime::class, 'YEAR'], + 'functionCall' => [DateTimeExcel\Year::class, 'funcYear'], 'argumentCount' => '1', ], 'YEARFRAC' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTime::class, 'YEARFRAC'], + 'functionCall' => [DateTimeExcel\YearFrac::class, 'funcYearfrac'], 'argumentCount' => '2,3', ], 'YIELD' => [ diff --git a/src/PhpSpreadsheet/Calculation/DateTime.php b/src/PhpSpreadsheet/Calculation/DateTime.php index 64d72c2b58..2aa265d6ca 100644 --- a/src/PhpSpreadsheet/Calculation/DateTime.php +++ b/src/PhpSpreadsheet/Calculation/DateTime.php @@ -2,127 +2,36 @@ namespace PhpOffice\PhpSpreadsheet\Calculation; -use DateTimeImmutable; use DateTimeInterface; -use PhpOffice\PhpSpreadsheet\Shared\Date; -use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class DateTime { /** * Identify if a year is a leap year or not. * + * @Deprecated 2.0.0 Use the method isLeapYear in the DateTimeExcel\Helpers class instead + * * @param int|string $year The year to test * * @return bool TRUE if the year is a leap year, otherwise FALSE */ public static function isLeapYear($year) { - return (($year % 4) === 0) && (($year % 100) !== 0) || (($year % 400) === 0); - } - - /** - * Return the number of days between two dates based on a 360 day calendar. - * - * @param int $startDay Day of month of the start date - * @param int $startMonth Month of the start date - * @param int $startYear Year of the start date - * @param int $endDay Day of month of the start date - * @param int $endMonth Month of the start date - * @param int $endYear Year of the start date - * @param bool $methodUS Whether to use the US method or the European method of calculation - * - * @return int Number of days between the start date and the end date - */ - private static function dateDiff360($startDay, $startMonth, $startYear, $endDay, $endMonth, $endYear, $methodUS) - { - if ($startDay == 31) { - --$startDay; - } elseif ($methodUS && ($startMonth == 2 && ($startDay == 29 || ($startDay == 28 && !self::isLeapYear($startYear))))) { - $startDay = 30; - } - if ($endDay == 31) { - if ($methodUS && $startDay != 30) { - $endDay = 1; - if ($endMonth == 12) { - ++$endYear; - $endMonth = 1; - } else { - ++$endMonth; - } - } else { - $endDay = 30; - } - } - - return $endDay + $endMonth * 30 + $endYear * 360 - $startDay - $startMonth * 30 - $startYear * 360; + return DateTimeExcel\Helpers::isLeapYear($year); } /** * getDateValue. * + * @Deprecated 2.0.0 Use the method getDateValueNoThrow in the DateTimeExcel\Helpers class instead + * * @param mixed $dateValue * * @return mixed Excel date/time serial value, or string if error */ public static function getDateValue($dateValue) { - if (!is_numeric($dateValue)) { - if ((is_object($dateValue)) && ($dateValue instanceof DateTimeInterface)) { - $dateValue = Date::PHPToExcel($dateValue); - } else { - $saveReturnDateType = Functions::getReturnDateType(); - Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - $dateValue = self::DATEVALUE($dateValue); - Functions::setReturnDateType($saveReturnDateType); - } - } - - return $dateValue; - } - - /** - * getTimeValue. - * - * @param string $timeValue - * - * @return mixed Excel date/time serial value, or string if error - */ - private static function getTimeValue($timeValue) - { - $saveReturnDateType = Functions::getReturnDateType(); - Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - $timeValue = self::TIMEVALUE($timeValue); - Functions::setReturnDateType($saveReturnDateType); - - return $timeValue; - } - - private static function adjustDateByMonths($dateValue = 0, $adjustmentMonths = 0) - { - // Execute function - $PHPDateObject = Date::excelToDateTimeObject($dateValue); - $oMonth = (int) $PHPDateObject->format('m'); - $oYear = (int) $PHPDateObject->format('Y'); - - $adjustmentMonthsString = (string) $adjustmentMonths; - if ($adjustmentMonths > 0) { - $adjustmentMonthsString = '+' . $adjustmentMonths; - } - if ($adjustmentMonths != 0) { - $PHPDateObject->modify($adjustmentMonthsString . ' months'); - } - $nMonth = (int) $PHPDateObject->format('m'); - $nYear = (int) $PHPDateObject->format('Y'); - - $monthDiff = ($nMonth - $oMonth) + (($nYear - $oYear) * 12); - if ($monthDiff != $adjustmentMonths) { - $adjustDays = (int) $PHPDateObject->format('d'); - $adjustDaysString = '-' . $adjustDays . ' days'; - $PHPDateObject->modify($adjustDaysString); - } - - return $PHPDateObject; + return DateTimeExcel\Helpers::getDateValueNoThrow($dateValue); } /** @@ -136,6 +45,8 @@ private static function adjustDateByMonths($dateValue = 0, $adjustmentMonths = 0 * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date * and time format of your regional settings. PhpSpreadsheet does not change cell formatting in this way. * + * @Deprecated 2.0.0 Use the funcNow method in the DateTimeExcel\Now class instead + * * Excel Function: * NOW() * @@ -144,10 +55,7 @@ private static function adjustDateByMonths($dateValue = 0, $adjustmentMonths = 0 */ public static function DATETIMENOW() { - $dti = new DateTimeImmutable(); - $dateArray = date_parse($dti->format('c')); - - return is_array($dateArray) ? self::returnIn3FormatsArray($dateArray) : Functions::VALUE(); + return DateTimeExcel\Now::funcNow(); } /** @@ -161,6 +69,8 @@ public static function DATETIMENOW() * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date * and time format of your regional settings. PhpSpreadsheet does not change cell formatting in this way. * + * @Deprecated 2.0.0 Use the funcToday method in the DateTimeExcel\Today class instead + * * Excel Function: * TODAY() * @@ -169,10 +79,7 @@ public static function DATETIMENOW() */ public static function DATENOW() { - $dti = new DateTimeImmutable(); - $dateArray = date_parse($dti->format('c')); - - return is_array($dateArray) ? self::returnIn3FormatsArray($dateArray, true) : Functions::VALUE(); + return DateTimeExcel\Today::funcToday(); } /** @@ -183,6 +90,8 @@ public static function DATENOW() * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date * format of your regional settings. PhpSpreadsheet does not change cell formatting in this way. * + * @Deprecated 2.0.0 Use the funcDate method in the DateTimeExcel\Date class instead + * * Excel Function: * DATE(year,month,day) * @@ -226,65 +135,7 @@ public static function DATENOW() */ public static function DATE($year = 0, $month = 1, $day = 1) { - $year = Functions::flattenSingleValue($year); - $month = Functions::flattenSingleValue($month); - $day = Functions::flattenSingleValue($day); - - if (($month !== null) && (!is_numeric($month))) { - $month = Date::monthStringToNumber($month); - } - - if (($day !== null) && (!is_numeric($day))) { - $day = Date::dayStringToNumber($day); - } - - $year = ($year !== null) ? StringHelper::testStringAsNumeric($year) : 0; - $month = ($month !== null) ? StringHelper::testStringAsNumeric($month) : 0; - $day = ($day !== null) ? StringHelper::testStringAsNumeric($day) : 0; - if ( - (!is_numeric($year)) || - (!is_numeric($month)) || - (!is_numeric($day)) - ) { - return Functions::VALUE(); - } - $year = (int) $year; - $month = (int) $month; - $day = (int) $day; - - $baseYear = Date::getExcelCalendar(); - // Validate parameters - if ($year < ($baseYear - 1900)) { - return Functions::NAN(); - } - if ((($baseYear - 1900) != 0) && ($year < $baseYear) && ($year >= 1900)) { - return Functions::NAN(); - } - - if (($year < $baseYear) && ($year >= ($baseYear - 1900))) { - $year += 1900; - } - - if ($month < 1) { - // Handle year/month adjustment if month < 1 - --$month; - $year += ceil($month / 12) - 1; - $month = 13 - abs($month % 12); - } elseif ($month > 12) { - // Handle year/month adjustment if month > 12 - $year += floor($month / 12); - $month = ($month % 12); - } - - // Re-validate the year parameter after adjustments - if (($year < $baseYear) || ($year >= 10000)) { - return Functions::NAN(); - } - - // Execute function - $excelDateValue = Date::formattedPHPToExcel($year, $month, $day); - - return self::returnIn3FormatsFloat($excelDateValue); + return DateTimeExcel\Datefunc::funcDate($year, $month, $day); } /** @@ -295,6 +146,8 @@ public static function DATE($year = 0, $month = 1, $day = 1) * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the time * format of your regional settings. PhpSpreadsheet does not change cell formatting in this way. * + * @Deprecated 2.0.0 Use the funcTime method in the DateTimeExcel\Time class instead + * * Excel Function: * TIME(hour,minute,second) * @@ -315,73 +168,7 @@ public static function DATE($year = 0, $month = 1, $day = 1) */ public static function TIME($hour = 0, $minute = 0, $second = 0) { - $hour = Functions::flattenSingleValue($hour); - $minute = Functions::flattenSingleValue($minute); - $second = Functions::flattenSingleValue($second); - - if ($hour == '') { - $hour = 0; - } - if ($minute == '') { - $minute = 0; - } - if ($second == '') { - $second = 0; - } - - if ((!is_numeric($hour)) || (!is_numeric($minute)) || (!is_numeric($second))) { - return Functions::VALUE(); - } - $hour = (int) $hour; - $minute = (int) $minute; - $second = (int) $second; - - if ($second < 0) { - $minute += floor($second / 60); - $second = 60 - abs($second % 60); - if ($second == 60) { - $second = 0; - } - } elseif ($second >= 60) { - $minute += floor($second / 60); - $second = $second % 60; - } - if ($minute < 0) { - $hour += floor($minute / 60); - $minute = 60 - abs($minute % 60); - if ($minute == 60) { - $minute = 0; - } - } elseif ($minute >= 60) { - $hour += floor($minute / 60); - $minute = $minute % 60; - } - - if ($hour > 23) { - $hour = $hour % 24; - } elseif ($hour < 0) { - return Functions::NAN(); - } - - // Execute function - $retType = Functions::getReturnDateType(); - if ($retType === Functions::RETURNDATE_EXCEL) { - $date = 0; - $calendar = Date::getExcelCalendar(); - if ($calendar != Date::CALENDAR_WINDOWS_1900) { - $date = 1; - } - - return (float) Date::formattedPHPToExcel($calendar, 1, $date, $hour, $minute, $second); - } - if ($retType === Functions::RETURNDATE_UNIX_TIMESTAMP) { - return (int) Date::excelToTimestamp(Date::formattedPHPToExcel(1970, 1, 1, $hour, $minute, $second)); // -2147468400; // -2147472000 + 3600 - } - // RETURNDATE_PHP_DATETIME_OBJECT - // Hour has already been normalized (0-23) above - $phpDateObject = new \DateTime('1900-01-01 ' . $hour . ':' . $minute . ':' . $second); - - return $phpDateObject; + return DateTimeExcel\Time::funcTime($hour, $minute, $second); } /** @@ -394,6 +181,8 @@ public static function TIME($hour = 0, $minute = 0, $second = 0) * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date * format of your regional settings. PhpSpreadsheet does not change cell formatting in this way. * + * @Deprecated 2.0.0 Use the funcDatevalue method in the DateTimeExcel\DateValue class instead + * * Excel Function: * DATEVALUE(dateValue) * @@ -411,186 +200,7 @@ public static function TIME($hour = 0, $minute = 0, $second = 0) */ public static function DATEVALUE($dateValue = 1) { - $dti = new DateTimeImmutable(); - $baseYear = Date::getExcelCalendar(); - $dateValue = trim(Functions::flattenSingleValue($dateValue), '"'); - // Strip any ordinals because they're allowed in Excel (English only) - $dateValue = preg_replace('/(\d)(st|nd|rd|th)([ -\/])/Ui', '$1$3', $dateValue); - // Convert separators (/ . or space) to hyphens (should also handle dot used for ordinals in some countries, e.g. Denmark, Germany) - $dateValue = str_replace(['/', '.', '-', ' '], ' ', $dateValue); - - $yearFound = false; - $t1 = explode(' ', $dateValue); - $t = ''; - foreach ($t1 as &$t) { - if ((is_numeric($t)) && ($t > 31)) { - if ($yearFound) { - return Functions::VALUE(); - } - if ($t < 100) { - $t += 1900; - } - $yearFound = true; - } - } - if (count($t1) === 1) { - // We've been fed a time value without any date - return ((strpos($t, ':') === false)) ? Functions::Value() : 0.0; - } - if (count($t1) == 2) { - // We only have two parts of the date: either day/month or month/year - if ($yearFound) { - array_unshift($t1, 1); - } else { - if (is_numeric($t1[1]) && $t1[1] > 29) { - $t1[1] += 1900; - array_unshift($t1, 1); - } else { - $t1[] = $dti->format('Y'); - } - } - } - unset($t); - $dateValue = implode(' ', $t1); - - $PHPDateArray = date_parse($dateValue); - if (($PHPDateArray === false) || ($PHPDateArray['error_count'] > 0)) { - // If original count was 1, we've already returned. - // If it was 2, we added another. - // Therefore, neither of the first 2 stroks below can fail. - $testVal1 = strtok($dateValue, '- '); - $testVal2 = strtok('- '); - $testVal3 = strtok('- ') ?: $dti->format('Y'); - self::adjustYear($testVal1, $testVal2, $testVal3); - $PHPDateArray = date_parse($testVal1 . '-' . $testVal2 . '-' . $testVal3); - if (($PHPDateArray === false) || ($PHPDateArray['error_count'] > 0)) { - $PHPDateArray = date_parse($testVal2 . '-' . $testVal1 . '-' . $testVal3); - if (($PHPDateArray === false) || ($PHPDateArray['error_count'] > 0)) { - return Functions::VALUE(); - } - } - } - - $retValue = Functions::Value(); - if (($PHPDateArray !== false) && ($PHPDateArray['error_count'] == 0)) { - // Execute function - self::replaceIfEmpty($PHPDateArray['year'], $dti->format('Y')); - if ($PHPDateArray['year'] < $baseYear) { - return Functions::VALUE(); - } - self::replaceIfEmpty($PHPDateArray['month'], $dti->format('m')); - self::replaceIfEmpty($PHPDateArray['day'], $dti->format('d')); - $PHPDateArray['hour'] = 0; - $PHPDateArray['minute'] = 0; - $PHPDateArray['second'] = 0; - $month = (int) $PHPDateArray['month']; - $day = (int) $PHPDateArray['day']; - $year = (int) $PHPDateArray['year']; - if (!checkdate($month, $day, $year)) { - return ($year === 1900 && $month === 2 && $day === 29) ? self::returnIn3FormatsFloat(60.0) : Functions::VALUE(); - } - $retValue = is_array($PHPDateArray) ? self::returnIn3FormatsArray($PHPDateArray, true) : Functions::VALUE(); - } - - return $retValue; - } - - /** - * Help reduce perceived complexity of some tests. - * - * @param mixed $value - * @param mixed $altValue - */ - private static function replaceIfEmpty(&$value, $altValue): void - { - $value = $value ?: $altValue; - } - - /** - * Adjust year in ambiguous situations. - */ - private static function adjustYear(string $testVal1, string $testVal2, string &$testVal3): void - { - if (!is_numeric($testVal1) || $testVal1 < 31) { - if (!is_numeric($testVal2) || $testVal2 < 12) { - if (is_numeric($testVal3) && $testVal3 < 12) { - $testVal3 += 2000; - } - } - } - } - - /** - * Return result in one of three formats. - * - * @return mixed - */ - private static function returnIn3FormatsArray(array $dateArray, bool $noFrac = false) - { - $retType = Functions::getReturnDateType(); - if ($retType === Functions::RETURNDATE_PHP_DATETIME_OBJECT) { - return new \DateTime( - $dateArray['year'] - . '-' . $dateArray['month'] - . '-' . $dateArray['day'] - . ' ' . $dateArray['hour'] - . ':' . $dateArray['minute'] - . ':' . $dateArray['second'] - ); - } - $excelDateValue = - Date::formattedPHPToExcel( - $dateArray['year'], - $dateArray['month'], - $dateArray['day'], - $dateArray['hour'], - $dateArray['minute'], - $dateArray['second'] - ); - if ($retType === Functions::RETURNDATE_EXCEL) { - return $noFrac ? floor($excelDateValue) : (float) $excelDateValue; - } - // RETURNDATE_UNIX_TIMESTAMP) - - return (int) Date::excelToTimestamp($excelDateValue); - } - - /** - * Return result in one of three formats. - * - * @return mixed - */ - private static function returnIn3FormatsFloat(float $excelDateValue) - { - $retType = Functions::getReturnDateType(); - if ($retType === Functions::RETURNDATE_EXCEL) { - return $excelDateValue; - } - if ($retType === Functions::RETURNDATE_UNIX_TIMESTAMP) { - return (int) Date::excelToTimestamp($excelDateValue); - } - // RETURNDATE_PHP_DATETIME_OBJECT - - return Date::excelToDateTimeObject($excelDateValue); - } - - /** - * Return result in one of three formats. - * - * @return mixed - */ - private static function returnIn3FormatsObject(\DateTime $PHPDateObject) - { - $retType = Functions::getReturnDateType(); - if ($retType === Functions::RETURNDATE_PHP_DATETIME_OBJECT) { - return $PHPDateObject; - } - if ($retType === Functions::RETURNDATE_EXCEL) { - return (float) Date::PHPToExcel($PHPDateObject); - } - // RETURNDATE_UNIX_TIMESTAMP - - return (int) Date::excelToTimestamp(Date::PHPToExcel($PHPDateObject)); + return DateTimeExcel\Datevalue::funcDatevalue($dateValue); } /** @@ -603,6 +213,8 @@ private static function returnIn3FormatsObject(\DateTime $PHPDateObject) * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the time * format of your regional settings. PhpSpreadsheet does not change cell formatting in this way. * + * @Deprecated 2.0.0 Use the funcTimevalue method in the DateTimeExcel\TimeValue class instead + * * Excel Function: * TIMEVALUE(timeValue) * @@ -616,37 +228,14 @@ private static function returnIn3FormatsObject(\DateTime $PHPDateObject) */ public static function TIMEVALUE($timeValue) { - $timeValue = trim(Functions::flattenSingleValue($timeValue), '"'); - $timeValue = str_replace(['/', '.'], '-', $timeValue); - - $arraySplit = preg_split('/[\/:\-\s]/', $timeValue); - if ((count($arraySplit) == 2 || count($arraySplit) == 3) && $arraySplit[0] > 24) { - $arraySplit[0] = ($arraySplit[0] % 24); - $timeValue = implode(':', $arraySplit); - } - - $PHPDateArray = date_parse($timeValue); - $retValue = Functions::VALUE(); - if (($PHPDateArray !== false) && ($PHPDateArray['error_count'] == 0)) { - // OpenOffice-specific code removed - it works just like Excel - $excelDateValue = Date::formattedPHPToExcel(1900, 1, 1, $PHPDateArray['hour'], $PHPDateArray['minute'], $PHPDateArray['second']) - 1; - - $retType = Functions::getReturnDateType(); - if ($retType === Functions::RETURNDATE_EXCEL) { - $retValue = (float) $excelDateValue; - } elseif ($retType === Functions::RETURNDATE_UNIX_TIMESTAMP) { - $retValue = (int) $phpDateValue = Date::excelToTimestamp($excelDateValue + 25569) - 3600; - } else { - $retValue = new \DateTime('1900-01-01 ' . $PHPDateArray['hour'] . ':' . $PHPDateArray['minute'] . ':' . $PHPDateArray['second']); - } - } - - return $retValue; + return DateTimeExcel\Timevalue::funcTimevalue($timeValue); } /** * DATEDIF. * + * @Deprecated 2.0.0 Use the funcDatedif method in the DateTimeExcel\Datedif class instead + * * @param mixed $startDate Excel date serial value, PHP date/time stamp, PHP DateTime object * or a standard date string * @param mixed $endDate Excel date serial value, PHP date/time stamp, PHP DateTime object @@ -657,95 +246,7 @@ public static function TIMEVALUE($timeValue) */ public static function DATEDIF($startDate = 0, $endDate = 0, $unit = 'D') { - $startDate = Functions::flattenSingleValue($startDate); - $endDate = Functions::flattenSingleValue($endDate); - $unit = strtoupper(Functions::flattenSingleValue($unit)); - - if (is_string($startDate = self::getDateValue($startDate))) { - return Functions::VALUE(); - } - if (is_string($endDate = self::getDateValue($endDate))) { - return Functions::VALUE(); - } - - // Validate parameters - if ($startDate > $endDate) { - return Functions::NAN(); - } - - // Execute function - $difference = $endDate - $startDate; - - $PHPStartDateObject = Date::excelToDateTimeObject($startDate); - $startDays = $PHPStartDateObject->format('j'); - $startMonths = $PHPStartDateObject->format('n'); - $startYears = $PHPStartDateObject->format('Y'); - - $PHPEndDateObject = Date::excelToDateTimeObject($endDate); - $endDays = $PHPEndDateObject->format('j'); - $endMonths = $PHPEndDateObject->format('n'); - $endYears = $PHPEndDateObject->format('Y'); - - $PHPDiffDateObject = $PHPEndDateObject->diff($PHPStartDateObject); - - switch ($unit) { - case 'D': - $retVal = (int) $difference; - - break; - case 'M': - $retVal = (int) 12 * $PHPDiffDateObject->format('%y') + $PHPDiffDateObject->format('%m'); - - break; - case 'Y': - $retVal = (int) $PHPDiffDateObject->format('%y'); - - break; - case 'MD': - if ($endDays < $startDays) { - $retVal = $endDays; - $PHPEndDateObject->modify('-' . $endDays . ' days'); - $adjustDays = $PHPEndDateObject->format('j'); - $retVal += ($adjustDays - $startDays); - } else { - $retVal = (int) $PHPDiffDateObject->format('%d'); - } - - break; - case 'YM': - $retVal = (int) $PHPDiffDateObject->format('%m'); - - break; - case 'YD': - $retVal = (int) $difference; - if ($endYears > $startYears) { - $isLeapStartYear = $PHPStartDateObject->format('L'); - $wasLeapEndYear = $PHPEndDateObject->format('L'); - - // Adjust end year to be as close as possible as start year - while ($PHPEndDateObject >= $PHPStartDateObject) { - $PHPEndDateObject->modify('-1 year'); - $endYears = $PHPEndDateObject->format('Y'); - } - $PHPEndDateObject->modify('+1 year'); - - // Get the result - $retVal = $PHPEndDateObject->diff($PHPStartDateObject)->days; - - // Adjust for leap years cases - $isLeapEndYear = $PHPEndDateObject->format('L'); - $limit = new \DateTime($PHPEndDateObject->format('Y-02-29')); - if (!$isLeapStartYear && !$wasLeapEndYear && $isLeapEndYear && $PHPEndDateObject >= $limit) { - --$retVal; - } - } - - break; - default: - $retVal = Functions::VALUE(); - } - - return $retVal; + return DateTimeExcel\Datedif::funcDatedif($startDate, $endDate, $unit); } /** @@ -753,43 +254,21 @@ public static function DATEDIF($startDate = 0, $endDate = 0, $unit = 'D') * * Returns the number of days between two dates * + * @Deprecated 2.0.0 Use the funcDays method in the DateTimeExcel\Days class instead + * * Excel Function: * DAYS(endDate, startDate) * - * @param DateTimeImmutable|float|int|string $endDate Excel date serial value (float), + * @param DateTimeInterface|float|int|string $endDate Excel date serial value (float), * PHP date timestamp (integer), PHP DateTime object, or a standard date string - * @param DateTimeImmutable|float|int|string $startDate Excel date serial value (float), + * @param DateTimeInterface|float|int|string $startDate Excel date serial value (float), * PHP date timestamp (integer), PHP DateTime object, or a standard date string * * @return int|string Number of days between start date and end date or an error */ public static function DAYS($endDate = 0, $startDate = 0) { - $startDate = Functions::flattenSingleValue($startDate); - $endDate = Functions::flattenSingleValue($endDate); - - $startDate = self::getDateValue($startDate); - if (is_string($startDate)) { - return Functions::VALUE(); - } - - $endDate = self::getDateValue($endDate); - if (is_string($endDate)) { - return Functions::VALUE(); - } - - // Execute function - $PHPStartDateObject = Date::excelToDateTimeObject($startDate); - $PHPEndDateObject = Date::excelToDateTimeObject($endDate); - - $diff = $PHPStartDateObject->diff($PHPEndDateObject); - $days = $diff->days; - - if ($diff->invert) { - $days = -$days; - } - - return $days; + return DateTimeExcel\Days::funcDays($endDate, $startDate); } /** @@ -799,6 +278,8 @@ public static function DAYS($endDate = 0, $startDate = 0) * which is used in some accounting calculations. Use this function to help compute payments if * your accounting system is based on twelve 30-day months. * + * @Deprecated 2.0.0 Use the funcDays360 method in the DateTimeExcel\Days360 class instead + * * Excel Function: * DAYS360(startDate,endDate[,method]) * @@ -822,32 +303,7 @@ public static function DAYS($endDate = 0, $startDate = 0) */ public static function DAYS360($startDate = 0, $endDate = 0, $method = false) { - $startDate = Functions::flattenSingleValue($startDate); - $endDate = Functions::flattenSingleValue($endDate); - - if (is_string($startDate = self::getDateValue($startDate))) { - return Functions::VALUE(); - } - if (is_string($endDate = self::getDateValue($endDate))) { - return Functions::VALUE(); - } - - if (!is_bool($method)) { - return Functions::VALUE(); - } - - // Execute function - $PHPStartDateObject = Date::excelToDateTimeObject($startDate); - $startDay = $PHPStartDateObject->format('j'); - $startMonth = $PHPStartDateObject->format('n'); - $startYear = $PHPStartDateObject->format('Y'); - - $PHPEndDateObject = Date::excelToDateTimeObject($endDate); - $endDay = $PHPEndDateObject->format('j'); - $endMonth = $PHPEndDateObject->format('n'); - $endYear = $PHPEndDateObject->format('Y'); - - return self::dateDiff360($startDay, $startMonth, $startYear, $endDay, $endMonth, $endYear, !$method); + return DateTimeExcel\Days360::funcDays360($startDate, $endDate, $method); } /** @@ -858,6 +314,8 @@ public static function DAYS360($startDate = 0, $endDate = 0, $method = false) * Use the YEARFRAC worksheet function to identify the proportion of a whole year's benefits or * obligations to assign to a specific term. * + * @Deprecated 2.0.0 Use the funcYearfrac method in the DateTimeExcel\YearFrac class instead + * * Excel Function: * YEARFRAC(startDate,endDate[,method]) * See https://lists.oasis-open.org/archives/office-formula/200806/msg00039.html @@ -878,78 +336,7 @@ public static function DAYS360($startDate = 0, $endDate = 0, $method = false) */ public static function YEARFRAC($startDate = 0, $endDate = 0, $method = 0) { - $startDate = Functions::flattenSingleValue($startDate); - $endDate = Functions::flattenSingleValue($endDate); - $method = Functions::flattenSingleValue($method); - - if (is_string($startDate = self::getDateValue($startDate))) { - return Functions::VALUE(); - } - if (is_string($endDate = self::getDateValue($endDate))) { - return Functions::VALUE(); - } - if ($startDate > $endDate) { - $temp = $startDate; - $startDate = $endDate; - $endDate = $temp; - } - - if (((is_numeric($method)) && (!is_string($method))) || ($method == '')) { - switch ($method) { - case 0: - return self::DAYS360($startDate, $endDate) / 360; - case 1: - $days = self::DATEDIF($startDate, $endDate); - $startYear = self::YEAR($startDate); - $endYear = self::YEAR($endDate); - $years = $endYear - $startYear + 1; - $startMonth = self::MONTHOFYEAR($startDate); - $startDay = self::DAYOFMONTH($startDate); - $endMonth = self::MONTHOFYEAR($endDate); - $endDay = self::DAYOFMONTH($endDate); - $startMonthDay = 100 * $startMonth + $startDay; - $endMonthDay = 100 * $endMonth + $endDay; - if ($years == 1) { - if (self::isLeapYear($endYear)) { - $tmpCalcAnnualBasis = 366; - } else { - $tmpCalcAnnualBasis = 365; - } - } elseif ($years == 2 && $startMonthDay >= $endMonthDay) { - if (self::isLeapYear($startYear)) { - if ($startMonthDay <= 229) { - $tmpCalcAnnualBasis = 366; - } else { - $tmpCalcAnnualBasis = 365; - } - } elseif (self::isLeapYear($endYear)) { - if ($endMonthDay >= 229) { - $tmpCalcAnnualBasis = 366; - } else { - $tmpCalcAnnualBasis = 365; - } - } else { - $tmpCalcAnnualBasis = 365; - } - } else { - $tmpCalcAnnualBasis = 0; - for ($year = $startYear; $year <= $endYear; ++$year) { - $tmpCalcAnnualBasis += self::isLeapYear($year) ? 366 : 365; - } - $tmpCalcAnnualBasis /= $years; - } - - return $days / $tmpCalcAnnualBasis; - case 2: - return self::DATEDIF($startDate, $endDate) / 360; - case 3: - return self::DATEDIF($startDate, $endDate) / 365; - case 4: - return self::DAYS360($startDate, $endDate, true) / 360; - } - } - - return Functions::VALUE(); + return DateTimeExcel\YearFrac::funcYearfrac($startDate, $endDate, $method); } /** @@ -960,6 +347,8 @@ public static function YEARFRAC($startDate = 0, $endDate = 0, $method = 0) * Use NETWORKDAYS to calculate employee benefits that accrue based on the number of days * worked during a specific term. * + * @Deprecated 2.0.0 Use the funcNetworkdays method in the DateTimeExcel\Networkdays class instead + * * Excel Function: * NETWORKDAYS(startDate,endDate[,holidays[,holiday[,...]]]) * @@ -972,62 +361,7 @@ public static function YEARFRAC($startDate = 0, $endDate = 0, $method = 0) */ public static function NETWORKDAYS($startDate, $endDate, ...$dateArgs) { - // Retrieve the mandatory start and end date that are referenced in the function definition - $startDate = Functions::flattenSingleValue($startDate); - $endDate = Functions::flattenSingleValue($endDate); - // Get the optional days - $dateArgs = Functions::flattenArray($dateArgs); - - // Validate the start and end dates - if (is_string($startDate = $sDate = self::getDateValue($startDate))) { - return Functions::VALUE(); - } - $startDate = (float) floor($startDate); - if (is_string($endDate = $eDate = self::getDateValue($endDate))) { - return Functions::VALUE(); - } - $endDate = (float) floor($endDate); - - if ($sDate > $eDate) { - $startDate = $eDate; - $endDate = $sDate; - } - - // Execute function - $startDoW = 6 - self::WEEKDAY($startDate, 2); - if ($startDoW < 0) { - $startDoW = 5; - } - $endDoW = self::WEEKDAY($endDate, 2); - if ($endDoW >= 6) { - $endDoW = 0; - } - - $wholeWeekDays = floor(($endDate - $startDate) / 7) * 5; - $partWeekDays = $endDoW + $startDoW; - if ($partWeekDays > 5) { - $partWeekDays -= 5; - } - - // Test any extra holiday parameters - $holidayCountedArray = []; - foreach ($dateArgs as $holidayDate) { - if (is_string($holidayDate = self::getDateValue($holidayDate))) { - return Functions::VALUE(); - } - if (($holidayDate >= $startDate) && ($holidayDate <= $endDate)) { - if ((self::WEEKDAY($holidayDate, 2) < 6) && (!in_array($holidayDate, $holidayCountedArray))) { - --$partWeekDays; - $holidayCountedArray[] = $holidayDate; - } - } - } - - if ($sDate > $eDate) { - return 0 - ($wholeWeekDays + $partWeekDays); - } - - return $wholeWeekDays + $partWeekDays; + return DateTimeExcel\Networkdays::funcNetworkdays($startDate, $endDate, ...$dateArgs); } /** @@ -1038,6 +372,8 @@ public static function NETWORKDAYS($startDate, $endDate, ...$dateArgs) * Use WORKDAY to exclude weekends or holidays when you calculate invoice due dates, expected * delivery times, or the number of days of work performed. * + * @Deprecated 2.0.0 Use the funcWorkday method in the DateTimeExcel\Workday class instead + * * Excel Function: * WORKDAY(startDate,endDays[,holidays[,holiday[,...]]]) * @@ -1052,84 +388,7 @@ public static function NETWORKDAYS($startDate, $endDate, ...$dateArgs) */ public static function WORKDAY($startDate, $endDays, ...$dateArgs) { - // Retrieve the mandatory start date and days that are referenced in the function definition - $startDate = Functions::flattenSingleValue($startDate); - $endDays = Functions::flattenSingleValue($endDays); - // Get the optional days - $dateArgs = Functions::flattenArray($dateArgs); - - if ((is_string($startDate = self::getDateValue($startDate))) || (!is_numeric($endDays))) { - return Functions::VALUE(); - } - $startDate = (float) floor($startDate); - $endDays = (int) floor($endDays); - // If endDays is 0, we always return startDate - if ($endDays == 0) { - return $startDate; - } - - $decrementing = $endDays < 0; - - // Adjust the start date if it falls over a weekend - - $startDoW = self::WEEKDAY($startDate, 3); - if (self::WEEKDAY($startDate, 3) >= 5) { - $startDate += ($decrementing) ? -$startDoW + 4 : 7 - $startDoW; - ($decrementing) ? $endDays++ : $endDays--; - } - - // Add endDays - $endDate = (float) $startDate + ((int) ($endDays / 5) * 7) + ($endDays % 5); - - // Adjust the calculated end date if it falls over a weekend - $endDoW = self::WEEKDAY($endDate, 3); - if ($endDoW >= 5) { - $endDate += ($decrementing) ? -$endDoW + 4 : 7 - $endDoW; - } - - // Test any extra holiday parameters - if (!empty($dateArgs)) { - $holidayCountedArray = $holidayDates = []; - foreach ($dateArgs as $holidayDate) { - if (($holidayDate !== null) && (trim($holidayDate) > '')) { - if (is_string($holidayDate = self::getDateValue($holidayDate))) { - return Functions::VALUE(); - } - if (self::WEEKDAY($holidayDate, 3) < 5) { - $holidayDates[] = $holidayDate; - } - } - } - if ($decrementing) { - rsort($holidayDates, SORT_NUMERIC); - } else { - sort($holidayDates, SORT_NUMERIC); - } - foreach ($holidayDates as $holidayDate) { - if ($decrementing) { - if (($holidayDate <= $startDate) && ($holidayDate >= $endDate)) { - if (!in_array($holidayDate, $holidayCountedArray)) { - --$endDate; - $holidayCountedArray[] = $holidayDate; - } - } - } else { - if (($holidayDate >= $startDate) && ($holidayDate <= $endDate)) { - if (!in_array($holidayDate, $holidayCountedArray)) { - ++$endDate; - $holidayCountedArray[] = $holidayDate; - } - } - } - // Adjust the calculated end date if it falls over a weekend - $endDoW = self::WEEKDAY($endDate, 3); - if ($endDoW >= 5) { - $endDate += ($decrementing) ? -$endDoW + 4 : 7 - $endDoW; - } - } - } - - return self::returnIn3FormatsFloat($endDate); + return DateTimeExcel\Workday::funcWorkday($startDate, $endDays, ...$dateArgs); } /** @@ -1138,6 +397,8 @@ public static function WORKDAY($startDate, $endDays, ...$dateArgs) * Returns the day of the month, for a specified date. The day is given as an integer * ranging from 1 to 31. * + * @Deprecated 2.0.0 Use the funcDay method in the DateTimeExcel\Day class instead + * * Excel Function: * DAY(dateValue) * @@ -1148,27 +409,7 @@ public static function WORKDAY($startDate, $endDays, ...$dateArgs) */ public static function DAYOFMONTH($dateValue = 1) { - $dateValue = Functions::flattenSingleValue($dateValue); - - if ($dateValue === null || is_bool($dateValue)) { - return (int) $dateValue; - } - if (is_string($dateValue = self::getDateValue($dateValue))) { - return Functions::VALUE(); - } - - if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_EXCEL) { - if ($dateValue < 0.0) { - return Functions::NAN(); - } elseif ($dateValue < 1.0) { - return 0; - } - } - - // Execute function - $PHPDateObject = Date::excelToDateTimeObject($dateValue); - - return (int) $PHPDateObject->format('j'); + return DateTimeExcel\Day::funcDay($dateValue); } /** @@ -1177,6 +418,8 @@ public static function DAYOFMONTH($dateValue = 1) * Returns the day of the week for a specified date. The day is given as an integer * ranging from 0 to 7 (dependent on the requested style). * + * @Deprecated 2.0.0 Use the funcWeekday method in the DateTimeExcel\Weekday class instead + * * Excel Function: * WEEKDAY(dateValue[,style]) * @@ -1191,51 +434,7 @@ public static function DAYOFMONTH($dateValue = 1) */ public static function WEEKDAY($dateValue = 1, $style = 1) { - $dateValue = Functions::flattenSingleValue($dateValue); - self::nullFalseTrueToNumber($dateValue); - $style = Functions::flattenSingleValue($style); - - if (!is_numeric($style)) { - return Functions::VALUE(); - } elseif (($style < 1) || ($style > 3)) { - return Functions::NAN(); - } - $style = floor($style); - - $dateValue = self::getDateValue($dateValue); - if (is_string($dateValue)) { - return Functions::VALUE(); - } - if ($dateValue < 0.0) { - return Functions::NAN(); - } - - // Execute function - $PHPDateObject = Date::excelToDateTimeObject($dateValue); - self::silly1900($PHPDateObject); - $DoW = (int) $PHPDateObject->format('w'); - - switch ($style) { - case 1: - ++$DoW; - - break; - case 2: - if ($DoW === 0) { - $DoW = 7; - } - - break; - case 3: - if ($DoW === 0) { - $DoW = 7; - } - --$DoW; - - break; - } - - return $DoW; + return DateTimeExcel\Weekday::funcWeekday($dateValue, $style); } const STARTWEEK_SUNDAY = 1; @@ -1278,6 +477,8 @@ public static function WEEKDAY($dateValue = 1, $style = 1) * three days or less in the first week of January, the WEEKNUM function returns week numbers * that are incorrect according to the European standard. * + * @Deprecated 2.0.0 Use the funcWeeknum method in the DateTimeExcel\Weeknum class instead + * * Excel Function: * WEEKNUM(dateValue[,style]) * @@ -1299,67 +500,7 @@ public static function WEEKDAY($dateValue = 1, $style = 1) */ public static function WEEKNUM($dateValue = 1, $method = self::STARTWEEK_SUNDAY) { - $origDateValueNull = $dateValue === null; - $dateValue = Functions::flattenSingleValue($dateValue); - $method = Functions::flattenSingleValue($method); - if (!is_numeric($method)) { - return Functions::VALUE(); - } - - $method = (int) $method; - if (!array_key_exists($method, self::METHODARR)) { - return Functions::NaN(); - } - $method = self::METHODARR[$method]; - if ($dateValue === null) { // boolean not allowed - // This seems to be an additional Excel bug. - if (self::buggyWeekNum1900($method)) { - return 0; - } - //$dateValue = 1; - $dateValue = (Date::getExcelCalendar() === DATE::CALENDAR_MAC_1904) ? 0 : 1; - } - - $dateValue = self::getDateValue($dateValue); - if (is_string($dateValue)) { - return Functions::VALUE(); - } - if ($dateValue < 0.0) { - return Functions::NAN(); - } - - // Execute function - $PHPDateObject = Date::excelToDateTimeObject($dateValue); - if ($method == self::STARTWEEK_MONDAY_ISO) { - self::silly1900($PHPDateObject); - - return (int) $PHPDateObject->format('W'); - } - if (self::buggyWeekNum1904($method, $origDateValueNull, $PHPDateObject)) { - return 0; - } - self::silly1900($PHPDateObject, '+ 5 years'); // 1905 calendar matches - $dayOfYear = $PHPDateObject->format('z'); - $PHPDateObject->modify('-' . $dayOfYear . ' days'); - $firstDayOfFirstWeek = $PHPDateObject->format('w'); - $daysInFirstWeek = (6 - $firstDayOfFirstWeek + $method) % 7; - $daysInFirstWeek += 7 * !$daysInFirstWeek; - $endFirstWeek = $daysInFirstWeek - 1; - $weekOfYear = floor(($dayOfYear - $endFirstWeek + 13) / 7); - - return (int) $weekOfYear; - } - - private static function buggyWeekNum1900(int $method): bool - { - return $method === self::DOW_SUNDAY && Date::getExcelCalendar() === Date::CALENDAR_WINDOWS_1900; - } - - private static function buggyWeekNum1904(int $method, bool $origNull, \DateTime $dateObject): bool - { - // This appears to be another Excel bug. - - return $method === self::DOW_SUNDAY && Date::getExcelCalendar() === Date::CALENDAR_MAC_1904 && !$origNull && $dateObject->format('Y-m-d') === '1904-01-01'; + return DateTimeExcel\Weeknum::funcWeeknum($dateValue, $method); } /** @@ -1367,6 +508,8 @@ private static function buggyWeekNum1904(int $method, bool $origNull, \DateTime * * Returns the ISO 8601 week number of the year for a specified date. * + * @Deprecated 2.0.0 Use the funcIsoWeeknum method in the DateTimeExcel\Isoweeknum class instead + * * Excel Function: * ISOWEEKNUM(dateValue) * @@ -1377,22 +520,7 @@ private static function buggyWeekNum1904(int $method, bool $origNull, \DateTime */ public static function ISOWEEKNUM($dateValue = 1) { - $dateValue = Functions::flattenSingleValue($dateValue); - self::nullFalseTrueToNumber($dateValue); - - $dateValue = self::getDateValue($dateValue); - if (!is_numeric($dateValue)) { - return Functions::VALUE(); - } - if ($dateValue < 0.0) { - return Functions::NAN(); - } - - // Execute function - $PHPDateObject = Date::excelToDateTimeObject($dateValue); - self::silly1900($PHPDateObject); - - return (int) $PHPDateObject->format('W'); + return DateTimeExcel\Isoweeknum::funcIsoWeeknum($dateValue); } /** @@ -1401,6 +529,8 @@ public static function ISOWEEKNUM($dateValue = 1) * Returns the month of a date represented by a serial number. * The month is given as an integer, ranging from 1 (January) to 12 (December). * + * @Deprecated 2.0.0 Use the funcMonth method in the DateTimeExcel\Month class instead + * * Excel Function: * MONTH(dateValue) * @@ -1411,21 +541,7 @@ public static function ISOWEEKNUM($dateValue = 1) */ public static function MONTHOFYEAR($dateValue = 1) { - $dateValue = Functions::flattenSingleValue($dateValue); - - if (empty($dateValue)) { - $dateValue = 1; - } - if (is_string($dateValue = self::getDateValue($dateValue))) { - return Functions::VALUE(); - } elseif ($dateValue < 0.0) { - return Functions::NAN(); - } - - // Execute function - $PHPDateObject = Date::excelToDateTimeObject($dateValue); - - return (int) $PHPDateObject->format('n'); + return DateTimeExcel\Month::funcMonth($dateValue); } /** @@ -1434,6 +550,8 @@ public static function MONTHOFYEAR($dateValue = 1) * Returns the year corresponding to a date. * The year is returned as an integer in the range 1900-9999. * + * @Deprecated 2.0.0 Use the funcYear method in the DateTimeExcel\Year class instead + * * Excel Function: * YEAR(dateValue) * @@ -1444,20 +562,7 @@ public static function MONTHOFYEAR($dateValue = 1) */ public static function YEAR($dateValue = 1) { - $dateValue = Functions::flattenSingleValue($dateValue); - - if ($dateValue === null) { - $dateValue = 1; - } elseif (is_string($dateValue = self::getDateValue($dateValue))) { - return Functions::VALUE(); - } elseif ($dateValue < 0.0) { - return Functions::NAN(); - } - - // Execute function - $PHPDateObject = Date::excelToDateTimeObject($dateValue); - - return (int) $PHPDateObject->format('Y'); + return DateTimeExcel\Year::funcYear($dateValue); } /** @@ -1466,6 +571,8 @@ public static function YEAR($dateValue = 1) * Returns the hour of a time value. * The hour is given as an integer, ranging from 0 (12:00 A.M.) to 23 (11:00 P.M.). * + * @Deprecated 2.0.0 Use the funcHour method in the DateTimeExcel\Hour class instead + * * Excel Function: * HOUR(timeValue) * @@ -1476,24 +583,7 @@ public static function YEAR($dateValue = 1) */ public static function HOUROFDAY($timeValue = 0) { - $timeValue = Functions::flattenSingleValue($timeValue); - - if (!is_numeric($timeValue)) { - // Gnumeric test removed - it operates like Excel - $timeValue = self::getTimeValue($timeValue); - if (is_string($timeValue)) { - return Functions::VALUE(); - } - } - // Execute function - if ($timeValue >= 1) { - $timeValue = fmod($timeValue, 1); - } elseif ($timeValue < 0.0) { - return Functions::NAN(); - } - $timeValue = Date::excelToTimestamp($timeValue); - - return (int) gmdate('G', $timeValue); + return DateTimeExcel\Hour::funcHour($timeValue); } /** @@ -1502,6 +592,8 @@ public static function HOUROFDAY($timeValue = 0) * Returns the minutes of a time value. * The minute is given as an integer, ranging from 0 to 59. * + * @Deprecated 2.0.0 Use the funcMinute method in the DateTimeExcel\Minute class instead + * * Excel Function: * MINUTE(timeValue) * @@ -1512,24 +604,7 @@ public static function HOUROFDAY($timeValue = 0) */ public static function MINUTE($timeValue = 0) { - $timeValue = $timeTester = Functions::flattenSingleValue($timeValue); - - if (!is_numeric($timeValue)) { - // Gnumeric test removed - it operates like Excel - $timeValue = self::getTimeValue($timeValue); - if (is_string($timeValue)) { - return Functions::VALUE(); - } - } - // Execute function - if ($timeValue >= 1) { - $timeValue = fmod($timeValue, 1); - } elseif ($timeValue < 0.0) { - return Functions::NAN(); - } - $timeValue = Date::excelToTimestamp($timeValue); - - return (int) gmdate('i', $timeValue); + return DateTimeExcel\Minute::funcMinute($timeValue); } /** @@ -1538,6 +613,8 @@ public static function MINUTE($timeValue = 0) * Returns the seconds of a time value. * The second is given as an integer in the range 0 (zero) to 59. * + * @Deprecated 2.0.0 Use the funcSecond method in the DateTimeExcel\Second class instead + * * Excel Function: * SECOND(timeValue) * @@ -1548,24 +625,7 @@ public static function MINUTE($timeValue = 0) */ public static function SECOND($timeValue = 0) { - $timeValue = Functions::flattenSingleValue($timeValue); - - if (!is_numeric($timeValue)) { - // Gnumeric test removed - it operates like Excel - $timeValue = self::getTimeValue($timeValue); - if (is_string($timeValue)) { - return Functions::VALUE(); - } - } - // Execute function - if ($timeValue >= 1) { - $timeValue = fmod($timeValue, 1); - } elseif ($timeValue < 0.0) { - return Functions::NAN(); - } - $timeValue = Date::excelToTimestamp($timeValue); - - return (int) gmdate('s', $timeValue); + return DateTimeExcel\Second::funcSecond($timeValue); } /** @@ -1576,6 +636,8 @@ public static function SECOND($timeValue = 0) * Use EDATE to calculate maturity dates or due dates that fall on the same day of the month * as the date of issue. * + * @Deprecated 2.0.0 Use the funcEdate method in the DateTimeExcel\Edate class instead + * * Excel Function: * EDATE(dateValue,adjustmentMonths) * @@ -1590,22 +652,7 @@ public static function SECOND($timeValue = 0) */ public static function EDATE($dateValue = 1, $adjustmentMonths = 0) { - $dateValue = Functions::flattenSingleValue($dateValue); - $adjustmentMonths = Functions::flattenSingleValue($adjustmentMonths); - - if (!is_numeric($adjustmentMonths)) { - return Functions::VALUE(); - } - $adjustmentMonths = floor($adjustmentMonths); - - if (is_string($dateValue = self::getDateValue($dateValue))) { - return Functions::VALUE(); - } - - // Execute function - $PHPDateObject = self::adjustDateByMonths($dateValue, $adjustmentMonths); - - return self::returnIn3FormatsObject($PHPDateObject); + return DateTimeExcel\Edate::funcEdate($dateValue, $adjustmentMonths); } /** @@ -1615,6 +662,8 @@ public static function EDATE($dateValue = 1, $adjustmentMonths = 0) * before or after start_date. * Use EOMONTH to calculate maturity dates or due dates that fall on the last day of the month. * + * @Deprecated 2.0.0 Use the funcEomonth method in the DateTimeExcel\Eomonth class instead + * * Excel Function: * EOMONTH(dateValue,adjustmentMonths) * @@ -1629,49 +678,6 @@ public static function EDATE($dateValue = 1, $adjustmentMonths = 0) */ public static function EOMONTH($dateValue = 1, $adjustmentMonths = 0) { - $dateValue = Functions::flattenSingleValue($dateValue); - $adjustmentMonths = Functions::flattenSingleValue($adjustmentMonths); - - if (!is_numeric($adjustmentMonths)) { - return Functions::VALUE(); - } - $adjustmentMonths = floor($adjustmentMonths); - - if (is_string($dateValue = self::getDateValue($dateValue))) { - return Functions::VALUE(); - } - - // Execute function - $PHPDateObject = self::adjustDateByMonths($dateValue, $adjustmentMonths + 1); - $adjustDays = (int) $PHPDateObject->format('d'); - $adjustDaysString = '-' . $adjustDays . ' days'; - $PHPDateObject->modify($adjustDaysString); - - return self::returnIn3FormatsObject($PHPDateObject); - } - - /** - * Many functions accept null/false/true argument treated as 0/0/1. - * - * @param mixed $number - */ - private static function nullFalseTrueToNumber(&$number): void - { - $number = Functions::flattenSingleValue($number); - $baseYear = Date::getExcelCalendar(); - $nullVal = $baseYear === DATE::CALENDAR_MAC_1904 ? 0 : 1; - if ($number === null) { - $number = $nullVal; - } elseif (is_bool($number)) { - $number = $nullVal + (int) $number; - } - } - - private static function silly1900(\DateTime $PHPDateObject, string $mod = '-1 day'): void - { - $isoDate = $PHPDateObject->format('c'); - if ($isoDate < '1900-03-01') { - $PHPDateObject->modify($mod); - } + return DateTimeExcel\Eomonth::funcEomonth($dateValue, $adjustmentMonths); } } diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php new file mode 100644 index 0000000000..fa8c616df3 --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php @@ -0,0 +1,152 @@ +getMessage(); + } + + // Execute function + $PHPStartDateObject = Date::excelToDateTimeObject($startDate); + $startDays = $PHPStartDateObject->format('j'); + $startMonths = $PHPStartDateObject->format('n'); + $startYears = $PHPStartDateObject->format('Y'); + + $PHPEndDateObject = Date::excelToDateTimeObject($endDate); + $endDays = $PHPEndDateObject->format('j'); + $endMonths = $PHPEndDateObject->format('n'); + $endYears = $PHPEndDateObject->format('Y'); + + $PHPDiffDateObject = $PHPEndDateObject->diff($PHPStartDateObject); + + $retVal = false; + $retVal = self::replaceRetValue($retVal, $unit, 'D') ?? self::datedifD($difference); + $retVal = self::replaceRetValue($retVal, $unit, 'M') ?? self::datedifM($PHPDiffDateObject); + $retVal = self::replaceRetValue($retVal, $unit, 'MD') ?? self::datedifMD($startDays, $endDays, $PHPEndDateObject, $PHPDiffDateObject); + $retVal = self::replaceRetValue($retVal, $unit, 'Y') ?? self::datedifY($PHPDiffDateObject); + $retVal = self::replaceRetValue($retVal, $unit, 'YD') ?? self::datedifYD($difference, $startYears, $endYears, $PHPStartDateObject, $PHPEndDateObject); + $retVal = self::replaceRetValue($retVal, $unit, 'YM') ?? self::datedifYM($PHPDiffDateObject); + $retVal = self::replaceRetValue($retVal, 'D', 'D') ?? self::datedifInvalid(); + + return $retVal; + } + + private static function initialDiff(float $startDate, float $endDate): float + { + // Validate parameters + if ($startDate > $endDate) { + throw new Exception(Functions::NAN()); + } + + return $endDate - $startDate; + } + + /** + * Decide whether it's time to set retVal. + * + * @param bool|int $retVal + * + * @return null|int + */ + private static function replaceRetValue($retVal, string $unit, string $compare) + { + if ($retVal !== false || $unit !== $compare) { + return $retVal; + } + + return null; + } + + private static function datedifD(float $difference): int + { + return (int) $difference; + } + + private static function datedifM(DateInterval $PHPDiffDateObject): int + { + return (int) 12 * $PHPDiffDateObject->format('%y') + $PHPDiffDateObject->format('%m'); + } + + private static function datedifMD(float $startDays, float $endDays, DateTime $PHPEndDateObject, DateInterval $PHPDiffDateObject): int + { + if ($endDays < $startDays) { + $retVal = $endDays; + $PHPEndDateObject->modify('-' . $endDays . ' days'); + $adjustDays = $PHPEndDateObject->format('j'); + $retVal += ($adjustDays - $startDays); + } else { + $retVal = (int) $PHPDiffDateObject->format('%d'); + } + + return $retVal; + } + + private static function datedifY(DateInterval $PHPDiffDateObject): int + { + return $PHPDiffDateObject->format('%y'); + } + + private static function datedifYD(float $difference, float $startYears, float $endYears, DateTime $PHPStartDateObject, DateTime $PHPEndDateObject): int + { + $retVal = (int) $difference; + if ($endYears > $startYears) { + $isLeapStartYear = $PHPStartDateObject->format('L'); + $wasLeapEndYear = $PHPEndDateObject->format('L'); + + // Adjust end year to be as close as possible as start year + while ($PHPEndDateObject >= $PHPStartDateObject) { + $PHPEndDateObject->modify('-1 year'); + $endYears = $PHPEndDateObject->format('Y'); + } + $PHPEndDateObject->modify('+1 year'); + + // Get the result + $retVal = $PHPEndDateObject->diff($PHPStartDateObject)->days; + + // Adjust for leap years cases + $isLeapEndYear = $PHPEndDateObject->format('L'); + $limit = new DateTime($PHPEndDateObject->format('Y-02-29')); + if (!$isLeapStartYear && !$wasLeapEndYear && $isLeapEndYear && $PHPEndDateObject >= $limit) { + --$retVal; + } + } + + return $retVal; + } + + private static function datedifYM(DateInterval $PHPDiffDateObject): int + { + return $PHPDiffDateObject->format('%m'); + } + + private static function datedifInvalid(): string + { + return Functions::VALUE(); + } +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datefunc.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datefunc.php new file mode 100644 index 0000000000..ec8be2dfac --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datefunc.php @@ -0,0 +1,168 @@ +getMessage(); + } + + // Execute function + $excelDateValue = Date::formattedPHPToExcel($year, $month, $day); + + return Helpers::returnIn3FormatsFloat($excelDateValue); + } + + /** + * Convert year from multiple formats to int. + * + * @param mixed $year + */ + private static function getYear($year, int $baseYear): int + { + $year = Functions::flattenSingleValue($year); + $year = ($year !== null) ? StringHelper::testStringAsNumeric($year) : 0; + if (!is_numeric($year)) { + throw new Exception(Functions::VALUE()); + } + $year = (int) $year; + + if ($year < ($baseYear - 1900)) { + throw new Exception(Functions::NAN()); + } + if ((($baseYear - 1900) !== 0) && ($year < $baseYear) && ($year >= 1900)) { + throw new Exception(Functions::NAN()); + } + + if (($year < $baseYear) && ($year >= ($baseYear - 1900))) { + $year += 1900; + } + + return $year; + } + + /** + * Convert month from multiple formats to int. + * + * @param mixed $month + */ + private static function getMonth($month): int + { + $month = Functions::flattenSingleValue($month); + + if (($month !== null) && (!is_numeric($month))) { + $month = Date::monthStringToNumber($month); + } + + $month = ($month !== null) ? StringHelper::testStringAsNumeric($month) : 0; + if (!is_numeric($month)) { + throw new Exception(Functions::VALUE()); + } + + return (int) $month; + } + + /** + * Convert day from multiple formats to int. + * + * @param mixed $day + */ + private static function getDay($day): int + { + $day = Functions::flattenSingleValue($day); + + if (($day !== null) && (!is_numeric($day))) { + $day = Date::dayStringToNumber($day); + } + + $day = ($day !== null) ? StringHelper::testStringAsNumeric($day) : 0; + if (!is_numeric($day)) { + throw new Exception(Functions::VALUE()); + } + + return (int) $day; + } + + private static function adjustYearMonth(int &$year, int &$month, int $baseYear): void + { + if ($month < 1) { + // Handle year/month adjustment if month < 1 + --$month; + $year += ceil($month / 12) - 1; + $month = 13 - abs($month % 12); + } elseif ($month > 12) { + // Handle year/month adjustment if month > 12 + $year += floor($month / 12); + $month = ($month % 12); + } + + // Re-validate the year parameter after adjustments + if (($year < $baseYear) || ($year >= 10000)) { + throw new Exception(Functions::NAN()); + } + } +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datevalue.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datevalue.php new file mode 100644 index 0000000000..bb7febec96 --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datevalue.php @@ -0,0 +1,151 @@ + 31)) { + if ($yearFound) { + return Functions::VALUE(); + } + if ($t < 100) { + $t += 1900; + } + $yearFound = true; + } + } + if (count($t1) === 1) { + // We've been fed a time value without any date + return ((strpos($t, ':') === false)) ? Functions::Value() : 0.0; + } + unset($t); + + $dateValue = self::t1ToString($t1, $dti, $yearFound); + + $PHPDateArray = self::setUpArray($dateValue, $dti); + + return self::finalResults($PHPDateArray, $dti, $baseYear); + } + + private static function t1ToString(array $t1, DateTimeImmutable $dti, bool $yearFound): string + { + if (count($t1) == 2) { + // We only have two parts of the date: either day/month or month/year + if ($yearFound) { + array_unshift($t1, 1); + } else { + if (is_numeric($t1[1]) && $t1[1] > 29) { + $t1[1] += 1900; + array_unshift($t1, 1); + } else { + $t1[] = $dti->format('Y'); + } + } + } + $dateValue = implode(' ', $t1); + + return $dateValue; + } + + /** + * Parse date. + * + * @return array|false + */ + private static function setUpArray(string $dateValue, DateTimeImmutable $dti) + { + $PHPDateArray = date_parse($dateValue); + if (($PHPDateArray === false) || ($PHPDateArray['error_count'] > 0)) { + // If original count was 1, we've already returned. + // If it was 2, we added another. + // Therefore, neither of the first 2 stroks below can fail. + $testVal1 = strtok($dateValue, '- '); + $testVal2 = strtok('- '); + $testVal3 = strtok('- ') ?: $dti->format('Y'); + Helpers::adjustYear($testVal1, $testVal2, $testVal3); + $PHPDateArray = date_parse($testVal1 . '-' . $testVal2 . '-' . $testVal3); + if (($PHPDateArray === false) || ($PHPDateArray['error_count'] > 0)) { + $PHPDateArray = date_parse($testVal2 . '-' . $testVal1 . '-' . $testVal3); + } + } + + return $PHPDateArray; + } + + /** + * Final results. + * + * @param array|false $PHPDateArray + * + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + private static function finalResults($PHPDateArray, DateTimeImmutable $dti, int $baseYear) + { + $retValue = Functions::Value(); + if (($PHPDateArray !== false) && ($PHPDateArray['error_count'] == 0)) { + // Execute function + Helpers::replaceIfEmpty($PHPDateArray['year'], $dti->format('Y')); + if ($PHPDateArray['year'] < $baseYear) { + return Functions::VALUE(); + } + Helpers::replaceIfEmpty($PHPDateArray['month'], $dti->format('m')); + Helpers::replaceIfEmpty($PHPDateArray['day'], $dti->format('d')); + $PHPDateArray['hour'] = 0; + $PHPDateArray['minute'] = 0; + $PHPDateArray['second'] = 0; + $month = (int) $PHPDateArray['month']; + $day = (int) $PHPDateArray['day']; + $year = (int) $PHPDateArray['year']; + if (!checkdate($month, $day, $year)) { + return ($year === 1900 && $month === 2 && $day === 29) ? Helpers::returnIn3FormatsFloat(60.0) : Functions::VALUE(); + } + $retValue = is_array($PHPDateArray) ? Helpers::returnIn3FormatsArray($PHPDateArray, true) : Functions::VALUE(); + } + + return $retValue; + } +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Day.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Day.php new file mode 100644 index 0000000000..97e8a8b8c3 --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Day.php @@ -0,0 +1,62 @@ += 0) { + return $weirdResult; + } + + try { + $dateValue = Helpers::getDateValue($dateValue); + } catch (Exception $e) { + return $e->getMessage(); + } + + // Execute function + $PHPDateObject = Date::excelToDateTimeObject($dateValue); + + return (int) $PHPDateObject->format('j'); + } + + private static function weirdCondition($dateValue): int + { + // Excel does not treat 0 consistently for DAY vs. (MONTH or YEAR) + $retval = -1; + if (Date::getExcelCalendar() === DATE::CALENDAR_WINDOWS_1900 && Functions::getCompatibilityMode() == Functions::COMPATIBILITY_EXCEL) { + if (is_bool($dateValue)) { + return (int) $dateValue; + } + if ($dateValue === null) { + return 0; + } + if (is_numeric($dateValue) && $dateValue < 1 && $dateValue >= 0) { + return 0; + } + } + + return -1; + } +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days.php new file mode 100644 index 0000000000..e4403907ee --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days.php @@ -0,0 +1,48 @@ +getMessage(); + } + + // Execute function + $PHPStartDateObject = Date::excelToDateTimeObject($startDate); + $PHPEndDateObject = Date::excelToDateTimeObject($endDate); + + $diff = $PHPStartDateObject->diff($PHPEndDateObject); + $days = $diff->days; + + if ($diff->invert) { + $days = -$days; + } + + return $days; + } +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days360.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days360.php new file mode 100644 index 0000000000..46063825a9 --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days360.php @@ -0,0 +1,106 @@ +getMessage(); + } + + if (!is_bool($method)) { + return Functions::VALUE(); + } + + // Execute function + $PHPStartDateObject = Date::excelToDateTimeObject($startDate); + $startDay = $PHPStartDateObject->format('j'); + $startMonth = $PHPStartDateObject->format('n'); + $startYear = $PHPStartDateObject->format('Y'); + + $PHPEndDateObject = Date::excelToDateTimeObject($endDate); + $endDay = $PHPEndDateObject->format('j'); + $endMonth = $PHPEndDateObject->format('n'); + $endYear = $PHPEndDateObject->format('Y'); + + return self::dateDiff360($startDay, $startMonth, $startYear, $endDay, $endMonth, $endYear, !$method); + } + + /** + * Return the number of days between two dates based on a 360 day calendar. + */ + private static function dateDiff360(int $startDay, int $startMonth, int $startYear, int $endDay, int $endMonth, int $endYear, bool $methodUS): int + { + $startDay = self::getStartDay($startDay, $startMonth, $startYear, $methodUS); + $endDay = self::getEndDay($endDay, $endMonth, $endYear, $startDay, $methodUS); + + return $endDay + $endMonth * 30 + $endYear * 360 - $startDay - $startMonth * 30 - $startYear * 360; + } + + private static function getStartDay(int $startDay, int $startMonth, int $startYear, bool $methodUS): int + { + if ($startDay == 31) { + --$startDay; + } elseif ($methodUS && ($startMonth == 2 && ($startDay == 29 || ($startDay == 28 && !Helpers::isLeapYear($startYear))))) { + $startDay = 30; + } + + return $startDay; + } + + private static function getEndDay(int $endDay, int &$endMonth, int &$endYear, int $startDay, bool $methodUS): int + { + if ($endDay == 31) { + if ($methodUS && $startDay != 30) { + $endDay = 1; + if ($endMonth == 12) { + ++$endYear; + $endMonth = 1; + } else { + ++$endMonth; + } + } else { + $endDay = 30; + } + } + + return $endDay; + } +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Edate.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Edate.php new file mode 100644 index 0000000000..5bc8d7462e --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Edate.php @@ -0,0 +1,45 @@ +getMessage(); + } + $adjustmentMonths = floor($adjustmentMonths); + + // Execute function + $PHPDateObject = Helpers::adjustDateByMonths($dateValue, $adjustmentMonths); + + return Helpers::returnIn3FormatsObject($PHPDateObject); + } +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Eomonth.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Eomonth.php new file mode 100644 index 0000000000..021873c72a --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Eomonth.php @@ -0,0 +1,47 @@ +getMessage(); + } + $adjustmentMonths = floor($adjustmentMonths); + + // Execute function + $PHPDateObject = Helpers::adjustDateByMonths($dateValue, $adjustmentMonths + 1); + $adjustDays = (int) $PHPDateObject->format('d'); + $adjustDaysString = '-' . $adjustDays . ' days'; + $PHPDateObject->modify($adjustDaysString); + + return Helpers::returnIn3FormatsObject($PHPDateObject); + } +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php new file mode 100644 index 0000000000..44c7a73c99 --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php @@ -0,0 +1,287 @@ +getMessage(); + } + } + + /** + * getTimeValue. + * + * @param string $timeValue + * + * @return mixed Excel date/time serial value, or string if error + */ + public static function getTimeValue($timeValue) + { + $saveReturnDateType = Functions::getReturnDateType(); + Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); + $timeValue = Timevalue::funcTimeValue($timeValue); + Functions::setReturnDateType($saveReturnDateType); + + return $timeValue; + } + + public static function adjustDateByMonths($dateValue = 0, $adjustmentMonths = 0) + { + // Execute function + $PHPDateObject = Date::excelToDateTimeObject($dateValue); + $oMonth = (int) $PHPDateObject->format('m'); + $oYear = (int) $PHPDateObject->format('Y'); + + $adjustmentMonthsString = (string) $adjustmentMonths; + if ($adjustmentMonths > 0) { + $adjustmentMonthsString = '+' . $adjustmentMonths; + } + if ($adjustmentMonths != 0) { + $PHPDateObject->modify($adjustmentMonthsString . ' months'); + } + $nMonth = (int) $PHPDateObject->format('m'); + $nYear = (int) $PHPDateObject->format('Y'); + + $monthDiff = ($nMonth - $oMonth) + (($nYear - $oYear) * 12); + if ($monthDiff != $adjustmentMonths) { + $adjustDays = (int) $PHPDateObject->format('d'); + $adjustDaysString = '-' . $adjustDays . ' days'; + $PHPDateObject->modify($adjustDaysString); + } + + return $PHPDateObject; + } + + /** + * Help reduce perceived complexity of some tests. + * + * @param mixed $value + * @param mixed $altValue + */ + public static function replaceIfEmpty(&$value, $altValue): void + { + $value = $value ?: $altValue; + } + + /** + * Adjust year in ambiguous situations. + */ + public static function adjustYear(string $testVal1, string $testVal2, string &$testVal3): void + { + if (!is_numeric($testVal1) || $testVal1 < 31) { + if (!is_numeric($testVal2) || $testVal2 < 12) { + if (is_numeric($testVal3) && $testVal3 < 12) { + $testVal3 += 2000; + } + } + } + } + + /** + * Return result in one of three formats. + * + * @return mixed + */ + public static function returnIn3FormatsArray(array $dateArray, bool $noFrac = false) + { + $retType = Functions::getReturnDateType(); + if ($retType === Functions::RETURNDATE_PHP_DATETIME_OBJECT) { + return new DateTime( + $dateArray['year'] + . '-' . $dateArray['month'] + . '-' . $dateArray['day'] + . ' ' . $dateArray['hour'] + . ':' . $dateArray['minute'] + . ':' . $dateArray['second'] + ); + } + $excelDateValue = + Date::formattedPHPToExcel( + $dateArray['year'], + $dateArray['month'], + $dateArray['day'], + $dateArray['hour'], + $dateArray['minute'], + $dateArray['second'] + ); + if ($retType === Functions::RETURNDATE_EXCEL) { + return $noFrac ? floor($excelDateValue) : (float) $excelDateValue; + } + // RETURNDATE_UNIX_TIMESTAMP) + + return (int) Date::excelToTimestamp($excelDateValue); + } + + /** + * Return result in one of three formats. + * + * @return mixed + */ + public static function returnIn3FormatsFloat(float $excelDateValue) + { + $retType = Functions::getReturnDateType(); + if ($retType === Functions::RETURNDATE_EXCEL) { + return $excelDateValue; + } + if ($retType === Functions::RETURNDATE_UNIX_TIMESTAMP) { + return (int) Date::excelToTimestamp($excelDateValue); + } + // RETURNDATE_PHP_DATETIME_OBJECT + + return Date::excelToDateTimeObject($excelDateValue); + } + + /** + * Return result in one of three formats. + * + * @return mixed + */ + public static function returnIn3FormatsObject(DateTime $PHPDateObject) + { + $retType = Functions::getReturnDateType(); + if ($retType === Functions::RETURNDATE_PHP_DATETIME_OBJECT) { + return $PHPDateObject; + } + if ($retType === Functions::RETURNDATE_EXCEL) { + return (float) Date::PHPToExcel($PHPDateObject); + } + // RETURNDATE_UNIX_TIMESTAMP + + return (int) Date::excelToTimestamp(Date::PHPToExcel($PHPDateObject)); + } + + private static function baseDate(): int + { + if (Functions::getCompatibilityMode() === Functions::COMPATIBILITY_OPENOFFICE) { + return 0; + } + if (Date::getExcelCalendar() === Date::CALENDAR_MAC_1904) { + return 0; + } + + return 1; + } + + /** + * Many functions accept null/false/true argument treated as 0/0/1. + * + * @param mixed $number + */ + public static function nullFalseTrueToNumber(&$number, bool $allowBool = true): void + { + $number = Functions::flattenSingleValue($number); + $nullVal = self::baseDate(); + if ($number === null) { + $number = $nullVal; + } elseif ($allowBool && is_bool($number)) { + $number = $nullVal + (int) $number; + } + } + + /** + * Many functions accept null argument treated as 0. + * + * @param mixed $number + * + * @return float|int + */ + public static function validateNumericNull($number) + { + $number = Functions::flattenSingleValue($number); + if ($number === null) { + return 0; + } + if (is_numeric($number)) { + return $number; + } + + throw new Exception(Functions::VALUE()); + } + + /** + * Many functions accept null/false/true argument treated as 0/0/1. + * + * @param mixed $number + * + * @return float + */ + public static function validateNotNegative($number) + { + if (!is_numeric($number)) { + throw new Exception(Functions::VALUE()); + } + if ($number >= 0) { + return (float) $number; + } + + throw new Exception(Functions::NAN()); + } + + public static function silly1900(DateTime $PHPDateObject, string $mod = '-1 day'): void + { + $isoDate = $PHPDateObject->format('c'); + if ($isoDate < '1900-03-01') { + $PHPDateObject->modify($mod); + } + } +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Hour.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Hour.php new file mode 100644 index 0000000000..98d4570d08 --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Hour.php @@ -0,0 +1,44 @@ +getMessage(); + } + + // Execute function + $timeValue = fmod($timeValue, 1); + $timeValue = Date::excelToDateTimeObject($timeValue); + + return (int) $timeValue->format('H'); + } +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/IsoWeeknum.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/IsoWeeknum.php new file mode 100644 index 0000000000..7e8a8f736f --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/IsoWeeknum.php @@ -0,0 +1,55 @@ +getMessage(); + } + + // Execute function + $PHPDateObject = Date::excelToDateTimeObject($dateValue); + Helpers::silly1900($PHPDateObject); + + return (int) $PHPDateObject->format('W'); + } + + private static function apparentBug($dateValue): bool + { + if (Date::getExcelCalendar() !== DATE::CALENDAR_MAC_1904) { + if (is_bool($dateValue)) { + return true; + } + if (is_numeric($dateValue) && !((int) $dateValue)) { + return true; + } + } + + return false; + } +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Minute.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Minute.php new file mode 100644 index 0000000000..a1747ec9a7 --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Minute.php @@ -0,0 +1,44 @@ +getMessage(); + } + + // Execute function + $timeValue = fmod($timeValue, 1); + $timeValue = Date::excelToDateTimeObject($timeValue); + + return (int) $timeValue->format('i'); + } +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Month.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Month.php new file mode 100644 index 0000000000..a9fb8ece74 --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Month.php @@ -0,0 +1,40 @@ +getMessage(); + } + if ($dateValue < 1 && Date::getExcelCalendar() === DATE::CALENDAR_WINDOWS_1900) { + return 1; + } + + // Execute function + $PHPDateObject = Date::excelToDateTimeObject($dateValue); + + return (int) $PHPDateObject->format('n'); + } +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Networkdays.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Networkdays.php new file mode 100644 index 0000000000..5d36a47ea3 --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Networkdays.php @@ -0,0 +1,102 @@ +getMessage(); + } + + // Execute function + $startDow = self::calcStartDow($startDate); + $endDow = self::calcEndDow($endDate); + $wholeWeekDays = floor(($endDate - $startDate) / 7) * 5; + $partWeekDays = self::calcPartWeekDays($startDow, $endDow); + + // Test any extra holiday parameters + $holidayCountedArray = []; + foreach ($holidayArray as $holidayDate) { + if (($holidayDate >= $startDate) && ($holidayDate <= $endDate)) { + if ((Weekday::funcWeekday($holidayDate, 2) < 6) && (!in_array($holidayDate, $holidayCountedArray))) { + --$partWeekDays; + $holidayCountedArray[] = $holidayDate; + } + } + } + + return self::applySign($wholeWeekDays + $partWeekDays, $sDate, $eDate); + } + + private static function calcStartDow(float $startDate): int + { + $startDow = 6 - Weekday::funcWeekday($startDate, 2); + if ($startDow < 0) { + $startDow = 5; + } + + return $startDow; + } + + private static function calcEndDow(float $endDate): int + { + $endDow = Weekday::funcWeekday($endDate, 2); + if ($endDow >= 6) { + $endDow = 0; + } + + return $endDow; + } + + private static function calcPartWeekDays(int $startDow, int $endDow): int + { + $partWeekDays = $endDow + $startDow; + if ($partWeekDays > 5) { + $partWeekDays -= 5; + } + + return $partWeekDays; + } + + private static function applySign(int $result, int $sDate, int $eDate) + { + return ($sDate > $eDate) ? -$result : $result; + } +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Now.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Now.php new file mode 100644 index 0000000000..6e6bd17155 --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Now.php @@ -0,0 +1,34 @@ +format('c')); + + return is_array($dateArray) ? Helpers::returnIn3FormatsArray($dateArray) : Functions::VALUE(); + } +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Second.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Second.php new file mode 100644 index 0000000000..c47499932e --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Second.php @@ -0,0 +1,44 @@ +getMessage(); + } + + // Execute function + $timeValue = fmod($timeValue, 1); + $timeValue = Date::excelToDateTimeObject($timeValue); + + return (int) $timeValue->format('s'); + } +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Time.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Time.php new file mode 100644 index 0000000000..450f9d508d --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Time.php @@ -0,0 +1,116 @@ +getMessage(); + } + + self::adjustSecond($second, $minute); + self::adjustMinute($minute, $hour); + + if ($hour > 23) { + $hour = $hour % 24; + } elseif ($hour < 0) { + return Functions::NAN(); + } + + // Execute function + $retType = Functions::getReturnDateType(); + if ($retType === Functions::RETURNDATE_EXCEL) { + $calendar = Date::getExcelCalendar(); + $date = (int) ($calendar !== Date::CALENDAR_WINDOWS_1900); + + return (float) Date::formattedPHPToExcel($calendar, 1, $date, $hour, $minute, $second); + } + if ($retType === Functions::RETURNDATE_UNIX_TIMESTAMP) { + return (int) Date::excelToTimestamp(Date::formattedPHPToExcel(1970, 1, 1, $hour, $minute, $second)); // -2147468400; // -2147472000 + 3600 + } + // RETURNDATE_PHP_DATETIME_OBJECT + // Hour has already been normalized (0-23) above + $phpDateObject = new DateTime('1900-01-01 ' . $hour . ':' . $minute . ':' . $second); + + return $phpDateObject; + } + + private static function adjustSecond(int &$second, int &$minute): void + { + if ($second < 0) { + $minute += floor($second / 60); + $second = 60 - abs($second % 60); + if ($second == 60) { + $second = 0; + } + } elseif ($second >= 60) { + $minute += floor($second / 60); + $second = $second % 60; + } + } + + private static function adjustMinute(int &$minute, int &$hour): void + { + if ($minute < 0) { + $hour += floor($minute / 60); + $minute = 60 - abs($minute % 60); + if ($minute == 60) { + $minute = 0; + } + } elseif ($minute >= 60) { + $hour += floor($minute / 60); + $minute = $minute % 60; + } + } + + private static function toIntWithNullBool($value): int + { + $value = Functions::flattenSingleValue($value); + $value = $value ?? 0; + if (is_bool($value)) { + $value = (int) $value; + } + if (!is_numeric($value)) { + throw new Exception(Functions::VALUE()); + } + + return (int) $value; + } +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Timevalue.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Timevalue.php new file mode 100644 index 0000000000..9f7df0f4f0 --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Timevalue.php @@ -0,0 +1,61 @@ + 24) { + $arraySplit[0] = ($arraySplit[0] % 24); + $timeValue = implode(':', $arraySplit); + } + + $PHPDateArray = date_parse($timeValue); + $retValue = Functions::VALUE(); + if (($PHPDateArray !== false) && ($PHPDateArray['error_count'] == 0)) { + // OpenOffice-specific code removed - it works just like Excel + $excelDateValue = Date::formattedPHPToExcel(1900, 1, 1, $PHPDateArray['hour'], $PHPDateArray['minute'], $PHPDateArray['second']) - 1; + + $retType = Functions::getReturnDateType(); + if ($retType === Functions::RETURNDATE_EXCEL) { + $retValue = (float) $excelDateValue; + } elseif ($retType === Functions::RETURNDATE_UNIX_TIMESTAMP) { + $retValue = (int) $phpDateValue = Date::excelToTimestamp($excelDateValue + 25569) - 3600; + } else { + $retValue = new DateTime('1900-01-01 ' . $PHPDateArray['hour'] . ':' . $PHPDateArray['minute'] . ':' . $PHPDateArray['second']); + } + } + + return $retValue; + } +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Today.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Today.php new file mode 100644 index 0000000000..5e459410c2 --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Today.php @@ -0,0 +1,34 @@ +format('c')); + + return is_array($dateArray) ? Helpers::returnIn3FormatsArray($dateArray, true) : Functions::VALUE(); + } +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Weekday.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Weekday.php new file mode 100644 index 0000000000..4cb0a73db9 --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Weekday.php @@ -0,0 +1,80 @@ +getMessage(); + } + + // Execute function + $PHPDateObject = Date::excelToDateTimeObject($dateValue); + Helpers::silly1900($PHPDateObject); + $DoW = (int) $PHPDateObject->format('w'); + + switch ($style) { + case 1: + ++$DoW; + + break; + case 2: + $DoW = self::dow0Becomes7($DoW); + + break; + case 3: + $DoW = self::dow0Becomes7($DoW) - 1; + + break; + } + + return $DoW; + } + + private static function validateStyle($style): int + { + $style = Functions::flattenSingleValue($style); + + if (!is_numeric($style)) { + throw new Exception(Functions::VALUE()); + } + $style = (int) $style; + if (($style < 1) || ($style > 3)) { + throw new Exception(Functions::NAN()); + } + + return $style; + } + + private static function dow0Becomes7(int $DoW): int + { + return ($DoW === 0) ? 7 : $DoW; + } +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Weeknum.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Weeknum.php new file mode 100644 index 0000000000..2ed80948fd --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Weeknum.php @@ -0,0 +1,160 @@ + self::DOW_SUNDAY, + self::DOW_MONDAY, + self::STARTWEEK_MONDAY_ALT => self::DOW_MONDAY, + self::DOW_TUESDAY, + self::DOW_WEDNESDAY, + self::DOW_THURSDAY, + self::DOW_FRIDAY, + self::DOW_SATURDAY, + self::DOW_SUNDAY, + self::STARTWEEK_MONDAY_ISO => self::STARTWEEK_MONDAY_ISO, + ]; + + /** + * WEEKNUM. + * + * Returns the week of the year for a specified date. + * The WEEKNUM function considers the week containing January 1 to be the first week of the year. + * However, there is a European standard that defines the first week as the one with the majority + * of days (four or more) falling in the new year. This means that for years in which there are + * three days or less in the first week of January, the WEEKNUM function returns week numbers + * that are incorrect according to the European standard. + * + * Excel Function: + * WEEKNUM(dateValue[,style]) + * + * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param int $method Week begins on Sunday or Monday + * 1 or omitted Week begins on Sunday. + * 2 Week begins on Monday. + * 11 Week begins on Monday. + * 12 Week begins on Tuesday. + * 13 Week begins on Wednesday. + * 14 Week begins on Thursday. + * 15 Week begins on Friday. + * 16 Week begins on Saturday. + * 17 Week begins on Sunday. + * 21 ISO (Jan. 4 is week 1, begins on Monday). + * + * @return int|string Week Number + */ + public static function funcWeeknum($dateValue, $method = self::STARTWEEK_SUNDAY) + { + $origDateValueNull = empty($dateValue); + + try { + $method = self::validateMethod($method); + if ($dateValue === null) { // boolean not allowed + $dateValue = (Date::getExcelCalendar() === DATE::CALENDAR_MAC_1904 || $method === self::DOW_SUNDAY) ? 0 : 1; + } + $dateValue = self::validateDateValue($dateValue); + if (!$dateValue && self::buggyWeekNum1900($method)) { + // This seems to be an additional Excel bug. + return 0; + } + } catch (Exception $e) { + return $e->getMessage(); + } + + // Execute function + $PHPDateObject = Date::excelToDateTimeObject($dateValue); + if ($method == self::STARTWEEK_MONDAY_ISO) { + Helpers::silly1900($PHPDateObject); + + return (int) $PHPDateObject->format('W'); + } + if (self::buggyWeekNum1904($method, $origDateValueNull, $PHPDateObject)) { + return 0; + } + Helpers::silly1900($PHPDateObject, '+ 5 years'); // 1905 calendar matches + $dayOfYear = $PHPDateObject->format('z'); + $PHPDateObject->modify('-' . $dayOfYear . ' days'); + $firstDayOfFirstWeek = $PHPDateObject->format('w'); + $daysInFirstWeek = (6 - $firstDayOfFirstWeek + $method) % 7; + $daysInFirstWeek += 7 * !$daysInFirstWeek; + $endFirstWeek = $daysInFirstWeek - 1; + $weekOfYear = floor(($dayOfYear - $endFirstWeek + 13) / 7); + + return (int) $weekOfYear; + } + + /** + * Validate dateValue parameter. + * + * @param mixed $dateValue + */ + private static function validateDateValue($dateValue): int + { + if (is_bool($dateValue)) { + throw new Exception(Functions::VALUE()); + } + + return Helpers::getDateValue($dateValue); + } + + /** + * Validate method parameter. + * + * @param mixed $method + */ + private static function validateMethod($method): int + { + if ($method === null) { + $method = self::STARTWEEK_SUNDAY; + } + $method = Functions::flattenSingleValue($method); + if (!is_numeric($method)) { + throw new Exception(Functions::VALUE()); + } + + $method = (int) $method; + if (!array_key_exists($method, self::METHODARR)) { + throw new Exception(Functions::NAN()); + } + $method = self::METHODARR[$method]; + + return $method; + } + + private static function buggyWeekNum1900(int $method): bool + { + return $method === self::DOW_SUNDAY && Date::getExcelCalendar() === Date::CALENDAR_WINDOWS_1900; + } + + private static function buggyWeekNum1904(int $method, bool $origNull, DateTime $dateObject): bool + { + // This appears to be another Excel bug. + + return $method === self::DOW_SUNDAY && Date::getExcelCalendar() === Date::CALENDAR_MAC_1904 && !$origNull && $dateObject->format('Y-m-d') === '1904-01-01'; + } +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Workday.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Workday.php new file mode 100644 index 0000000000..811033aed3 --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Workday.php @@ -0,0 +1,182 @@ +getMessage(); + } + + $startDate = (float) floor($startDate); + $endDays = (int) floor($endDays); + // If endDays is 0, we always return startDate + if ($endDays == 0) { + return $startDate; + } + if ($endDays < 0) { + return self::decrementing($startDate, $endDays, $holidayArray); + } + + return self::incrementing($startDate, $endDays, $holidayArray); + } + + /** + * Use incrementing logic to determine Workday. + * + * @return mixed + */ + private static function incrementing(float $startDate, int $endDays, array $holidayArray) + { + // Adjust the start date if it falls over a weekend + + $startDoW = weekday::funcWeekday($startDate, 3); + if (Weekday::funcWeekday($startDate, 3) >= 5) { + $startDate += 7 - $startDoW; + --$endDays; + } + + // Add endDays + $endDate = (float) $startDate + ((int) ($endDays / 5) * 7); + $endDays = $endDays % 5; + while ($endDays > 0) { + ++$endDate; + // Adjust the calculated end date if it falls over a weekend + $endDow = Weekday::funcWeekday($endDate, 3); + if ($endDow >= 5) { + $endDate += 7 - $endDow; + } + --$endDays; + } + + // Test any extra holiday parameters + if (!empty($holidayArray)) { + $endDate = self::incrementingArray($startDate, $endDate, $holidayArray); + } + + return Helpers::returnIn3FormatsFloat($endDate); + } + + private static function incrementingArray(float $startDate, float $endDate, array $holidayArray): float + { + $holidayCountedArray = $holidayDates = []; + foreach ($holidayArray as $holidayDate) { + if (Weekday::funcWeekday($holidayDate, 3) < 5) { + $holidayDates[] = $holidayDate; + } + } + sort($holidayDates, SORT_NUMERIC); + foreach ($holidayDates as $holidayDate) { + if (($holidayDate >= $startDate) && ($holidayDate <= $endDate)) { + if (!in_array($holidayDate, $holidayCountedArray)) { + ++$endDate; + $holidayCountedArray[] = $holidayDate; + } + } + // Adjust the calculated end date if it falls over a weekend + $endDoW = Weekday::funcWeekDay($endDate, 3); + if ($endDoW >= 5) { + $endDate += 7 - $endDoW; + } + } + + return $endDate; + } + + /** + * Use decrementing logic to determine Workday. + * + * @return mixed + */ + private static function decrementing(float $startDate, int $endDays, array $holidayArray) + { + // Adjust the start date if it falls over a weekend + + $startDoW = weekday::funcWeekday($startDate, 3); + if (Weekday::funcWeekday($startDate, 3) >= 5) { + $startDate += -$startDoW + 4; + ++$endDays; + } + + // Add endDays + $endDate = (float) $startDate + ((int) ($endDays / 5) * 7); + $endDays = $endDays % 5; + while ($endDays < 0) { + --$endDate; + // Adjust the calculated end date if it falls over a weekend + $endDow = Weekday::funcWeekday($endDate, 3); + if ($endDow >= 5) { + $endDate += 4 - $endDow; + } + ++$endDays; + } + + // Test any extra holiday parameters + if (!empty($holidayArray)) { + $endDate = self::decrementingArray($startDate, $endDate, $holidayArray); + } + + return Helpers::returnIn3FormatsFloat($endDate); + } + + private static function decrementingArray(float $startDate, float $endDate, array $holidayArray): float + { + $holidayCountedArray = $holidayDates = []; + foreach ($holidayArray as $holidayDate) { + if (Weekday::funcWeekday($holidayDate, 3) < 5) { + $holidayDates[] = $holidayDate; + } + } + rsort($holidayDates, SORT_NUMERIC); + foreach ($holidayDates as $holidayDate) { + if (($holidayDate <= $startDate) && ($holidayDate >= $endDate)) { + if (!in_array($holidayDate, $holidayCountedArray)) { + --$endDate; + $holidayCountedArray[] = $holidayDate; + } + } + // Adjust the calculated end date if it falls over a weekend + $endDoW = Weekday::funcWeekDay($endDate, 3); + if ($endDoW >= 5) { + $endDate += -$endDoW + 4; + } + } + + return $endDate; + } +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Year.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Year.php new file mode 100644 index 0000000000..5fcac73904 --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Year.php @@ -0,0 +1,40 @@ +getMessage(); + } + + if ($dateValue < 1 && Date::getExcelCalendar() === DATE::CALENDAR_WINDOWS_1900) { + return 1900; + } + // Execute function + $PHPDateObject = Date::excelToDateTimeObject($dateValue); + + return (int) $PHPDateObject->format('Y'); + } +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php new file mode 100644 index 0000000000..86fe83a7df --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php @@ -0,0 +1,97 @@ +getMessage(); + } + + switch ($method) { + case 0: + return Days360::funcDays360($startDate, $endDate) / 360; + case 1: + return self::method1($startDate, $endDate, $method); + case 2: + return Datedif::funcDatedif($startDate, $endDate) / 360; + case 3: + return Datedif::funcDatedif($startDate, $endDate) / 365; + case 4: + return Days360::funcDays360($startDate, $endDate, true) / 360; + } + + return Functions::NAN(); + } + + private static function method1(float $startDate, float $endDate, int $method): float + { + $days = Datedif::funcDatedif($startDate, $endDate); + $startYear = Year::funcYear($startDate); + $endYear = Year::funcYear($endDate); + $years = $endYear - $startYear + 1; + $startMonth = Month::funcMonth($startDate); + $startDay = Day::funcDay($startDate); + $endMonth = Month::funcMonth($endDate); + $endDay = Day::funcDay($endDate); + $startMonthDay = 100 * $startMonth + $startDay; + $endMonthDay = 100 * $endMonth + $endDay; + if ($years == 1) { + $tmpCalcAnnualBasis = 365 + (int) Helpers::isLeapYear($endYear); + } elseif ($years == 2 && $startMonthDay >= $endMonthDay) { + if (Helpers::isLeapYear($startYear)) { + $tmpCalcAnnualBasis = 365 + (int) ($startMonthDay <= 229); + } elseif (Helpers::isLeapYear($endYear)) { + $tmpCalcAnnualBasis = 365 + (int) ($endMonthDay >= 229); + } else { + $tmpCalcAnnualBasis = 365; + } + } else { + $tmpCalcAnnualBasis = 0; + for ($year = $startYear; $year <= $endYear; ++$year) { + $tmpCalcAnnualBasis += 365 + (int) Helpers::isLeapYear($year); + } + $tmpCalcAnnualBasis /= $years; + } + + return $days / $tmpCalcAnnualBasis; + } +} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/AllSetupTeardown.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/AllSetupTeardown.php new file mode 100644 index 0000000000..709a83c8b4 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/AllSetupTeardown.php @@ -0,0 +1,71 @@ +compatibilityMode = Functions::getCompatibilityMode(); + $this->excelCalendar = Date::getExcelCalendar(); + $this->returnDateType = Functions::getReturnDateType(); + $this->spreadsheet = new Spreadsheet(); + $this->sheet = $this->spreadsheet->getActiveSheet(); + } + + protected function tearDown(): void + { + Date::setExcelCalendar($this->excelCalendar); + Functions::setCompatibilityMode($this->compatibilityMode); + Functions::setReturnDateType($this->returnDateType); + $this->spreadsheet->disconnectWorksheets(); + $this->spreadsheet = null; + $this->sheet = null; + } + + protected function setMac1904(): void + { + Date::setExcelCalendar(Date::CALENDAR_MAC_1904); + } + + protected function setUnixReturn(): void + { + Functions::setReturnDateType(Functions::RETURNDATE_UNIX_TIMESTAMP); + } + + protected function setObjectReturn(): void + { + Functions::setReturnDateType(Functions::RETURNDATE_PHP_DATETIME_OBJECT); + } + + protected function setOpenOffice(): void + { + Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); + } + + /** + * @param mixed $expectedResult + */ + protected function mightHaveException($expectedResult): void + { + if ($expectedResult === 'exception') { + $this->expectException(CalcException::class); + } + } +} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateDifTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateDifTest.php index db8e29a1f7..e772eaa16c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateDifTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateDifTest.php @@ -2,32 +2,20 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Shared\Date; -use PHPUnit\Framework\TestCase; - -class DateDifTest extends TestCase +class DateDifTest extends AllSetupTeardown { - protected function setUp(): void - { - Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); - Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900); - } - /** * @dataProvider providerDATEDIF * * @param mixed $expectedResult - * @param $startDate - * @param $endDate - * @param $unit */ - public function testDATEDIF($expectedResult, $startDate, $endDate, $unit): void + public function testDATEDIF($expectedResult, string $formula): void { - $result = DateTime::DATEDIF($startDate, $endDate, $unit); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); + self::mightHaveException($expectedResult); + $sheet = $this->sheet; + $sheet->getCell('B1')->setValue('1954-11-23'); + $sheet->getCell('A1')->setValue("=DATEDIF($formula)"); + self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue()); } public function providerDATEDIF() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateTest.php index aad59729be..ff45a6dd6a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateTest.php @@ -2,42 +2,22 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Shared\Date; -use PHPUnit\Framework\TestCase; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Datefunc; -class DateTest extends TestCase +class DateTest extends AllSetupTeardown { - private $returnDateType; - - private $excelCalendar; - - protected function setUp(): void - { - $this->returnDateType = Functions::getReturnDateType(); - $this->excelCalendar = Date::getExcelCalendar(); - Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - } - - protected function tearDown(): void - { - Functions::setReturnDateType($this->returnDateType); - Date::setExcelCalendar($this->excelCalendar); - } - /** * @dataProvider providerDATE * * @param mixed $expectedResult - * @param $year - * @param $month - * @param $day */ - public function testDATE($expectedResult, $year, $month, $day): void + public function testDATE($expectedResult, string $formula): void { - $result = DateTime::DATE($year, $month, $day); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); + self::mightHaveException($expectedResult); + $sheet = $this->sheet; + $sheet->getCell('B1')->setValue('1954-11-23'); + $sheet->getCell('A1')->setValue("=DATE($formula)"); + self::assertEquals($expectedResult, $sheet->getCell('A1')->getCalculatedValue()); } public function providerDATE() @@ -47,18 +27,17 @@ public function providerDATE() public function testDATEtoUnixTimestamp(): void { - Functions::setReturnDateType(Functions::RETURNDATE_UNIX_TIMESTAMP); + self::setUnixReturn(); - $result = DateTime::DATE(2012, 1, 31); + $result = Datefunc::funcDate(2012, 1, 31); // 32-bit safe self::assertEquals(1327968000, $result); - self::assertEqualsWithDelta(1327968000, $result, 1E-8); } public function testDATEtoDateTimeObject(): void { - Functions::setReturnDateType(Functions::RETURNDATE_PHP_DATETIME_OBJECT); + self::setObjectReturn(); - $result = DateTime::DATE(2012, 1, 31); + $result = Datefunc::funcDate(2012, 1, 31); // Must return an object... self::assertIsObject($result); // ... of the correct type @@ -69,17 +48,12 @@ public function testDATEtoDateTimeObject(): void public function testDATEwith1904Calendar(): void { - Date::setExcelCalendar(Date::CALENDAR_MAC_1904); + self::setMac1904(); - $result = DateTime::DATE(1918, 11, 11); + $result = Datefunc::funcDate(1918, 11, 11); self::assertEquals($result, 5428); - } - - public function testDATEwith1904CalendarError(): void - { - Date::setExcelCalendar(Date::CALENDAR_MAC_1904); - $result = DateTime::DATE(1901, 1, 31); + $result = Datefunc::funcDate(1901, 1, 31); self::assertEquals($result, '#NUM!'); } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateValueTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateValueTest.php index 72e036f95d..f5aab0ddc6 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateValueTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateValueTest.php @@ -4,50 +4,33 @@ use DateTimeImmutable; use DateTimeInterface; -use PhpOffice\PhpSpreadsheet\Calculation\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Shared\Date; -use PHPUnit\Framework\TestCase; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\DateValue; -class DateValueTest extends TestCase +class DateValueTest extends AllSetupTeardown { - private $returnDateType; - - private $excelCalendar; - - protected function setUp(): void - { - $this->returnDateType = Functions::getReturnDateType(); - $this->excelCalendar = Date::getExcelCalendar(); - Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - } - - protected function tearDown(): void - { - Functions::setReturnDateType($this->returnDateType); - Date::setExcelCalendar($this->excelCalendar); - } - /** * @dataProvider providerDATEVALUE * * @param mixed $expectedResult - * @param $dateValue */ - public function testDATEVALUE($expectedResult, $dateValue): void + public function testDATEVALUE($expectedResult, string $dateValue): void { + $this->sheet->getCell('B1')->setValue('1954-07-20'); // Loop to avoid extraordinarily rare edge case where first calculation // and second do not take place on same day. + $row = 0; do { + ++$row; $dtStart = new DateTimeImmutable(); $startDay = $dtStart->format('d'); if (is_string($expectedResult)) { $replYMD = str_replace('Y', date('Y'), $expectedResult); if ($replYMD !== $expectedResult) { - $expectedResult = DateTime::DATEVALUE($replYMD); + $expectedResult = Datevalue::funcDateValue($replYMD); } } - $result = DateTime::DATEVALUE($dateValue); + $this->sheet->getCell("A$row")->setValue("=DATEVALUE($dateValue)"); + $result = $this->sheet->getCell("A$row")->getCalculatedValue(); $dtEnd = new DateTimeImmutable(); $endDay = $dtEnd->format('d'); } while ($startDay !== $endDay); @@ -61,18 +44,18 @@ public function providerDATEVALUE() public function testDATEVALUEtoUnixTimestamp(): void { - Functions::setReturnDateType(Functions::RETURNDATE_UNIX_TIMESTAMP); + self::setUnixReturn(); - $result = DateTime::DATEVALUE('2012-1-31'); + $result = Datevalue::funcDateValue('2012-1-31'); self::assertEquals(1327968000, $result); self::assertEqualsWithDelta(1327968000, $result, 1E-8); } public function testDATEVALUEtoDateTimeObject(): void { - Functions::setReturnDateType(Functions::RETURNDATE_PHP_DATETIME_OBJECT); + self::setObjectReturn(); - $result = DateTime::DATEVALUE('2012-1-31'); + $result = Datevalue::funcDateValue('2012-1-31'); // Must return an object... self::assertIsObject($result); // ... of the correct type @@ -83,10 +66,10 @@ public function testDATEVALUEtoDateTimeObject(): void public function testDATEVALUEwith1904Calendar(): void { - Date::setExcelCalendar(Date::CALENDAR_MAC_1904); - self::assertEquals(5428, DateTime::DATEVALUE('1918-11-11')); - self::assertEquals(0, DateTime::DATEVALUE('1904-01-01')); - self::assertEquals('#VALUE!', DateTime::DATEVALUE('1903-12-31')); - self::assertEquals('#VALUE!', DateTime::DATEVALUE('1900-02-29')); + self::setMac1904(); + self::assertEquals(5428, Datevalue::funcDateValue('1918-11-11')); + self::assertEquals(0, Datevalue::funcDateValue('1904-01-01')); + self::assertEquals('#VALUE!', Datevalue::funcDateValue('1903-12-31')); + self::assertEquals('#VALUE!', Datevalue::funcDateValue('1900-02-29')); } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DayTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DayTest.php index 482e068d7e..7c54911d30 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DayTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DayTest.php @@ -2,56 +2,43 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Shared\Date; -use PHPUnit\Framework\TestCase; - -class DayTest extends TestCase +class DayTest extends AllSetupTeardown { - private $compatibilityMode; - - private $returnDateType; - - private $excelCalendar; - - protected function setUp(): void + /** + * @dataProvider providerDAY + * + * @param mixed $expectedResultExcel + */ + public function testDAY($expectedResultExcel, string $dateTimeValue): void { - $this->compatibilityMode = Functions::getCompatibilityMode(); - $this->returnDateType = Functions::getReturnDateType(); - $this->excelCalendar = Date::getExcelCalendar(); - Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); - Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900); + self::mightHaveException($expectedResultExcel); + $sheet = $this->sheet; + $sheet->getCell('B1')->setValue('1954-11-23'); + $sheet->getCell('A1')->setValue("=DAY($dateTimeValue)"); + self::assertSame($expectedResultExcel, $sheet->getCell('A1')->getCalculatedValue()); } - protected function tearDown(): void + public function providerDAY() { - Functions::setCompatibilityMode($this->compatibilityMode); - Functions::setReturnDateType($this->returnDateType); - Date::setExcelCalendar($this->excelCalendar); + return require 'tests/data/Calculation/DateTime/DAY.php'; } /** - * @dataProvider providerDAY + * @dataProvider providerDAYOpenOffice * - * @param mixed $expectedResultExcel * @param mixed $expectedResultOpenOffice - * @param $dateTimeValue */ - public function testDAY($expectedResultExcel, $expectedResultOpenOffice, $dateTimeValue): void + public function testDAYOpenOffice($expectedResultOpenOffice, string $dateTimeValue): void { - $resultExcel = DateTime::DAYOFMONTH($dateTimeValue); - self::assertEqualsWithDelta($expectedResultExcel, $resultExcel, 1E-8); - - Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); - - $resultOpenOffice = DateTime::DAYOFMONTH($dateTimeValue); - self::assertEqualsWithDelta($expectedResultOpenOffice, $resultOpenOffice, 1E-8); + self::setOpenOffice(); + self::mightHaveException($expectedResultOpenOffice); + $sheet = $this->sheet; + $sheet->getCell('A2')->setValue("=DAY($dateTimeValue)"); + self::assertSame($expectedResultOpenOffice, $sheet->getCell('A2')->getCalculatedValue()); } - public function providerDAY() + public function providerDAYOpenOffice() { - return require 'tests/data/Calculation/DateTime/DAY.php'; + return require 'tests/data/Calculation/DateTime/DAYOpenOffice.php'; } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/Days360Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/Days360Test.php index 47449e0d17..8b054fa5a4 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/Days360Test.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/Days360Test.php @@ -2,32 +2,21 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Shared\Date; -use PHPUnit\Framework\TestCase; - -class Days360Test extends TestCase +class Days360Test extends AllSetupTeardown { - protected function setUp(): void - { - Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); - Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900); - } - /** * @dataProvider providerDAYS360 * * @param mixed $expectedResult - * @param $startDate - * @param $endDate - * @param $method */ - public function testDAYS360($expectedResult, $startDate, $endDate, $method): void + public function testDAYS360($expectedResult, string $formula): void { - $result = DateTime::DAYS360($startDate, $endDate, $method); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); + self::mightHaveException($expectedResult); + $sheet = $this->sheet; + $sheet->getCell('B1')->setValue('2000-02-29'); + $sheet->getCell('C1')->setValue('2000-03-31'); + $sheet->getCell('A1')->setValue("=DAYS360($formula)"); + self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue()); } public function providerDAYS360() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DaysTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DaysTest.php index fe31dfcc7e..f64c98aa22 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DaysTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DaysTest.php @@ -2,35 +2,36 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Shared\Date; -use PHPUnit\Framework\TestCase; +use DateTime; +use DateTimeImmutable; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Days; -class DaysTest extends TestCase +class DaysTest extends AllSetupTeardown { - protected function setUp(): void - { - Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); - Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900); - } - /** * @dataProvider providerDAYS * * @param mixed $expectedResult - * @param $endDate - * @param $startDate */ - public function testDAYS($expectedResult, $endDate, $startDate): void + public function testDAYS($expectedResult, string $formula): void { - $result = DateTime::DAYS($endDate, $startDate); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); + self::mightHaveException($expectedResult); + $sheet = $this->sheet; + $sheet->getCell('B1')->setValue('1954-11-23'); + $sheet->getCell('C1')->setValue('1954-11-30'); + $sheet->getCell('A1')->setValue("=DAYS($formula)"); + self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue()); } public function providerDAYS() { return require 'tests/data/Calculation/DateTime/DAYS.php'; } + + public function testObject(): void + { + $obj1 = new DateTime('2000-3-31'); + $obj2 = new DateTimeImmutable('2000-2-29'); + self::assertSame(31, Days::funcDays($obj1, $obj2)); + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EDateTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EDateTest.php index a887ba5b63..2f9707eba2 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EDateTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EDateTest.php @@ -2,31 +2,22 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Shared\Date; -use PHPUnit\Framework\TestCase; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Edate; -class EDateTest extends TestCase +class EDateTest extends AllSetupTeardown { - protected function setUp(): void - { - Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); - Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900); - } - /** * @dataProvider providerEDATE * * @param mixed $expectedResult - * @param $dateValue - * @param $adjustmentMonths */ - public function testEDATE($expectedResult, $dateValue, $adjustmentMonths): void + public function testEDATE($expectedResult, string $formula): void { - $result = DateTime::EDATE($dateValue, $adjustmentMonths); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); + self::mightHaveException($expectedResult); + $sheet = $this->sheet; + $sheet->getCell('A1')->setValue("=EDATE($formula)"); + $sheet->getCell('B1')->setValue('1954-11-23'); + self::assertEquals($expectedResult, $sheet->getCell('A1')->getCalculatedValue()); } public function providerEDATE() @@ -36,18 +27,18 @@ public function providerEDATE() public function testEDATEtoUnixTimestamp(): void { - Functions::setReturnDateType(Functions::RETURNDATE_UNIX_TIMESTAMP); + self::setUnixReturn(); - $result = DateTime::EDATE('2012-1-26', -1); + $result = Edate::funcEdate('2012-1-26', -1); self::assertEquals(1324857600, $result); self::assertEqualsWithDelta(1324857600, $result, 1E-8); } public function testEDATEtoDateTimeObject(): void { - Functions::setReturnDateType(Functions::RETURNDATE_PHP_DATETIME_OBJECT); + self::setObjectReturn(); - $result = DateTime::EDATE('2012-1-26', -1); + $result = Edate::funcEdate('2012-1-26', -1); // Must return an object... self::assertIsObject($result); // ... of the correct type diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EoMonthTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EoMonthTest.php index f9c54039e1..85fc77d9b0 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EoMonthTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EoMonthTest.php @@ -2,31 +2,22 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Shared\Date; -use PHPUnit\Framework\TestCase; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Eomonth; -class EoMonthTest extends TestCase +class EoMonthTest extends AllSetupTeardown { - protected function setUp(): void - { - Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); - Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900); - } - /** * @dataProvider providerEOMONTH * * @param mixed $expectedResult - * @param $dateValue - * @param $adjustmentMonths */ - public function testEOMONTH($expectedResult, $dateValue, $adjustmentMonths): void + public function testEOMONTH($expectedResult, string $formula): void { - $result = DateTime::EOMONTH($dateValue, $adjustmentMonths); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); + self::mightHaveException($expectedResult); + $sheet = $this->sheet; + $sheet->getCell('A1')->setValue("=EOMONTH($formula)"); + $sheet->getCell('B1')->setValue('1954-11-23'); + self::assertEquals($expectedResult, $sheet->getCell('A1')->getCalculatedValue()); } public function providerEOMONTH() @@ -36,23 +27,22 @@ public function providerEOMONTH() public function testEOMONTHtoUnixTimestamp(): void { - Functions::setReturnDateType(Functions::RETURNDATE_UNIX_TIMESTAMP); + self::setUnixReturn(); - $result = DateTime::EOMONTH('2012-1-26', -1); + $result = Eomonth::funcEomonth('2012-1-26', -1); self::assertEquals(1325289600, $result); - self::assertEqualsWithDelta(1325289600, $result, 1E-8); } public function testEOMONTHtoDateTimeObject(): void { - Functions::setReturnDateType(Functions::RETURNDATE_PHP_DATETIME_OBJECT); + self::setObjectReturn(); - $result = DateTime::EOMONTH('2012-1-26', -1); + $result = Eomonth::funcEomonth('2012-1-26', -1); // Must return an object... self::assertIsObject($result); // ... of the correct type self::assertTrue(is_a($result, 'DateTimeInterface')); // ... with the correct value - self::assertEquals($result->format('d-M-Y'), '31-Dec-2011'); + self::assertSame($result->format('d-M-Y'), '31-Dec-2011'); } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/HourTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/HourTest.php index 2d0cd5d1b4..ff9df7ed23 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/HourTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/HourTest.php @@ -2,30 +2,20 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Shared\Date; -use PHPUnit\Framework\TestCase; - -class HourTest extends TestCase +class HourTest extends AllSetupTeardown { - protected function setUp(): void - { - Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); - Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900); - } - /** * @dataProvider providerHOUR * * @param mixed $expectedResult - * @param $dateTimeValue */ - public function testHOUR($expectedResult, $dateTimeValue): void + public function testHOUR($expectedResult, string $dateTimeValue): void { - $result = DateTime::HOUROFDAY($dateTimeValue); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); + self::mightHaveException($expectedResult); + $sheet = $this->sheet; + $sheet->getCell('A1')->setValue("=HOUR($dateTimeValue)"); + $sheet->getCell('B1')->setValue('1954-11-23 2:23:46'); + self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue()); } public function providerHOUR() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/IsoWeekNumTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/IsoWeekNumTest.php index 1ef0080add..c6eaab0e72 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/IsoWeekNumTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/IsoWeekNumTest.php @@ -2,34 +2,46 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Shared\Date; -use PHPUnit\Framework\TestCase; - -class IsoWeekNumTest extends TestCase +class IsoWeekNumTest extends AllSetupTeardown { - protected function setUp(): void - { - Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); - Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900); - } - /** * @dataProvider providerISOWEEKNUM * * @param mixed $expectedResult - * @param mixed $dateValue + * @param string $dateValue */ public function testISOWEEKNUM($expectedResult, $dateValue): void { - $result = DateTime::ISOWEEKNUM($dateValue); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); + self::mightHaveException($expectedResult); + $sheet = $this->sheet; + $sheet->getCell('A1')->setValue("=ISOWEEKNUM($dateValue)"); + $sheet->getCell('B1')->setValue('1954-11-23'); + self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue()); } public function providerISOWEEKNUM() { return require 'tests/data/Calculation/DateTime/ISOWEEKNUM.php'; } + + /** + * @dataProvider providerISOWEEKNUM1904 + * + * @param mixed $expectedResult + * @param string $dateValue + */ + public function testISOWEEKNUM1904($expectedResult, $dateValue): void + { + self::mightHaveException($expectedResult); + self::setMac1904(); + $sheet = $this->sheet; + $sheet->getCell('A1')->setValue("=ISOWEEKNUM($dateValue)"); + $sheet->getCell('B1')->setValue('1954-11-23'); + self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue()); + } + + public function providerISOWEEKNUM1904() + { + return require 'tests/data/Calculation/DateTime/ISOWEEKNUM1904.php'; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MinuteTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MinuteTest.php index 8472c6de07..d127e96503 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MinuteTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MinuteTest.php @@ -2,30 +2,20 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Shared\Date; -use PHPUnit\Framework\TestCase; - -class MinuteTest extends TestCase +class MinuteTest extends AllSetupTeardown { - protected function setUp(): void - { - Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); - Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900); - } - /** * @dataProvider providerMINUTE * * @param mixed $expectedResult - * @param $dateTimeValue */ - public function testMINUTE($expectedResult, $dateTimeValue): void + public function testMINUTE($expectedResult, string $dateTimeValue): void { - $result = DateTime::MINUTE($dateTimeValue); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); + self::mightHaveException($expectedResult); + $sheet = $this->sheet; + $sheet->getCell('A1')->setValue("=MINUTE($dateTimeValue)"); + $sheet->getCell('B1')->setValue('1954-11-23 2:23:46'); + self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue()); } public function providerMINUTE() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MonthTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MonthTest.php index 6251370261..8fb7a86f97 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MonthTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MonthTest.php @@ -2,30 +2,20 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Shared\Date; -use PHPUnit\Framework\TestCase; - -class MonthTest extends TestCase +class MonthTest extends AllSetupTeardown { - protected function setUp(): void - { - Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); - Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900); - } - /** * @dataProvider providerMONTH * * @param mixed $expectedResult - * @param $dateTimeValue */ - public function testMONTH($expectedResult, $dateTimeValue): void + public function testMONTH($expectedResult, string $dateTimeValue): void { - $result = DateTime::MONTHOFYEAR($dateTimeValue); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); + self::mightHaveException($expectedResult); + $sheet = $this->sheet; + $sheet->getCell('A1')->setValue("=MONTH($dateTimeValue)"); + $sheet->getCell('B1')->setValue('1954-11-23'); + self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue()); } public function providerMONTH() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MovedFunctionsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MovedFunctionsTest.php new file mode 100644 index 0000000000..d14f7d7d24 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MovedFunctionsTest.php @@ -0,0 +1,63 @@ +format('s'); + $nowResult = DateTime::DATETIMENOW(); + $todayResult = DateTime::DATENOW(); + $dtEnd = new DateTimeImmutable(); + $endSecond = $dtEnd->format('s'); + } while ($startSecond !== $endSecond); + self::assertSame(DateTime::DAYOFMONTH($nowResult), DateTime::DAYOFMONTH($todayResult)); + } +} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NetworkDaysTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NetworkDaysTest.php index e366c44ec8..d14487c545 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NetworkDaysTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NetworkDaysTest.php @@ -2,20 +2,10 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Shared\Date; -use PHPUnit\Framework\TestCase; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Networkdays; -class NetworkDaysTest extends TestCase +class NetworkDaysTest extends AllSetupTeardown { - protected function setUp(): void - { - Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); - Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900); - } - /** * @dataProvider providerNETWORKDAYS * @@ -23,7 +13,7 @@ protected function setUp(): void */ public function testNETWORKDAYS($expectedResult, ...$args): void { - $result = DateTime::NETWORKDAYS(...$args); + $result = Networkdays::funcNetworkdays(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-8); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NowTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NowTest.php index f139f70393..e0f68c2488 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NowTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NowTest.php @@ -3,15 +3,12 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; use DateTimeImmutable; -use PhpOffice\PhpSpreadsheet\Spreadsheet; -use PHPUnit\Framework\TestCase; -class NowTest extends TestCase +class NowTest extends AllSetupTeardown { public function testNow(): void { - $spreadsheet = new Spreadsheet(); - $sheet = $spreadsheet->getActiveSheet(); + $sheet = $this->sheet; // Loop to avoid rare edge case where first calculation // and second do not take place in same second. do { @@ -21,7 +18,6 @@ public function testNow(): void $dtEnd = new DateTimeImmutable(); $endSecond = $dtEnd->format('s'); } while ($startSecond !== $endSecond); - //echo("\n"); var_dump($sheet->getCell('A1')->getCalculatedValue()); echo ("\n"); $sheet->setCellValue('B1', '=YEAR(A1)'); $sheet->setCellValue('C1', '=MONTH(A1)'); $sheet->setCellValue('D1', '=DAY(A1)'); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/SecondTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/SecondTest.php index bc2b075253..5f772cb2ea 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/SecondTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/SecondTest.php @@ -2,30 +2,20 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Shared\Date; -use PHPUnit\Framework\TestCase; - -class SecondTest extends TestCase +class SecondTest extends AllSetupTeardown { - protected function setUp(): void - { - Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); - Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900); - } - /** * @dataProvider providerSECOND * * @param mixed $expectedResult - * @param $dateTimeValue */ - public function testSECOND($expectedResult, $dateTimeValue): void + public function testSECOND($expectedResult, string $dateTimeValue): void { - $result = DateTime::SECOND($dateTimeValue); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); + self::mightHaveException($expectedResult); + $sheet = $this->sheet; + $sheet->getCell('A1')->setValue("=SECOND($dateTimeValue)"); + $sheet->getCell('B1')->setValue('1954-11-23 2:23:46'); + self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue()); } public function providerSECOND() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeTest.php index 3ef58374a6..b28e8eea68 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeTest.php @@ -2,39 +2,24 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Shared\Date; -use PHPUnit\Framework\TestCase; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Time; -class TimeTest extends TestCase +class TimeTest extends AllSetupTeardown { - private $returnDateType; - - private $calendar; - - protected function setUp(): void - { - $this->returnDateType = Functions::getReturnDateType(); - $this->calendar = Date::getExcelCalendar(); - } - - protected function tearDown(): void - { - Functions::setReturnDateType($this->returnDateType); - Date::setExcelCalendar($this->calendar); - } - /** * @dataProvider providerTIME * * @param mixed $expectedResult */ - public function testTIME($expectedResult, ...$args): void + public function testTIME($expectedResult, string $formula): void { - Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - $result = DateTime::TIME(...$args); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); + self::mightHaveException($expectedResult); + $sheet = $this->sheet; + $sheet->getCell('B1')->setValue('15'); + $sheet->getCell('B2')->setValue('32'); + $sheet->getCell('B3')->setValue('50'); + $sheet->getCell('A1')->setValue("=TIME($formula)"); + self::assertEqualsWithDelta($expectedResult, $sheet->getCell('A1')->getCalculatedValue(), 1E-8); } public function providerTIME() @@ -44,17 +29,17 @@ public function providerTIME() public function testTIMEtoUnixTimestamp(): void { - Functions::setReturnDateType(Functions::RETURNDATE_PHP_NUMERIC); + self::setUnixReturn(); - $result = DateTime::TIME(7, 30, 20); + $result = Time::funcTime(7, 30, 20); self::assertEqualsWithDelta(27020, $result, 1E-8); } public function testTIMEtoDateTimeObject(): void { - Functions::setReturnDateType(Functions::RETURNDATE_PHP_OBJECT); + self::setObjectReturn(); - $result = DateTime::TIME(7, 30, 20); + $result = Time::funcTime(7, 30, 20); // Must return an object... self::assertIsObject($result); // ... of the correct type @@ -65,17 +50,14 @@ public function testTIMEtoDateTimeObject(): void public function testTIME1904(): void { - Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - Date::setExcelCalendar(Date::CALENDAR_MAC_1904); - $result = DateTime::TIME(0, 0, 0); + self::setMac1904(); + $result = Time::funcTime(0, 0, 0); self::assertEquals(0, $result); } public function testTIME1900(): void { - Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900); - $result = DateTime::TIME(0, 0, 0); + $result = Time::funcTime(0, 0, 0); self::assertEquals(0, $result); } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeValueTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeValueTest.php index 04b8c05840..04cb20d38c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeValueTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeValueTest.php @@ -2,20 +2,10 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Shared\Date; -use PHPUnit\Framework\TestCase; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Timevalue; -class TimeValueTest extends TestCase +class TimeValueTest extends AllSetupTeardown { - protected function setUp(): void - { - Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); - Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900); - } - /** * @dataProvider providerTIMEVALUE * @@ -24,7 +14,11 @@ protected function setUp(): void */ public function testTIMEVALUE($expectedResult, $timeValue): void { - $result = DateTime::TIMEVALUE($timeValue); + self::mightHaveException($expectedResult); + $sheet = $this->sheet; + $sheet->getCell('B1')->setValue('03:45:52'); + $sheet->getCell('A1')->setValue("=TIMEVALUE($timeValue)"); + $result = $sheet->getCell('A1')->getCalculatedValue(); self::assertEqualsWithDelta($expectedResult, $result, 1E-8); } @@ -35,18 +29,18 @@ public function providerTIMEVALUE() public function testTIMEVALUEtoUnixTimestamp(): void { - Functions::setReturnDateType(Functions::RETURNDATE_UNIX_TIMESTAMP); + self::setUnixReturn(); - $result = DateTime::TIMEVALUE('7:30:20'); + $result = Timevalue::funcTimevalue('7:30:20'); self::assertEquals(23420, $result); self::assertEqualsWithDelta(23420, $result, 1E-8); } public function testTIMEVALUEtoDateTimeObject(): void { - Functions::setReturnDateType(Functions::RETURNDATE_PHP_DATETIME_OBJECT); + self::setObjectReturn(); - $result = DateTime::TIMEVALUE('7:30:20'); + $result = Timevalue::funcTimevalue('7:30:20'); // Must return an object... self::assertIsObject($result); // ... of the correct type diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TodayTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TodayTest.php new file mode 100644 index 0000000000..6ce82bfd18 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TodayTest.php @@ -0,0 +1,34 @@ +sheet; + // Loop to avoid rare edge case where first calculation + // and second do not take place in same second. + do { + $dtStart = new DateTimeImmutable(); + $startSecond = $dtStart->format('s'); + $sheet->setCellValue('A1', '=TODAY()'); + $dtEnd = new DateTimeImmutable(); + $endSecond = $dtEnd->format('s'); + } while ($startSecond !== $endSecond); + $sheet->setCellValue('B1', '=YEAR(A1)'); + $sheet->setCellValue('C1', '=MONTH(A1)'); + $sheet->setCellValue('D1', '=DAY(A1)'); + $sheet->setCellValue('E1', '=HOUR(A1)'); + $sheet->setCellValue('F1', '=MINUTE(A1)'); + $sheet->setCellValue('G1', '=SECOND(A1)'); + self::assertSame((int) $dtStart->format('Y'), $sheet->getCell('B1')->getCalculatedValue()); + self::assertSame((int) $dtStart->format('m'), $sheet->getCell('C1')->getCalculatedValue()); + self::assertSame((int) $dtStart->format('d'), $sheet->getCell('D1')->getCalculatedValue()); + self::assertSame(0, $sheet->getCell('E1')->getCalculatedValue()); + self::assertSame(0, $sheet->getCell('F1')->getCalculatedValue()); + self::assertSame(0, $sheet->getCell('G1')->getCalculatedValue()); + } +} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekDayTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekDayTest.php index 99aa6f7cb9..79c84e28fd 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekDayTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekDayTest.php @@ -2,33 +2,22 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTime; -use PhpOffice\PhpSpreadsheet\Shared\Date; -use PHPUnit\Framework\TestCase; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Weekday; -class WeekDayTest extends TestCase +class WeekDayTest extends AllSetupTeardown { - private $excelCalendar; - - protected function setUp(): void - { - $this->excelCalendar = Date::getExcelCalendar(); - } - - protected function tearDown(): void - { - Date::setExcelCalendar($this->excelCalendar); - } - /** * @dataProvider providerWEEKDAY * * @param mixed $expectedResult */ - public function testWEEKDAY($expectedResult, ...$args): void + public function testWEEKDAY($expectedResult, string $formula): void { - $result = DateTime::WEEKDAY(...$args); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); + self::mightHaveException($expectedResult); + $sheet = $this->sheet; + $sheet->getCell('B1')->setValue('1954-11-23'); + $sheet->getCell('A1')->setValue("=WEEKDAY($formula)"); + self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue()); } public function providerWEEKDAY() @@ -38,9 +27,9 @@ public function providerWEEKDAY() public function testWEEKDAYwith1904Calendar(): void { - Date::setExcelCalendar(Date::CALENDAR_MAC_1904); - self::assertEquals(7, DateTime::WEEKDAY('1904-01-02')); - self::assertEquals(6, DateTime::WEEKDAY('1904-01-01')); - self::assertEquals(6, DateTime::WEEKDAY(null)); + self::setMac1904(); + self::assertEquals(7, Weekday::funcWeekday('1904-01-02')); + self::assertEquals(6, Weekday::funcWeekday('1904-01-01')); + self::assertEquals(6, Weekday::funcWeekday(null)); } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekNumTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekNumTest.php index 17119f2873..0efed4e269 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekNumTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekNumTest.php @@ -2,33 +2,20 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTime; -use PhpOffice\PhpSpreadsheet\Shared\Date; -use PHPUnit\Framework\TestCase; - -class WeekNumTest extends TestCase +class WeekNumTest extends AllSetupTeardown { - private $excelCalendar; - - protected function setUp(): void - { - $this->excelCalendar = Date::getExcelCalendar(); - } - - protected function tearDown(): void - { - Date::setExcelCalendar($this->excelCalendar); - } - /** * @dataProvider providerWEEKNUM * * @param mixed $expectedResult */ - public function testWEEKNUM($expectedResult, ...$args): void + public function testWEEKNUM($expectedResult, string $formula): void { - $result = DateTime::WEEKNUM(...$args); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); + self::mightHaveException($expectedResult); + $sheet = $this->sheet; + $sheet->getCell('B1')->setValue('1954-11-23'); + $sheet->getCell('A1')->setValue("=WEEKNUM($formula)"); + self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue()); } public function providerWEEKNUM() @@ -36,13 +23,23 @@ public function providerWEEKNUM() return require 'tests/data/Calculation/DateTime/WEEKNUM.php'; } - public function testWEEKNUMwith1904Calendar(): void + /** + * @dataProvider providerWEEKNUM1904 + * + * @param mixed $expectedResult + */ + public function testWEEKNUM1904($expectedResult, string $formula): void + { + self::mightHaveException($expectedResult); + self::setMac1904(); + $sheet = $this->sheet; + $sheet->getCell('B1')->setValue('1954-11-23'); + $sheet->getCell('A1')->setValue("=WEEKNUM($formula)"); + self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue()); + } + + public function providerWEEKNUM1904() { - Date::setExcelCalendar(Date::CALENDAR_MAC_1904); - self::assertEquals(27, DateTime::WEEKNUM('2004-07-02')); - self::assertEquals(1, DateTime::WEEKNUM('1904-01-02')); - self::assertEquals(1, DateTime::WEEKNUM(null)); - // The following is a bug in Excel. - self::assertEquals(0, DateTime::WEEKNUM('1904-01-01')); + return require 'tests/data/Calculation/DateTime/WEEKNUM1904.php'; } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WorkDayTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WorkDayTest.php index 4784e4630d..72c5aa52b4 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WorkDayTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WorkDayTest.php @@ -3,19 +3,9 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; use PhpOffice\PhpSpreadsheet\Calculation\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Shared\Date; -use PHPUnit\Framework\TestCase; -class WorkDayTest extends TestCase +class WorkDayTest extends AllSetupTeardown { - protected function setUp(): void - { - Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); - Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900); - } - /** * @dataProvider providerWORKDAY * diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearFracTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearFracTest.php index 05f1131099..177d7316b7 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearFracTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearFracTest.php @@ -2,20 +2,10 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Shared\Date; -use PHPUnit\Framework\TestCase; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\YearFrac; -class YearFracTest extends TestCase +class YearFracTest extends AllSetupTeardown { - protected function setUp(): void - { - Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); - Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900); - } - /** * @dataProvider providerYEARFRAC * @@ -23,7 +13,7 @@ protected function setUp(): void */ public function testYEARFRAC($expectedResult, ...$args): void { - $result = DateTime::YEARFRAC(...$args); + $result = YearFrac::funcYearfrac(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-8); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearTest.php index bbdaf92a4f..503da7b655 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearTest.php @@ -2,30 +2,20 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Shared\Date; -use PHPUnit\Framework\TestCase; - -class YearTest extends TestCase +class YearTest extends AllSetupTeardown { - protected function setUp(): void - { - Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); - Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900); - } - /** * @dataProvider providerYEAR * * @param mixed $expectedResult - * @param $dateTimeValue */ - public function testYEAR($expectedResult, $dateTimeValue): void + public function testYEAR($expectedResult, string $dateTimeValue): void { - $result = DateTime::YEAR($dateTimeValue); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); + self::mightHaveException($expectedResult); + $sheet = $this->sheet; + $sheet->getCell('A1')->setValue("=YEAR($dateTimeValue)"); + $sheet->getCell('B1')->setValue('1954-11-23'); + self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue()); } public function providerYEAR() diff --git a/tests/data/Calculation/DateTime/DATE.php b/tests/data/Calculation/DateTime/DATE.php index 9acc6716b9..72816b763e 100644 --- a/tests/data/Calculation/DateTime/DATE.php +++ b/tests/data/Calculation/DateTime/DATE.php @@ -1,319 +1,84 @@ [ - 6890, // '11th November 1918' - 18, 11, 11, - ], - 'Excel 1900 Calendar Base Date' => [ - 1, - 1900, 1, 1, - ], - 'Day before Excel mythical 1900 leap day' => [ - 59, - 1900, 2, 28, - ], - 'Excel mythical 1900 leap day' => [ - 60, - 1900, 2, 29, - ], - 'Day after Excel mythical 1900 leap day' => [ - 61, - 1900, 3, 1, - ], - 'Day after Excel actual 1904 leap day' => [ - 713, - 1901, 12, 13, - ], - 'signed 32-bit Unix Timestamp Earliest Date' => [ - 714, - 1901, 12, 14, - ], - 'Day before Excel 1904 Calendar Base Date' => [ - 1461, - 1903, 12, 31, - ], - 'Excel 1904 Calendar Base Date' => [ - 1462, - 1904, 1, 1, - ], - 'Day after Excel 1904 Calendar Base Date' => [ - 1463, - 1904, 1, 2, - ], - [ - 22269, - 1960, 12, 19, - ], - 'Unix Timestamp Base Date' => [ - 25569, - 1970, 1, 1, - ], - [ - 30292, - 1982, 12, 7, - ], - [ - 39611, - 2008, 6, 12, - ], - '32-bit signed Unix Timestamp Latest Date' => [ - 50424, - 2038, 1, 19, - ], - 'Day after 32-bit signed Unix Timestamp Latest Date' => [ - 50425, - 2038, 1, 20, - ], - [ - 39448, - 2008, 1, 1, - ], - [ - 39447, - 2008, 1, null, - ], - [ - 39446, - 2008, 1, -1, - ], - [ - 39417, - 2008, 1, -30, - ], - [ - 39416, - 2008, 1, -31, - ], - [ - 39082, - 2008, 1, -365, - ], - [ - 39508, - 2008, 3, 1, - ], - [ - 39507, - 2008, 3, null, - ], - [ - 39506, - 2008, 3, -1, - ], - [ - 39142, - 2008, 3, -365, - ], - [ - 39417, - 2008, null, 1, - ], - [ - 39387, - 2008, -1, 1, - ], - [ - 39083, - 2008, -11, 1, - ], - [ - 39052, - 2008, -12, 1, - ], - [ - 39022, - 2008, -13, 1, - ], - [ - 39051, - 2008, -13, 30, - ], - [ - 39021, - 2008, -13, null, - ], - [ - 38991, - 2008, -13, -30, - ], - [ - 38990, - 2008, -13, -31, - ], - [ - 39814, - 2008, 13, 1, - ], - [ - 39507, - 2007, 15, null, - ], - [ - 40210, - 2008, 26, 1, - ], - [ - 40199, - 2008, 26, -10, - ], - [ - 38686, - 2008, -26, 61, - ], - [ - 39641, - 2010, -15, -50, - ], - [ - 39741, - 2010, -15, 50, - ], - [ - 40552, - 2010, 15, -50, - ], - [ - 40652, - 2010, 15, 50, - ], - [ - 40179, - 2010, 1.5, 1, - ], - [ - 40178, - 2010, 1.5, 0, - ], - [ - 40148, - 2010, 0, 1.5, - ], - [ - 40179, - 2010, 1, 1.5, - ], - [ - 41075, - 2012, 6, 15, - ], - [ - 41060, - 2012, 6, null, - ], - [ - 40892, - 2012, null, 15, - ], - [ - 167, - null, 6, 15, - ], - [ - 3819, - 10, 6, 15, - ], - [ - 3622, - 10, null, null, - ], - [ - 274, - null, 10, null, - ], - [ - '#NUM!', - null, null, 10, - ], - [ - '#NUM!', - -20, null, null, - ], - [ - '#NUM!', - -20, 6, 15, - ], - 'Excel Maximum Date' => [ - 2958465, - 9999, 12, 31, - ], - 'Exceeded Excel Maximum Date' => [ - '#NUM!', - 10000, 1, 1, - ], - [ - 39670, - 2008, 8, 10, - ], - [ - 39813, - 2008, 12, 31, - ], - [ - 39692, - 2008, 8, 32, - ], - [ - 39844, - 2008, 13, 31, - ], - [ - 39813, - 2009, 1, 0, - ], - [ - 39812, - 2009, 1, -1, - ], - [ - 39782, - 2009, 0, 0, - ], - [ - 39781, - 2009, 0, -1, - ], - [ - 39752, - 2009, -1, 0, - ], - [ - 39751, - 2009, -1, -1, - ], - [ - 40146, - 2010, 0, -1, - ], - [ - 40329, - 2010, 5, 31, - ], + [6890, '18, 11, 11'], // year without centure + [1, '1900, 1, 1'], // Excel 1900 Calendar BaseDate + [59, '1900, 2, 28'], // Day before Excel mythical 1900 leap day + [60, '1900, 2, 29'], // Excel mythical 1900 leap day + [61, '1900, 3, 1'], // Day after Excel mythical 1900 leap day + [713, '1901, 12, 13'], // Day after actual 1904 leap day + [714, '1901, 12, 14'], // signed 32-bit Unix Timestamp Earliest Date + [1461, '1903, 12, 31'], // Day before Excel 1904 Calendar Base Date + [1462, '1904, 1, 1'], // Excel 1904 Calendar Base Date + [1463, '1904, 1, 2'], // Day after Excel 1904 Calendar Base Date + [22269, '1960, 12, 19'], + [25569, '1970, 1, 1'], // Unix Timestamp Base Date + [30292, '1982, 12, 7'], + [39611, '2008, 6, 12'], + [50424, '2038, 1, 19'], // 32-bit signed Unix Timestamp Latest Date + [50425, '2038, 1, 20'], // Day after 32-bit signed Unix Timestamp Latest Date + [39448, '2008, 1, 1'], + [39447, '2008, 1, Q15'], + [39446, '2008, 1, -1'], + [39417, '2008, 1, -30'], + [39416, '2008, 1, -31'], + [39082, '2008, 1, -365'], + [39508, '2008, 3, 1'], + [39507, '2008, 3, Q15'], + [39506, '2008, 3, -1'], + [39142, '2008, 3, -365'], + [39417, '2008, Q15, 1'], + [39387, '2008, -1, 1'], + [39083, '2008, -11, 1'], + [39052, '2008, -12, 1'], + [39022, '2008, -13, 1'], + [39051, '2008, -13, 30'], + [39021, '2008, -13, Q15'], + [38991, '2008, -13, -30'], + [38990, '2008, -13, -31'], + [39814, '2008, 13, 1'], + [39507, '2007, 15, Q15'], + [40210, '2008, 26, 1'], + [40199, '2008, 26, -10'], + [38686, '2008, -26, 61'], + [39641, '2010, -15, -50'], + [39741, '2010, -15, 50'], + [40552, '2010, 15, -50'], + [40652, '2010, 15, 50'], + [40179, '2010, 1.5, 1'], + [40178, '2010, 1.5, 0'], + [40148, '2010, 0, 1.5'], + [40179, '2010, 1, 1.5'], + [41075, '2012, 6, 15'], + [41060, '2012, 6, Q15'], + [40892, '2012, Q15, 15'], + [167, 'Q15, 6, 15'], + [3819, '10, 6, 15'], + [3622, '10, Q15, Q16'], + [274, 'Q14, 10, Q15'], + ['#NUM!', 'Q14, Q15, 10'], + ['#NUM!', '-20, Q14, Q15'], + ['#NUM!', '-20, 6, 15'], + [2958465, '9999, 12, 31'], // Excel maximum date + ['#NUM!', '10000, 1, 1'], // Exceeded Excel maximum date + [39670, '2008, 8, 10'], + [39813, '2008, 12, 31'], + [39692, '2008, 8, 32'], + [39844, '2008, 13, 31'], + [39813, '2009, 1, 0'], + [39812, '2009, 1, -1'], + [39782, '2009, 0, 0'], + [39781, '2009, 0, -1'], + [39752, '2009, -1, 0'], + [39751, '2009, -1, -1'], + [40146, '2010, 0, -1'], + [40329, '2010, 5, 31'], + [40199, '2010, 1, "21st"'], // Excel can't parse ordinal, PhpSpreadsheet can + [40258, '2010, "March", "21st"'], // ordinal and month name // MS Excel will fail with a #VALUE return, but PhpSpreadsheet can parse this date - [ - 40199, - 2010, 1, '21st', - ], - // MS Excel will fail with a #VALUE return, but PhpSpreadsheet can parse this date - [ - 40258, - 2010, 'March', '21st', - ], - // MS Excel will fail with a #VALUE return, but PhpSpreadsheet can parse this date - [ - 40258, - 2010, 'March', 21, - ], - [ - '#VALUE!', - 'ABC', 1, 21, - ], - [ - '#VALUE!', - 2010, 'DEF', 21, - ], - [ - '#VALUE!', - 2010, 3, 'GHI', - ], + [40258, '2010, "March", 21'], // Excel can't parse month name, PhpSpreadsheet can + ['#VALUE!', '"ABC", 1, 21'], + ['#VALUE!', '2010, "DEF", 21'], + ['#VALUE!', '2010, 3, "GHI"'], + ['exception', '2010, 3'], ]; diff --git a/tests/data/Calculation/DateTime/DATEDIF.php b/tests/data/Calculation/DateTime/DATEDIF.php index a6d2d76122..5ba0bd3cfe 100644 --- a/tests/data/Calculation/DateTime/DATEDIF.php +++ b/tests/data/Calculation/DateTime/DATEDIF.php @@ -1,424 +1,112 @@ Date: Thu, 18 Mar 2021 17:59:21 -0700 Subject: [PATCH 02/12] Upper/Lowercase Problem That's what I get for testing on Windows. --- src/PhpSpreadsheet/Calculation/Calculation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 5f38d8b551..306fb20284 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -2629,7 +2629,7 @@ class Calculation ], 'YEARFRAC' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\YearFrac::class, 'funcYearfrac'], + 'functionCall' => [DateTimeExcel\Yearfrac::class, 'funcYearfrac'], 'argumentCount' => '2,3', ], 'YIELD' => [ From 62e9dc3735d3f5e645e503371650bbe0b1a86f5b Mon Sep 17 00:00:00 2001 From: Owen Leibman Date: Thu, 18 Mar 2021 18:05:05 -0700 Subject: [PATCH 03/12] More Lowercase Hopefully just this one now. --- src/PhpSpreadsheet/Calculation/Calculation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 306fb20284..dfb4925188 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -764,7 +764,7 @@ class Calculation ], 'DATEVALUE' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\DateValue::class, 'funcDateValue'], + 'functionCall' => [DateTimeExcel\Datevalue::class, 'funcDatevalue'], 'argumentCount' => '1', ], 'DAVERAGE' => [ From e430800f798a62660c2373e17922292f31e30b6f Mon Sep 17 00:00:00 2001 From: Owen Leibman Date: Thu, 18 Mar 2021 20:12:14 -0700 Subject: [PATCH 04/12] And Now the Scrutinizer Work Begins 66 problems. Yipe. --- .../Calculation/DateTimeExcel/Datedif.php | 26 +++++++++---------- .../Calculation/DateTimeExcel/Datevalue.php | 4 +-- .../Calculation/DateTimeExcel/Day.php | 1 - .../Calculation/DateTimeExcel/Days.php | 12 ++++++--- .../Calculation/DateTimeExcel/Days360.php | 2 +- .../Calculation/DateTimeExcel/Helpers.php | 7 ++++- .../Calculation/DateTimeExcel/IsoWeeknum.php | 2 +- .../Calculation/DateTimeExcel/Networkdays.php | 6 ++--- .../Calculation/DateTimeExcel/Weeknum.php | 2 +- .../Calculation/DateTimeExcel/Yearfrac.php | 4 +-- .../Functions/DateTime/AllSetupTeardown.php | 8 +++--- .../Functions/DateTime/DateDifTest.php | 2 +- .../Functions/DateTime/DateTest.php | 2 +- .../Functions/DateTime/DayTest.php | 4 +-- .../Functions/DateTime/Days360Test.php | 2 +- .../Functions/DateTime/DaysTest.php | 2 +- .../Functions/DateTime/EDateTest.php | 2 +- .../Functions/DateTime/EoMonthTest.php | 2 +- .../Functions/DateTime/HourTest.php | 2 +- .../Functions/DateTime/IsoWeekNumTest.php | 4 +-- .../Functions/DateTime/MinuteTest.php | 2 +- .../Functions/DateTime/MonthTest.php | 2 +- .../Functions/DateTime/SecondTest.php | 2 +- .../Functions/DateTime/TimeTest.php | 2 +- .../Functions/DateTime/TimeValueTest.php | 2 +- .../Functions/DateTime/WeekDayTest.php | 2 +- .../Functions/DateTime/WeekNumTest.php | 4 +-- .../Functions/DateTime/YearTest.php | 2 +- 28 files changed, 61 insertions(+), 53 deletions(-) diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php index fa8c616df3..e58c1e9eef 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php @@ -34,14 +34,14 @@ public static function funcDatedif($startDate, $endDate, $unit = 'D') // Execute function $PHPStartDateObject = Date::excelToDateTimeObject($startDate); - $startDays = $PHPStartDateObject->format('j'); - $startMonths = $PHPStartDateObject->format('n'); - $startYears = $PHPStartDateObject->format('Y'); + $startDays = (int) $PHPStartDateObject->format('j'); + $startMonths = (int) $PHPStartDateObject->format('n'); + $startYears = (int) $PHPStartDateObject->format('Y'); $PHPEndDateObject = Date::excelToDateTimeObject($endDate); - $endDays = $PHPEndDateObject->format('j'); - $endMonths = $PHPEndDateObject->format('n'); - $endYears = $PHPEndDateObject->format('Y'); + $endDays = (int) $PHPEndDateObject->format('j'); + $endMonths = (int) $PHPEndDateObject->format('n'); + $endYears = (int) $PHPEndDateObject->format('Y'); $PHPDiffDateObject = $PHPEndDateObject->diff($PHPStartDateObject); @@ -72,7 +72,7 @@ private static function initialDiff(float $startDate, float $endDate): float * * @param bool|int $retVal * - * @return null|int + * @return null|bool|int */ private static function replaceRetValue($retVal, string $unit, string $compare) { @@ -93,12 +93,12 @@ private static function datedifM(DateInterval $PHPDiffDateObject): int return (int) 12 * $PHPDiffDateObject->format('%y') + $PHPDiffDateObject->format('%m'); } - private static function datedifMD(float $startDays, float $endDays, DateTime $PHPEndDateObject, DateInterval $PHPDiffDateObject): int + private static function datedifMD(int $startDays, int $endDays, DateTime $PHPEndDateObject, DateInterval $PHPDiffDateObject): int { if ($endDays < $startDays) { $retVal = $endDays; $PHPEndDateObject->modify('-' . $endDays . ' days'); - $adjustDays = $PHPEndDateObject->format('j'); + $adjustDays = (int) $PHPEndDateObject->format('j'); $retVal += ($adjustDays - $startDays); } else { $retVal = (int) $PHPDiffDateObject->format('%d'); @@ -109,10 +109,10 @@ private static function datedifMD(float $startDays, float $endDays, DateTime $PH private static function datedifY(DateInterval $PHPDiffDateObject): int { - return $PHPDiffDateObject->format('%y'); + return (int) $PHPDiffDateObject->format('%y'); } - private static function datedifYD(float $difference, float $startYears, float $endYears, DateTime $PHPStartDateObject, DateTime $PHPEndDateObject): int + private static function datedifYD(float $difference, int $startYears, int $endYears, DateTime $PHPStartDateObject, DateTime $PHPEndDateObject): int { $retVal = (int) $difference; if ($endYears > $startYears) { @@ -137,12 +137,12 @@ private static function datedifYD(float $difference, float $startYears, float $e } } - return $retVal; + return (int) $retVal; } private static function datedifYM(DateInterval $PHPDiffDateObject): int { - return $PHPDiffDateObject->format('%m'); + return (int) $PHPDiffDateObject->format('%m'); } private static function datedifInvalid(): string diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datevalue.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datevalue.php index bb7febec96..19357b35df 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datevalue.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datevalue.php @@ -93,7 +93,7 @@ private static function t1ToString(array $t1, DateTimeImmutable $dti, bool $year /** * Parse date. * - * @return array|false + * @return array|bool */ private static function setUpArray(string $dateValue, DateTimeImmutable $dti) { @@ -143,7 +143,7 @@ private static function finalResults($PHPDateArray, DateTimeImmutable $dti, int if (!checkdate($month, $day, $year)) { return ($year === 1900 && $month === 2 && $day === 29) ? Helpers::returnIn3FormatsFloat(60.0) : Functions::VALUE(); } - $retValue = is_array($PHPDateArray) ? Helpers::returnIn3FormatsArray($PHPDateArray, true) : Functions::VALUE(); + $retValue = Helpers::returnIn3FormatsArray($PHPDateArray, true); } return $retValue; diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Day.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Day.php index 97e8a8b8c3..6ab271840d 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Day.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Day.php @@ -44,7 +44,6 @@ public static function funcDay($dateValue) private static function weirdCondition($dateValue): int { // Excel does not treat 0 consistently for DAY vs. (MONTH or YEAR) - $retval = -1; if (Date::getExcelCalendar() === DATE::CALENDAR_WINDOWS_1900 && Functions::getCompatibilityMode() == Functions::COMPATIBILITY_EXCEL) { if (is_bool($dateValue)) { return (int) $dateValue; diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days.php index e4403907ee..f0195cf916 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days.php @@ -4,6 +4,7 @@ use DateTimeInterface; use Exception; +use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Shared\Date; class Days @@ -37,12 +38,15 @@ public static function funcDays($endDate, $startDate) $PHPEndDateObject = Date::excelToDateTimeObject($endDate); $diff = $PHPStartDateObject->diff($PHPEndDateObject); - $days = $diff->days; + if ($diff !== false && $diff->days !== false) { + $days = $diff->days; + if ($diff->invert) { + $days = -$days; + } - if ($diff->invert) { - $days = -$days; + return $days; } - return $days; + return Functions::VALUE(); } } diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days360.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days360.php index 46063825a9..068ea2bca6 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days360.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days360.php @@ -60,7 +60,7 @@ public static function funcDays360($startDate = 0, $endDate = 0, $method = false $endMonth = $PHPEndDateObject->format('n'); $endYear = $PHPEndDateObject->format('Y'); - return self::dateDiff360($startDay, $startMonth, $startYear, $endDay, $endMonth, $endYear, !$method); + return self::dateDiff360((int) $startDay, (int) $startMonth, (int) $startYear, (int) $endDay, (int) $endMonth, (int) $endYear, !$method); } /** diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php index 44c7a73c99..38aff0a0ca 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php @@ -32,7 +32,12 @@ public static function isLeapYear($year) public static function getDateValue($dateValue, bool $allowBool = true) { if ($dateValue instanceof DateTimeInterface) { - return Date::PHPToExcel($dateValue); + $retval = Date::PHPToExcel($dateValue); + if (is_bool($retval)) { + throw new Exception(Functions::VALUE()); + } + + return $retval; } self::nullFalseTrueToNumber($dateValue, $allowBool); diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/IsoWeeknum.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/IsoWeeknum.php index 7e8a8f736f..e81cc8623d 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/IsoWeeknum.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/IsoWeeknum.php @@ -18,7 +18,7 @@ class IsoWeeknum * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), * PHP DateTime object, or a standard date string * - * @return int Week Number + * @return int|string Week Number */ public static function funcIsoWeeknum($dateValue) { diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Networkdays.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Networkdays.php index 5d36a47ea3..9a424238e8 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Networkdays.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Networkdays.php @@ -48,7 +48,7 @@ public static function funcNetworkdays($startDate, $endDate, ...$dateArgs) // Execute function $startDow = self::calcStartDow($startDate); $endDow = self::calcEndDow($endDate); - $wholeWeekDays = floor(($endDate - $startDate) / 7) * 5; + $wholeWeekDays = (int) floor(($endDate - $startDate) / 7) * 5; $partWeekDays = self::calcPartWeekDays($startDow, $endDow); // Test any extra holiday parameters @@ -67,7 +67,7 @@ public static function funcNetworkdays($startDate, $endDate, ...$dateArgs) private static function calcStartDow(float $startDate): int { - $startDow = 6 - Weekday::funcWeekday($startDate, 2); + $startDow = 6 - (int) Weekday::funcWeekday($startDate, 2); if ($startDow < 0) { $startDow = 5; } @@ -95,7 +95,7 @@ private static function calcPartWeekDays(int $startDow, int $endDow): int return $partWeekDays; } - private static function applySign(int $result, int $sDate, int $eDate) + private static function applySign(int $result, float $sDate, float $eDate) { return ($sDate > $eDate) ? -$result : $result; } diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Weeknum.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Weeknum.php index 2ed80948fd..5f5ed920af 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Weeknum.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Weeknum.php @@ -113,7 +113,7 @@ public static function funcWeeknum($dateValue, $method = self::STARTWEEK_SUNDAY) * * @param mixed $dateValue */ - private static function validateDateValue($dateValue): int + private static function validateDateValue($dateValue): float { if (is_bool($dateValue)) { throw new Exception(Functions::VALUE()); diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php index 86fe83a7df..14ece071fc 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php @@ -50,7 +50,7 @@ public static function funcYearfrac($startDate, $endDate, $method = 0) case 0: return Days360::funcDays360($startDate, $endDate) / 360; case 1: - return self::method1($startDate, $endDate, $method); + return self::method1($startDate, $endDate); case 2: return Datedif::funcDatedif($startDate, $endDate) / 360; case 3: @@ -62,7 +62,7 @@ public static function funcYearfrac($startDate, $endDate, $method = 0) return Functions::NAN(); } - private static function method1(float $startDate, float $endDate, int $method): float + private static function method1(float $startDate, float $endDate): float { $days = Datedif::funcDatedif($startDate, $endDate); $startYear = Year::funcYear($startDate); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/AllSetupTeardown.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/AllSetupTeardown.php index 709a83c8b4..c56c743125 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/AllSetupTeardown.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/AllSetupTeardown.php @@ -39,22 +39,22 @@ protected function tearDown(): void $this->sheet = null; } - protected function setMac1904(): void + protected static function setMac1904(): void { Date::setExcelCalendar(Date::CALENDAR_MAC_1904); } - protected function setUnixReturn(): void + protected static function setUnixReturn(): void { Functions::setReturnDateType(Functions::RETURNDATE_UNIX_TIMESTAMP); } - protected function setObjectReturn(): void + protected static function setObjectReturn(): void { Functions::setReturnDateType(Functions::RETURNDATE_PHP_DATETIME_OBJECT); } - protected function setOpenOffice(): void + protected static function setOpenOffice(): void { Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateDifTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateDifTest.php index e772eaa16c..6c39408787 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateDifTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateDifTest.php @@ -11,7 +11,7 @@ class DateDifTest extends AllSetupTeardown */ public function testDATEDIF($expectedResult, string $formula): void { - self::mightHaveException($expectedResult); + $this->mightHaveException($expectedResult); $sheet = $this->sheet; $sheet->getCell('B1')->setValue('1954-11-23'); $sheet->getCell('A1')->setValue("=DATEDIF($formula)"); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateTest.php index ff45a6dd6a..354e6f3bcc 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateTest.php @@ -13,7 +13,7 @@ class DateTest extends AllSetupTeardown */ public function testDATE($expectedResult, string $formula): void { - self::mightHaveException($expectedResult); + $this->mightHaveException($expectedResult); $sheet = $this->sheet; $sheet->getCell('B1')->setValue('1954-11-23'); $sheet->getCell('A1')->setValue("=DATE($formula)"); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DayTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DayTest.php index 7c54911d30..e50475cf33 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DayTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DayTest.php @@ -11,7 +11,7 @@ class DayTest extends AllSetupTeardown */ public function testDAY($expectedResultExcel, string $dateTimeValue): void { - self::mightHaveException($expectedResultExcel); + $this->mightHaveException($expectedResultExcel); $sheet = $this->sheet; $sheet->getCell('B1')->setValue('1954-11-23'); $sheet->getCell('A1')->setValue("=DAY($dateTimeValue)"); @@ -31,7 +31,7 @@ public function providerDAY() public function testDAYOpenOffice($expectedResultOpenOffice, string $dateTimeValue): void { self::setOpenOffice(); - self::mightHaveException($expectedResultOpenOffice); + $this->mightHaveException($expectedResultOpenOffice); $sheet = $this->sheet; $sheet->getCell('A2')->setValue("=DAY($dateTimeValue)"); self::assertSame($expectedResultOpenOffice, $sheet->getCell('A2')->getCalculatedValue()); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/Days360Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/Days360Test.php index 8b054fa5a4..5d6ba29e1a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/Days360Test.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/Days360Test.php @@ -11,7 +11,7 @@ class Days360Test extends AllSetupTeardown */ public function testDAYS360($expectedResult, string $formula): void { - self::mightHaveException($expectedResult); + $this->mightHaveException($expectedResult); $sheet = $this->sheet; $sheet->getCell('B1')->setValue('2000-02-29'); $sheet->getCell('C1')->setValue('2000-03-31'); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DaysTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DaysTest.php index f64c98aa22..e016d064b3 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DaysTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DaysTest.php @@ -15,7 +15,7 @@ class DaysTest extends AllSetupTeardown */ public function testDAYS($expectedResult, string $formula): void { - self::mightHaveException($expectedResult); + $this->mightHaveException($expectedResult); $sheet = $this->sheet; $sheet->getCell('B1')->setValue('1954-11-23'); $sheet->getCell('C1')->setValue('1954-11-30'); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EDateTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EDateTest.php index 2f9707eba2..30bba2336d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EDateTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EDateTest.php @@ -13,7 +13,7 @@ class EDateTest extends AllSetupTeardown */ public function testEDATE($expectedResult, string $formula): void { - self::mightHaveException($expectedResult); + $this->mightHaveException($expectedResult); $sheet = $this->sheet; $sheet->getCell('A1')->setValue("=EDATE($formula)"); $sheet->getCell('B1')->setValue('1954-11-23'); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EoMonthTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EoMonthTest.php index 85fc77d9b0..ae1a4a9ef1 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EoMonthTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EoMonthTest.php @@ -13,7 +13,7 @@ class EoMonthTest extends AllSetupTeardown */ public function testEOMONTH($expectedResult, string $formula): void { - self::mightHaveException($expectedResult); + $this->mightHaveException($expectedResult); $sheet = $this->sheet; $sheet->getCell('A1')->setValue("=EOMONTH($formula)"); $sheet->getCell('B1')->setValue('1954-11-23'); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/HourTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/HourTest.php index ff9df7ed23..99544b5ad3 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/HourTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/HourTest.php @@ -11,7 +11,7 @@ class HourTest extends AllSetupTeardown */ public function testHOUR($expectedResult, string $dateTimeValue): void { - self::mightHaveException($expectedResult); + $this->mightHaveException($expectedResult); $sheet = $this->sheet; $sheet->getCell('A1')->setValue("=HOUR($dateTimeValue)"); $sheet->getCell('B1')->setValue('1954-11-23 2:23:46'); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/IsoWeekNumTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/IsoWeekNumTest.php index c6eaab0e72..b27ca7d5e9 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/IsoWeekNumTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/IsoWeekNumTest.php @@ -12,7 +12,7 @@ class IsoWeekNumTest extends AllSetupTeardown */ public function testISOWEEKNUM($expectedResult, $dateValue): void { - self::mightHaveException($expectedResult); + $this->mightHaveException($expectedResult); $sheet = $this->sheet; $sheet->getCell('A1')->setValue("=ISOWEEKNUM($dateValue)"); $sheet->getCell('B1')->setValue('1954-11-23'); @@ -32,7 +32,7 @@ public function providerISOWEEKNUM() */ public function testISOWEEKNUM1904($expectedResult, $dateValue): void { - self::mightHaveException($expectedResult); + $this->mightHaveException($expectedResult); self::setMac1904(); $sheet = $this->sheet; $sheet->getCell('A1')->setValue("=ISOWEEKNUM($dateValue)"); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MinuteTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MinuteTest.php index d127e96503..cbc2a1a466 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MinuteTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MinuteTest.php @@ -11,7 +11,7 @@ class MinuteTest extends AllSetupTeardown */ public function testMINUTE($expectedResult, string $dateTimeValue): void { - self::mightHaveException($expectedResult); + $this->mightHaveException($expectedResult); $sheet = $this->sheet; $sheet->getCell('A1')->setValue("=MINUTE($dateTimeValue)"); $sheet->getCell('B1')->setValue('1954-11-23 2:23:46'); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MonthTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MonthTest.php index 8fb7a86f97..a9f702296c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MonthTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MonthTest.php @@ -11,7 +11,7 @@ class MonthTest extends AllSetupTeardown */ public function testMONTH($expectedResult, string $dateTimeValue): void { - self::mightHaveException($expectedResult); + $this->mightHaveException($expectedResult); $sheet = $this->sheet; $sheet->getCell('A1')->setValue("=MONTH($dateTimeValue)"); $sheet->getCell('B1')->setValue('1954-11-23'); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/SecondTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/SecondTest.php index 5f772cb2ea..03cef8bc0d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/SecondTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/SecondTest.php @@ -11,7 +11,7 @@ class SecondTest extends AllSetupTeardown */ public function testSECOND($expectedResult, string $dateTimeValue): void { - self::mightHaveException($expectedResult); + $this->mightHaveException($expectedResult); $sheet = $this->sheet; $sheet->getCell('A1')->setValue("=SECOND($dateTimeValue)"); $sheet->getCell('B1')->setValue('1954-11-23 2:23:46'); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeTest.php index b28e8eea68..f33b5aacbb 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeTest.php @@ -13,7 +13,7 @@ class TimeTest extends AllSetupTeardown */ public function testTIME($expectedResult, string $formula): void { - self::mightHaveException($expectedResult); + $this->mightHaveException($expectedResult); $sheet = $this->sheet; $sheet->getCell('B1')->setValue('15'); $sheet->getCell('B2')->setValue('32'); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeValueTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeValueTest.php index 04cb20d38c..aec9dfda80 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeValueTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeValueTest.php @@ -14,7 +14,7 @@ class TimeValueTest extends AllSetupTeardown */ public function testTIMEVALUE($expectedResult, $timeValue): void { - self::mightHaveException($expectedResult); + $this->mightHaveException($expectedResult); $sheet = $this->sheet; $sheet->getCell('B1')->setValue('03:45:52'); $sheet->getCell('A1')->setValue("=TIMEVALUE($timeValue)"); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekDayTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekDayTest.php index 79c84e28fd..7303c8d18b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekDayTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekDayTest.php @@ -13,7 +13,7 @@ class WeekDayTest extends AllSetupTeardown */ public function testWEEKDAY($expectedResult, string $formula): void { - self::mightHaveException($expectedResult); + $this->mightHaveException($expectedResult); $sheet = $this->sheet; $sheet->getCell('B1')->setValue('1954-11-23'); $sheet->getCell('A1')->setValue("=WEEKDAY($formula)"); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekNumTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekNumTest.php index 0efed4e269..c3e785f3cc 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekNumTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekNumTest.php @@ -11,7 +11,7 @@ class WeekNumTest extends AllSetupTeardown */ public function testWEEKNUM($expectedResult, string $formula): void { - self::mightHaveException($expectedResult); + $this->mightHaveException($expectedResult); $sheet = $this->sheet; $sheet->getCell('B1')->setValue('1954-11-23'); $sheet->getCell('A1')->setValue("=WEEKNUM($formula)"); @@ -30,7 +30,7 @@ public function providerWEEKNUM() */ public function testWEEKNUM1904($expectedResult, string $formula): void { - self::mightHaveException($expectedResult); + $this->mightHaveException($expectedResult); self::setMac1904(); $sheet = $this->sheet; $sheet->getCell('B1')->setValue('1954-11-23'); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearTest.php index 503da7b655..7942f06cdf 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearTest.php @@ -11,7 +11,7 @@ class YearTest extends AllSetupTeardown */ public function testYEAR($expectedResult, string $dateTimeValue): void { - self::mightHaveException($expectedResult); + $this->mightHaveException($expectedResult); $sheet = $this->sheet; $sheet->getCell('A1')->setValue("=YEAR($dateTimeValue)"); $sheet->getCell('B1')->setValue('1954-11-23'); From f9b037a065df63d08538b7b66f2502d8a89027ba Mon Sep 17 00:00:00 2001 From: Owen Leibman Date: Thu, 18 Mar 2021 20:39:23 -0700 Subject: [PATCH 05/12] More Scrutinizer Down to 4 issues. --- src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php | 8 +------- src/PhpSpreadsheet/Calculation/DateTimeExcel/Days.php | 2 +- .../Calculation/DateTimeExcel/Networkdays.php | 2 +- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php index e58c1e9eef..cf3af9f8d5 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php @@ -52,9 +52,8 @@ public static function funcDatedif($startDate, $endDate, $unit = 'D') $retVal = self::replaceRetValue($retVal, $unit, 'Y') ?? self::datedifY($PHPDiffDateObject); $retVal = self::replaceRetValue($retVal, $unit, 'YD') ?? self::datedifYD($difference, $startYears, $endYears, $PHPStartDateObject, $PHPEndDateObject); $retVal = self::replaceRetValue($retVal, $unit, 'YM') ?? self::datedifYM($PHPDiffDateObject); - $retVal = self::replaceRetValue($retVal, 'D', 'D') ?? self::datedifInvalid(); - return $retVal; + return is_bool($retVal) ? Functions::VALUE() : $retVal; } private static function initialDiff(float $startDate, float $endDate): float @@ -144,9 +143,4 @@ private static function datedifYM(DateInterval $PHPDiffDateObject): int { return (int) $PHPDiffDateObject->format('%m'); } - - private static function datedifInvalid(): string - { - return Functions::VALUE(); - } } diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days.php index f0195cf916..c8083a61ba 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days.php @@ -38,7 +38,7 @@ public static function funcDays($endDate, $startDate) $PHPEndDateObject = Date::excelToDateTimeObject($endDate); $diff = $PHPStartDateObject->diff($PHPEndDateObject); - if ($diff !== false && $diff->days !== false) { + if ($diff !== false && !is_bool($diff->days)) { $days = $diff->days; if ($diff->invert) { $days = -$days; diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Networkdays.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Networkdays.php index 9a424238e8..878b500624 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Networkdays.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Networkdays.php @@ -77,7 +77,7 @@ private static function calcStartDow(float $startDate): int private static function calcEndDow(float $endDate): int { - $endDow = Weekday::funcWeekday($endDate, 2); + $endDow = (int) Weekday::funcWeekday($endDate, 2); if ($endDow >= 6) { $endDow = 0; } From ac6910cdfe403de5f08ae832da6ebe5e8cd68dbc Mon Sep 17 00:00:00 2001 From: Owen Leibman Date: Fri, 19 Mar 2021 08:16:54 -0700 Subject: [PATCH 06/12] First Capitalization Change in New Classes Mark Baker has suggested changing capitalization in some new classes. I am concerned that, because I am dealing with Windows which uses non-case-sensitive file names, things may get messed up when I attempt that. So, here's a test case renaming one class, to see how that fares. Once I know that, I'll know how to handle the rest. --- src/PhpSpreadsheet/Calculation/Calculation.php | 2 +- src/PhpSpreadsheet/Calculation/DateTime.php | 4 ++-- src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php | 2 +- src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php | 6 +++--- tests/data/Calculation/DateTime/ISOWEEKNUM.php | 2 +- tests/data/Calculation/DateTime/ISOWEEKNUM1904.php | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index dfb4925188..a68b5770c8 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -759,7 +759,7 @@ class Calculation ], 'DATEDIF' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\Datedif::class, 'funcDatedif'], + 'functionCall' => [DateTimeExcel\DateDif::class, 'funcDateDif'], 'argumentCount' => '2,3', ], 'DATEVALUE' => [ diff --git a/src/PhpSpreadsheet/Calculation/DateTime.php b/src/PhpSpreadsheet/Calculation/DateTime.php index 2aa265d6ca..4e7b79631d 100644 --- a/src/PhpSpreadsheet/Calculation/DateTime.php +++ b/src/PhpSpreadsheet/Calculation/DateTime.php @@ -234,7 +234,7 @@ public static function TIMEVALUE($timeValue) /** * DATEDIF. * - * @Deprecated 2.0.0 Use the funcDatedif method in the DateTimeExcel\Datedif class instead + * @Deprecated 2.0.0 Use the funcDateDif method in the DateTimeExcel\DateDif class instead * * @param mixed $startDate Excel date serial value, PHP date/time stamp, PHP DateTime object * or a standard date string @@ -246,7 +246,7 @@ public static function TIMEVALUE($timeValue) */ public static function DATEDIF($startDate = 0, $endDate = 0, $unit = 'D') { - return DateTimeExcel\Datedif::funcDatedif($startDate, $endDate, $unit); + return DateTimeExcel\DateDif::funcDateDif($startDate, $endDate, $unit); } /** diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php index cf3af9f8d5..212c6b347b 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php @@ -21,7 +21,7 @@ class Datedif * * @return int|string Interval between the dates */ - public static function funcDatedif($startDate, $endDate, $unit = 'D') + public static function funcDateDif($startDate, $endDate, $unit = 'D') { try { $startDate = Helpers::getDateValue($startDate); diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php index 14ece071fc..2b4bd3e958 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php @@ -52,9 +52,9 @@ public static function funcYearfrac($startDate, $endDate, $method = 0) case 1: return self::method1($startDate, $endDate); case 2: - return Datedif::funcDatedif($startDate, $endDate) / 360; + return DateDif::funcDateDif($startDate, $endDate) / 360; case 3: - return Datedif::funcDatedif($startDate, $endDate) / 365; + return DateDif::funcDateDif($startDate, $endDate) / 365; case 4: return Days360::funcDays360($startDate, $endDate, true) / 360; } @@ -64,7 +64,7 @@ public static function funcYearfrac($startDate, $endDate, $method = 0) private static function method1(float $startDate, float $endDate): float { - $days = Datedif::funcDatedif($startDate, $endDate); + $days = DateDif::funcDateDif($startDate, $endDate); $startYear = Year::funcYear($startDate); $endYear = Year::funcYear($endDate); $years = $endYear - $startYear + 1; diff --git a/tests/data/Calculation/DateTime/ISOWEEKNUM.php b/tests/data/Calculation/DateTime/ISOWEEKNUM.php index 63a3e1a47f..bc532455b9 100644 --- a/tests/data/Calculation/DateTime/ISOWEEKNUM.php +++ b/tests/data/Calculation/DateTime/ISOWEEKNUM.php @@ -3,7 +3,7 @@ return [ [51, '"21-Dec-2000"'], [52, '"2000-01-01"'], - [1, '"2000-01-03"'], + [1, '"2000-01-03"'], [52, '"1995-01-01"'], [1, '"1995-01-07"'], [2, '"1995-01-10"'], diff --git a/tests/data/Calculation/DateTime/ISOWEEKNUM1904.php b/tests/data/Calculation/DateTime/ISOWEEKNUM1904.php index f3a3b46900..a87cb5b268 100644 --- a/tests/data/Calculation/DateTime/ISOWEEKNUM1904.php +++ b/tests/data/Calculation/DateTime/ISOWEEKNUM1904.php @@ -3,7 +3,7 @@ return [ [51, '"21-Dec-2000"'], [52, '"2000-01-01"'], - [1, '"2000-01-03"'], + [1, '"2000-01-03"'], [52, '"1995-01-01"'], [1, '"1995-01-07"'], [2, '"1995-01-10"'], From ad7a21cd2cef113e7f6ed43f20bb0d1f1ebc9ef3 Mon Sep 17 00:00:00 2001 From: Owen Leibman Date: Fri, 19 Mar 2021 08:23:37 -0700 Subject: [PATCH 07/12] Error in My Simple Capitalization Change Missed one needed change. Correcting and trying again. --- src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php index 212c6b347b..ace22cbfbf 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php @@ -8,7 +8,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Shared\Date; -class Datedif +class DateDif { /** * DATEDIF. From 81528e36a24595f78abb3921120b7cff0f6bac48 Mon Sep 17 00:00:00 2001 From: Owen Leibman Date: Fri, 19 Mar 2021 08:30:47 -0700 Subject: [PATCH 08/12] Trying Rename as 2-step Process As feared, Windows non-case-sensitive names make this process difficult. --- src/PhpSpreadsheet/Calculation/Calculation.php | 2 +- src/PhpSpreadsheet/Calculation/DateTime.php | 2 +- .../Calculation/DateTimeExcel/{Datedif.php => XDateDif.php} | 2 +- src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) rename src/PhpSpreadsheet/Calculation/DateTimeExcel/{Datedif.php => XDateDif.php} (99%) diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index a68b5770c8..cbad20facd 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -759,7 +759,7 @@ class Calculation ], 'DATEDIF' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\DateDif::class, 'funcDateDif'], + 'functionCall' => [DateTimeExcel\XDateDif::class, 'funcDateDif'], 'argumentCount' => '2,3', ], 'DATEVALUE' => [ diff --git a/src/PhpSpreadsheet/Calculation/DateTime.php b/src/PhpSpreadsheet/Calculation/DateTime.php index 4e7b79631d..c09d63803d 100644 --- a/src/PhpSpreadsheet/Calculation/DateTime.php +++ b/src/PhpSpreadsheet/Calculation/DateTime.php @@ -246,7 +246,7 @@ public static function TIMEVALUE($timeValue) */ public static function DATEDIF($startDate = 0, $endDate = 0, $unit = 'D') { - return DateTimeExcel\DateDif::funcDateDif($startDate, $endDate, $unit); + return DateTimeExcel\XDateDif::funcDateDif($startDate, $endDate, $unit); } /** diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/XDateDif.php similarity index 99% rename from src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php rename to src/PhpSpreadsheet/Calculation/DateTimeExcel/XDateDif.php index ace22cbfbf..c0618a845b 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datedif.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/XDateDif.php @@ -8,7 +8,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Shared\Date; -class DateDif +class XDateDif { /** * DATEDIF. diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php index 2b4bd3e958..e26a3d0df7 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php @@ -52,9 +52,9 @@ public static function funcYearfrac($startDate, $endDate, $method = 0) case 1: return self::method1($startDate, $endDate); case 2: - return DateDif::funcDateDif($startDate, $endDate) / 360; + return XDateDif::funcDateDif($startDate, $endDate) / 360; case 3: - return DateDif::funcDateDif($startDate, $endDate) / 365; + return XDateDif::funcDateDif($startDate, $endDate) / 365; case 4: return Days360::funcDays360($startDate, $endDate, true) / 360; } @@ -64,7 +64,7 @@ public static function funcYearfrac($startDate, $endDate, $method = 0) private static function method1(float $startDate, float $endDate): float { - $days = DateDif::funcDateDif($startDate, $endDate); + $days = XDateDif::funcDateDif($startDate, $endDate); $startYear = Year::funcYear($startDate); $endYear = Year::funcYear($endDate); $years = $endYear - $startYear + 1; From 8afc8b62f34ec15735a2333b6a17d78e9f4679e5 Mon Sep 17 00:00:00 2001 From: Owen Leibman Date: Fri, 19 Mar 2021 08:39:27 -0700 Subject: [PATCH 09/12] Trying Rename as 2-step Process - Part 2 First part worked. Let's see if this one does. --- src/PhpSpreadsheet/Calculation/Calculation.php | 2 +- src/PhpSpreadsheet/Calculation/DateTime.php | 2 +- .../Calculation/DateTimeExcel/{XDateDif.php => DateDif.php} | 2 +- src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) rename src/PhpSpreadsheet/Calculation/DateTimeExcel/{XDateDif.php => DateDif.php} (99%) diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index cbad20facd..a68b5770c8 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -759,7 +759,7 @@ class Calculation ], 'DATEDIF' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\XDateDif::class, 'funcDateDif'], + 'functionCall' => [DateTimeExcel\DateDif::class, 'funcDateDif'], 'argumentCount' => '2,3', ], 'DATEVALUE' => [ diff --git a/src/PhpSpreadsheet/Calculation/DateTime.php b/src/PhpSpreadsheet/Calculation/DateTime.php index c09d63803d..4e7b79631d 100644 --- a/src/PhpSpreadsheet/Calculation/DateTime.php +++ b/src/PhpSpreadsheet/Calculation/DateTime.php @@ -246,7 +246,7 @@ public static function TIMEVALUE($timeValue) */ public static function DATEDIF($startDate = 0, $endDate = 0, $unit = 'D') { - return DateTimeExcel\XDateDif::funcDateDif($startDate, $endDate, $unit); + return DateTimeExcel\DateDif::funcDateDif($startDate, $endDate, $unit); } /** diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/XDateDif.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/DateDif.php similarity index 99% rename from src/PhpSpreadsheet/Calculation/DateTimeExcel/XDateDif.php rename to src/PhpSpreadsheet/Calculation/DateTimeExcel/DateDif.php index c0618a845b..ace22cbfbf 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/XDateDif.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/DateDif.php @@ -8,7 +8,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Shared\Date; -class XDateDif +class DateDif { /** * DATEDIF. diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php index e26a3d0df7..2b4bd3e958 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php @@ -52,9 +52,9 @@ public static function funcYearfrac($startDate, $endDate, $method = 0) case 1: return self::method1($startDate, $endDate); case 2: - return XDateDif::funcDateDif($startDate, $endDate) / 360; + return DateDif::funcDateDif($startDate, $endDate) / 360; case 3: - return XDateDif::funcDateDif($startDate, $endDate) / 365; + return DateDif::funcDateDif($startDate, $endDate) / 365; case 4: return Days360::funcDays360($startDate, $endDate, true) / 360; } @@ -64,7 +64,7 @@ public static function funcYearfrac($startDate, $endDate, $method = 0) private static function method1(float $startDate, float $endDate): float { - $days = XDateDif::funcDateDif($startDate, $endDate); + $days = DateDif::funcDateDif($startDate, $endDate); $startYear = Year::funcYear($startDate); $endYear = Year::funcYear($endDate); $years = $endYear - $startYear + 1; From 9d23741dce4233887410d7411799fb3cda3223bd Mon Sep 17 00:00:00 2001 From: Owen Leibman Date: Fri, 19 Mar 2021 16:54:24 -0700 Subject: [PATCH 10/12] Multiple Class Renames - Part 1 of 2 Well, I hope just 2 parts to this. Need to do in 2 steps due to Windows file system being case insensitive. --- .../Calculation/Calculation.php | 20 +++++----- src/PhpSpreadsheet/Calculation/DateTime.php | 38 +++++++++---------- .../Calculation/DateTimeExcel/Helpers.php | 4 +- .../{Datevalue.php => ZYXDateValue.php} | 4 +- .../DateTimeExcel/{Edate.php => ZYXEDate.php} | 4 +- .../{Eomonth.php => ZYXEoMonth.php} | 4 +- .../{IsoWeeknum.php => ZYXIsoWeekNum.php} | 4 +- .../{Networkdays.php => ZYXNetworkDays.php} | 10 ++--- .../{Timevalue.php => ZYXTimeValue.php} | 4 +- .../{Weekday.php => ZYXWeekDay.php} | 4 +- .../{Weeknum.php => ZYXWeekNum.php} | 4 +- .../{Workday.php => ZYXWorkDay.php} | 24 ++++++------ .../{Yearfrac.php => ZYXYearFrac.php} | 4 +- .../Functions/DateTime/DateValueTest.php | 16 ++++---- .../Functions/DateTime/EDateTest.php | 6 +-- .../Functions/DateTime/EoMonthTest.php | 6 +-- .../Functions/DateTime/NetworkDaysTest.php | 4 +- .../Functions/DateTime/TimeValueTest.php | 6 +-- .../Functions/DateTime/WeekDayTest.php | 8 ++-- .../Functions/DateTime/YearFracTest.php | 4 +- 20 files changed, 89 insertions(+), 89 deletions(-) rename src/PhpSpreadsheet/Calculation/DateTimeExcel/{Datevalue.php => ZYXDateValue.php} (98%) rename src/PhpSpreadsheet/Calculation/DateTimeExcel/{Edate.php => ZYXEDate.php} (95%) rename src/PhpSpreadsheet/Calculation/DateTimeExcel/{Eomonth.php => ZYXEoMonth.php} (95%) rename src/PhpSpreadsheet/Calculation/DateTimeExcel/{IsoWeeknum.php => ZYXIsoWeekNum.php} (94%) rename src/PhpSpreadsheet/Calculation/DateTimeExcel/{Networkdays.php => ZYXNetworkDays.php} (90%) rename src/PhpSpreadsheet/Calculation/DateTimeExcel/{Timevalue.php => ZYXTimeValue.php} (97%) rename src/PhpSpreadsheet/Calculation/DateTimeExcel/{Weekday.php => ZYXWeekDay.php} (96%) rename src/PhpSpreadsheet/Calculation/DateTimeExcel/{Weeknum.php => ZYXWeekNum.php} (98%) rename src/PhpSpreadsheet/Calculation/DateTimeExcel/{Workday.php => ZYXWorkDay.php} (89%) rename src/PhpSpreadsheet/Calculation/DateTimeExcel/{Yearfrac.php => ZYXYearFrac.php} (97%) diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index a68b5770c8..01e8f5f020 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -764,7 +764,7 @@ class Calculation ], 'DATEVALUE' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\Datevalue::class, 'funcDatevalue'], + 'functionCall' => [DateTimeExcel\ZYXDateValue::class, 'funcDateValue'], 'argumentCount' => '1', ], 'DAVERAGE' => [ @@ -919,7 +919,7 @@ class Calculation ], 'EDATE' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\Edate::class, 'funcEdate'], + 'functionCall' => [DateTimeExcel\ZYXEDate::class, 'funcEDate'], 'argumentCount' => '2', ], 'EFFECT' => [ @@ -934,7 +934,7 @@ class Calculation ], 'EOMONTH' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\Eomonth::class, 'funcEomonth'], + 'functionCall' => [DateTimeExcel\ZYXEoMonth::class, 'funcEoMonth'], 'argumentCount' => '2', ], 'ERF' => [ @@ -1500,7 +1500,7 @@ class Calculation ], 'ISOWEEKNUM' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\IsoWeeknum::class, 'funcIsoWeeknum'], + 'functionCall' => [DateTimeExcel\ZYXIsoWeekNum::class, 'funcIsoWeekNum'], 'argumentCount' => '1', ], 'ISPMT' => [ @@ -1760,7 +1760,7 @@ class Calculation ], 'NETWORKDAYS' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\Networkdays::class, 'funcNetworkdays'], + 'functionCall' => [DateTimeExcel\ZYXNetworkDays::class, 'funcNetworkDays'], 'argumentCount' => '2-3', ], 'NETWORKDAYS.INTL' => [ @@ -2424,7 +2424,7 @@ class Calculation ], 'TIMEVALUE' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\Timevalue::class, 'funcTimevalue'], + 'functionCall' => [DateTimeExcel\ZYXTimeValue::class, 'funcTimeValue'], 'argumentCount' => '1', ], 'TINV' => [ @@ -2569,12 +2569,12 @@ class Calculation ], 'WEEKDAY' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\Weekday::class, 'funcWeekday'], + 'functionCall' => [DateTimeExcel\ZYXWeekDay::class, 'funcWeekDay'], 'argumentCount' => '1,2', ], 'WEEKNUM' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\Weeknum::class, 'funcWeeknum'], + 'functionCall' => [DateTimeExcel\ZYXWeekNum::class, 'funcWeekNum'], 'argumentCount' => '1,2', ], 'WEIBULL' => [ @@ -2589,7 +2589,7 @@ class Calculation ], 'WORKDAY' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\Workday::class, 'funcWorkday'], + 'functionCall' => [DateTimeExcel\ZYXWorkDay::class, 'funcWorkDay'], 'argumentCount' => '2-3', ], 'WORKDAY.INTL' => [ @@ -2629,7 +2629,7 @@ class Calculation ], 'YEARFRAC' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\Yearfrac::class, 'funcYearfrac'], + 'functionCall' => [DateTimeExcel\ZYXYearFrac::class, 'funcYearFrac'], 'argumentCount' => '2,3', ], 'YIELD' => [ diff --git a/src/PhpSpreadsheet/Calculation/DateTime.php b/src/PhpSpreadsheet/Calculation/DateTime.php index 4e7b79631d..bd32b98394 100644 --- a/src/PhpSpreadsheet/Calculation/DateTime.php +++ b/src/PhpSpreadsheet/Calculation/DateTime.php @@ -181,7 +181,7 @@ public static function TIME($hour = 0, $minute = 0, $second = 0) * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date * format of your regional settings. PhpSpreadsheet does not change cell formatting in this way. * - * @Deprecated 2.0.0 Use the funcDatevalue method in the DateTimeExcel\DateValue class instead + * @Deprecated 2.0.0 Use the funcDateValue method in the DateTimeExcel\DateValue class instead * * Excel Function: * DATEVALUE(dateValue) @@ -200,7 +200,7 @@ public static function TIME($hour = 0, $minute = 0, $second = 0) */ public static function DATEVALUE($dateValue = 1) { - return DateTimeExcel\Datevalue::funcDatevalue($dateValue); + return DateTimeExcel\ZYXDateValue::funcDateValue($dateValue); } /** @@ -213,7 +213,7 @@ public static function DATEVALUE($dateValue = 1) * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the time * format of your regional settings. PhpSpreadsheet does not change cell formatting in this way. * - * @Deprecated 2.0.0 Use the funcTimevalue method in the DateTimeExcel\TimeValue class instead + * @Deprecated 2.0.0 Use the funcTimeValue method in the DateTimeExcel\TimeValue class instead * * Excel Function: * TIMEVALUE(timeValue) @@ -228,7 +228,7 @@ public static function DATEVALUE($dateValue = 1) */ public static function TIMEVALUE($timeValue) { - return DateTimeExcel\Timevalue::funcTimevalue($timeValue); + return DateTimeExcel\ZYXTimeValue::funcTimeValue($timeValue); } /** @@ -314,7 +314,7 @@ public static function DAYS360($startDate = 0, $endDate = 0, $method = false) * Use the YEARFRAC worksheet function to identify the proportion of a whole year's benefits or * obligations to assign to a specific term. * - * @Deprecated 2.0.0 Use the funcYearfrac method in the DateTimeExcel\YearFrac class instead + * @Deprecated 2.0.0 Use the funcYearFrac method in the DateTimeExcel\YearFrac class instead * * Excel Function: * YEARFRAC(startDate,endDate[,method]) @@ -336,7 +336,7 @@ public static function DAYS360($startDate = 0, $endDate = 0, $method = false) */ public static function YEARFRAC($startDate = 0, $endDate = 0, $method = 0) { - return DateTimeExcel\YearFrac::funcYearfrac($startDate, $endDate, $method); + return DateTimeExcel\ZYXYearFrac::funcYearFrac($startDate, $endDate, $method); } /** @@ -347,7 +347,7 @@ public static function YEARFRAC($startDate = 0, $endDate = 0, $method = 0) * Use NETWORKDAYS to calculate employee benefits that accrue based on the number of days * worked during a specific term. * - * @Deprecated 2.0.0 Use the funcNetworkdays method in the DateTimeExcel\Networkdays class instead + * @Deprecated 2.0.0 Use the funcNetworkDays method in the DateTimeExcel\NetworkDays class instead * * Excel Function: * NETWORKDAYS(startDate,endDate[,holidays[,holiday[,...]]]) @@ -361,7 +361,7 @@ public static function YEARFRAC($startDate = 0, $endDate = 0, $method = 0) */ public static function NETWORKDAYS($startDate, $endDate, ...$dateArgs) { - return DateTimeExcel\Networkdays::funcNetworkdays($startDate, $endDate, ...$dateArgs); + return DateTimeExcel\ZYXNetworkDays::funcNetworkDays($startDate, $endDate, ...$dateArgs); } /** @@ -372,7 +372,7 @@ public static function NETWORKDAYS($startDate, $endDate, ...$dateArgs) * Use WORKDAY to exclude weekends or holidays when you calculate invoice due dates, expected * delivery times, or the number of days of work performed. * - * @Deprecated 2.0.0 Use the funcWorkday method in the DateTimeExcel\Workday class instead + * @Deprecated 2.0.0 Use the funcWorkDay method in the DateTimeExcel\WorkDay class instead * * Excel Function: * WORKDAY(startDate,endDays[,holidays[,holiday[,...]]]) @@ -388,7 +388,7 @@ public static function NETWORKDAYS($startDate, $endDate, ...$dateArgs) */ public static function WORKDAY($startDate, $endDays, ...$dateArgs) { - return DateTimeExcel\Workday::funcWorkday($startDate, $endDays, ...$dateArgs); + return DateTimeExcel\ZYXWorkDay::funcWorkDay($startDate, $endDays, ...$dateArgs); } /** @@ -418,7 +418,7 @@ public static function DAYOFMONTH($dateValue = 1) * Returns the day of the week for a specified date. The day is given as an integer * ranging from 0 to 7 (dependent on the requested style). * - * @Deprecated 2.0.0 Use the funcWeekday method in the DateTimeExcel\Weekday class instead + * @Deprecated 2.0.0 Use the funcWeekDay method in the DateTimeExcel\WeekDay class instead * * Excel Function: * WEEKDAY(dateValue[,style]) @@ -434,7 +434,7 @@ public static function DAYOFMONTH($dateValue = 1) */ public static function WEEKDAY($dateValue = 1, $style = 1) { - return DateTimeExcel\Weekday::funcWeekday($dateValue, $style); + return DateTimeExcel\ZYXWeekDay::funcWeekDay($dateValue, $style); } const STARTWEEK_SUNDAY = 1; @@ -477,7 +477,7 @@ public static function WEEKDAY($dateValue = 1, $style = 1) * three days or less in the first week of January, the WEEKNUM function returns week numbers * that are incorrect according to the European standard. * - * @Deprecated 2.0.0 Use the funcWeeknum method in the DateTimeExcel\Weeknum class instead + * @Deprecated 2.0.0 Use the funcWeekNum method in the DateTimeExcel\WeekNum class instead * * Excel Function: * WEEKNUM(dateValue[,style]) @@ -500,7 +500,7 @@ public static function WEEKDAY($dateValue = 1, $style = 1) */ public static function WEEKNUM($dateValue = 1, $method = self::STARTWEEK_SUNDAY) { - return DateTimeExcel\Weeknum::funcWeeknum($dateValue, $method); + return DateTimeExcel\ZYXWeekNum::funcWeekNum($dateValue, $method); } /** @@ -520,7 +520,7 @@ public static function WEEKNUM($dateValue = 1, $method = self::STARTWEEK_SUNDAY) */ public static function ISOWEEKNUM($dateValue = 1) { - return DateTimeExcel\Isoweeknum::funcIsoWeeknum($dateValue); + return DateTimeExcel\ZYXIsoweekNum::funcIsoWeekNum($dateValue); } /** @@ -636,7 +636,7 @@ public static function SECOND($timeValue = 0) * Use EDATE to calculate maturity dates or due dates that fall on the same day of the month * as the date of issue. * - * @Deprecated 2.0.0 Use the funcEdate method in the DateTimeExcel\Edate class instead + * @Deprecated 2.0.0 Use the funcEDate method in the DateTimeExcel\EDate class instead * * Excel Function: * EDATE(dateValue,adjustmentMonths) @@ -652,7 +652,7 @@ public static function SECOND($timeValue = 0) */ public static function EDATE($dateValue = 1, $adjustmentMonths = 0) { - return DateTimeExcel\Edate::funcEdate($dateValue, $adjustmentMonths); + return DateTimeExcel\ZYXEDate::funcEDate($dateValue, $adjustmentMonths); } /** @@ -662,7 +662,7 @@ public static function EDATE($dateValue = 1, $adjustmentMonths = 0) * before or after start_date. * Use EOMONTH to calculate maturity dates or due dates that fall on the last day of the month. * - * @Deprecated 2.0.0 Use the funcEomonth method in the DateTimeExcel\Eomonth class instead + * @Deprecated 2.0.0 Use the funcEoMonth method in the DateTimeExcel\EoMonth class instead * * Excel Function: * EOMONTH(dateValue,adjustmentMonths) @@ -678,6 +678,6 @@ public static function EDATE($dateValue = 1, $adjustmentMonths = 0) */ public static function EOMONTH($dateValue = 1, $adjustmentMonths = 0) { - return DateTimeExcel\Eomonth::funcEomonth($dateValue, $adjustmentMonths); + return DateTimeExcel\ZYXEoMonth::funcEoMonth($dateValue, $adjustmentMonths); } } diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php index 38aff0a0ca..2c0fe8d6b6 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php @@ -44,7 +44,7 @@ public static function getDateValue($dateValue, bool $allowBool = true) if (!is_numeric($dateValue)) { $saveReturnDateType = Functions::getReturnDateType(); Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - $dateValue = Datevalue::funcDatevalue($dateValue); + $dateValue = ZYXDateValue::funcDateValue($dateValue); Functions::setReturnDateType($saveReturnDateType); if (!is_numeric($dateValue)) { throw new Exception(Functions::VALUE()); @@ -84,7 +84,7 @@ public static function getTimeValue($timeValue) { $saveReturnDateType = Functions::getReturnDateType(); Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - $timeValue = Timevalue::funcTimeValue($timeValue); + $timeValue = ZYXTimeValue::funcTimeValue($timeValue); Functions::setReturnDateType($saveReturnDateType); return $timeValue; diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datevalue.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXDateValue.php similarity index 98% rename from src/PhpSpreadsheet/Calculation/DateTimeExcel/Datevalue.php rename to src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXDateValue.php index 19357b35df..97f7726173 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Datevalue.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXDateValue.php @@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Shared\Date; -class Datevalue +class ZYXDateValue { /** * DATEVALUE. @@ -33,7 +33,7 @@ class Datevalue * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, * depending on the value of the ReturnDateType flag */ - public static function funcDatevalue($dateValue = 1) + public static function funcDateValue($dateValue = 1) { $dti = new DateTimeImmutable(); $baseYear = Date::getExcelCalendar(); diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Edate.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXEDate.php similarity index 95% rename from src/PhpSpreadsheet/Calculation/DateTimeExcel/Edate.php rename to src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXEDate.php index 5bc8d7462e..c04a58e191 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Edate.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXEDate.php @@ -5,7 +5,7 @@ use Exception; use PhpOffice\PhpSpreadsheet\Shared\Date; -class Edate +class ZYXEDate { /** * EDATE. @@ -27,7 +27,7 @@ class Edate * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, * depending on the value of the ReturnDateType flag */ - public static function funcEdate($dateValue, $adjustmentMonths) + public static function funcEDate($dateValue, $adjustmentMonths) { try { $dateValue = Helpers::getDateValue($dateValue, false); diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Eomonth.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXEoMonth.php similarity index 95% rename from src/PhpSpreadsheet/Calculation/DateTimeExcel/Eomonth.php rename to src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXEoMonth.php index 021873c72a..f178bca58c 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Eomonth.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXEoMonth.php @@ -5,7 +5,7 @@ use Exception; use PhpOffice\PhpSpreadsheet\Shared\Date; -class Eomonth +class ZYXEoMonth { /** * EOMONTH. @@ -26,7 +26,7 @@ class Eomonth * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, * depending on the value of the ReturnDateType flag */ - public static function funcEomonth($dateValue, $adjustmentMonths) + public static function funcEoMonth($dateValue, $adjustmentMonths) { try { $dateValue = Helpers::getDateValue($dateValue, false); diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/IsoWeeknum.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXIsoWeekNum.php similarity index 94% rename from src/PhpSpreadsheet/Calculation/DateTimeExcel/IsoWeeknum.php rename to src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXIsoWeekNum.php index e81cc8623d..ed442d6b6f 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/IsoWeeknum.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXIsoWeekNum.php @@ -5,7 +5,7 @@ use Exception; use PhpOffice\PhpSpreadsheet\Shared\Date; -class IsoWeeknum +class ZYXIsoWeekNum { /** * ISOWEEKNUM. @@ -20,7 +20,7 @@ class IsoWeeknum * * @return int|string Week Number */ - public static function funcIsoWeeknum($dateValue) + public static function funcIsoWeekNum($dateValue) { if (self::apparentBug($dateValue)) { return 52; diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Networkdays.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXNetworkDays.php similarity index 90% rename from src/PhpSpreadsheet/Calculation/DateTimeExcel/Networkdays.php rename to src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXNetworkDays.php index 878b500624..fdbbbc31aa 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Networkdays.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXNetworkDays.php @@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Shared\Date; -class Networkdays +class ZYXNetworkDays { /** * NETWORKDAYS. @@ -26,7 +26,7 @@ class Networkdays * * @return int|string Interval between the dates */ - public static function funcNetworkdays($startDate, $endDate, ...$dateArgs) + public static function funcNetworkDays($startDate, $endDate, ...$dateArgs) { try { // Retrieve the mandatory start and end date that are referenced in the function definition @@ -55,7 +55,7 @@ public static function funcNetworkdays($startDate, $endDate, ...$dateArgs) $holidayCountedArray = []; foreach ($holidayArray as $holidayDate) { if (($holidayDate >= $startDate) && ($holidayDate <= $endDate)) { - if ((Weekday::funcWeekday($holidayDate, 2) < 6) && (!in_array($holidayDate, $holidayCountedArray))) { + if ((ZYXWeekDay::funcWeekDay($holidayDate, 2) < 6) && (!in_array($holidayDate, $holidayCountedArray))) { --$partWeekDays; $holidayCountedArray[] = $holidayDate; } @@ -67,7 +67,7 @@ public static function funcNetworkdays($startDate, $endDate, ...$dateArgs) private static function calcStartDow(float $startDate): int { - $startDow = 6 - (int) Weekday::funcWeekday($startDate, 2); + $startDow = 6 - (int) ZYXWeekDay::funcWeekDay($startDate, 2); if ($startDow < 0) { $startDow = 5; } @@ -77,7 +77,7 @@ private static function calcStartDow(float $startDate): int private static function calcEndDow(float $endDate): int { - $endDow = (int) Weekday::funcWeekday($endDate, 2); + $endDow = (int) ZYXWeekDay::funcWeekDay($endDate, 2); if ($endDow >= 6) { $endDow = 0; } diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Timevalue.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXTimeValue.php similarity index 97% rename from src/PhpSpreadsheet/Calculation/DateTimeExcel/Timevalue.php rename to src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXTimeValue.php index 9f7df0f4f0..8dbbc3e4a0 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Timevalue.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXTimeValue.php @@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Shared\Date; -class Timevalue +class ZYXTimeValue { /** * TIMEVALUE. @@ -29,7 +29,7 @@ class Timevalue * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, * depending on the value of the ReturnDateType flag */ - public static function funcTimevalue($timeValue) + public static function funcTimeValue($timeValue) { $timeValue = trim(Functions::flattenSingleValue($timeValue), '"'); $timeValue = str_replace(['/', '.'], '-', $timeValue); diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Weekday.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXWeekDay.php similarity index 96% rename from src/PhpSpreadsheet/Calculation/DateTimeExcel/Weekday.php rename to src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXWeekDay.php index 4cb0a73db9..cd2728dfa3 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Weekday.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXWeekDay.php @@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Shared\Date; -class Weekday +class ZYXWeekDay { /** * WEEKDAY. @@ -26,7 +26,7 @@ class Weekday * * @return int|string Day of the week value */ - public static function funcWeekday($dateValue, $style = 1) + public static function funcWeekDay($dateValue, $style = 1) { try { $dateValue = Helpers::getDateValue($dateValue); diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Weeknum.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXWeekNum.php similarity index 98% rename from src/PhpSpreadsheet/Calculation/DateTimeExcel/Weeknum.php rename to src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXWeekNum.php index 5f5ed920af..06861f134f 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Weeknum.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXWeekNum.php @@ -7,7 +7,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Shared\Date; -class Weeknum +class ZYXWeekNum { const STARTWEEK_SUNDAY = 1; const STARTWEEK_MONDAY = 2; @@ -68,7 +68,7 @@ class Weeknum * * @return int|string Week Number */ - public static function funcWeeknum($dateValue, $method = self::STARTWEEK_SUNDAY) + public static function funcWeekNum($dateValue, $method = self::STARTWEEK_SUNDAY) { $origDateValueNull = empty($dateValue); diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Workday.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXWorkDay.php similarity index 89% rename from src/PhpSpreadsheet/Calculation/DateTimeExcel/Workday.php rename to src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXWorkDay.php index 811033aed3..1badf5c3fd 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Workday.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXWorkDay.php @@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Shared\Date; -class Workday +class ZYXWorkDay { /** * WORKDAY. @@ -28,7 +28,7 @@ class Workday * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, * depending on the value of the ReturnDateType flag */ - public static function funcWorkday($startDate, $endDays, ...$dateArgs) + public static function funcWorkDay($startDate, $endDays, ...$dateArgs) { // Retrieve the mandatory start date and days that are referenced in the function definition try { @@ -65,8 +65,8 @@ private static function incrementing(float $startDate, int $endDays, array $holi { // Adjust the start date if it falls over a weekend - $startDoW = weekday::funcWeekday($startDate, 3); - if (Weekday::funcWeekday($startDate, 3) >= 5) { + $startDoW = ZYXWeekDay::funcWeekDay($startDate, 3); + if (ZYXWeekDay::funcWeekDay($startDate, 3) >= 5) { $startDate += 7 - $startDoW; --$endDays; } @@ -77,7 +77,7 @@ private static function incrementing(float $startDate, int $endDays, array $holi while ($endDays > 0) { ++$endDate; // Adjust the calculated end date if it falls over a weekend - $endDow = Weekday::funcWeekday($endDate, 3); + $endDow = ZYXWeekDay::funcWeekDay($endDate, 3); if ($endDow >= 5) { $endDate += 7 - $endDow; } @@ -96,7 +96,7 @@ private static function incrementingArray(float $startDate, float $endDate, arra { $holidayCountedArray = $holidayDates = []; foreach ($holidayArray as $holidayDate) { - if (Weekday::funcWeekday($holidayDate, 3) < 5) { + if (ZYXWeekDay::funcWeekDay($holidayDate, 3) < 5) { $holidayDates[] = $holidayDate; } } @@ -109,7 +109,7 @@ private static function incrementingArray(float $startDate, float $endDate, arra } } // Adjust the calculated end date if it falls over a weekend - $endDoW = Weekday::funcWeekDay($endDate, 3); + $endDoW = ZYXWeekDay::funcWeekDay($endDate, 3); if ($endDoW >= 5) { $endDate += 7 - $endDoW; } @@ -127,8 +127,8 @@ private static function decrementing(float $startDate, int $endDays, array $holi { // Adjust the start date if it falls over a weekend - $startDoW = weekday::funcWeekday($startDate, 3); - if (Weekday::funcWeekday($startDate, 3) >= 5) { + $startDoW = ZYXWeekDay::funcWeekDay($startDate, 3); + if (ZYXWeekDay::funcWeekDay($startDate, 3) >= 5) { $startDate += -$startDoW + 4; ++$endDays; } @@ -139,7 +139,7 @@ private static function decrementing(float $startDate, int $endDays, array $holi while ($endDays < 0) { --$endDate; // Adjust the calculated end date if it falls over a weekend - $endDow = Weekday::funcWeekday($endDate, 3); + $endDow = ZYXWeekDay::funcWeekDay($endDate, 3); if ($endDow >= 5) { $endDate += 4 - $endDow; } @@ -158,7 +158,7 @@ private static function decrementingArray(float $startDate, float $endDate, arra { $holidayCountedArray = $holidayDates = []; foreach ($holidayArray as $holidayDate) { - if (Weekday::funcWeekday($holidayDate, 3) < 5) { + if (ZYXWeekDay::funcWeekDay($holidayDate, 3) < 5) { $holidayDates[] = $holidayDate; } } @@ -171,7 +171,7 @@ private static function decrementingArray(float $startDate, float $endDate, arra } } // Adjust the calculated end date if it falls over a weekend - $endDoW = Weekday::funcWeekDay($endDate, 3); + $endDoW = ZYXWeekDay::funcWeekDay($endDate, 3); if ($endDoW >= 5) { $endDate += -$endDoW + 4; } diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXYearFrac.php similarity index 97% rename from src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php rename to src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXYearFrac.php index 2b4bd3e958..51546007c9 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Yearfrac.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXYearFrac.php @@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Shared\Date; -class Yearfrac +class ZYXYearFrac { /** * YEARFRAC. @@ -34,7 +34,7 @@ class Yearfrac * * @return float|string fraction of the year, or a string containing an error */ - public static function funcYearfrac($startDate, $endDate, $method = 0) + public static function funcYearFrac($startDate, $endDate, $method = 0) { try { $sDate = Helpers::getDateValue($startDate); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateValueTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateValueTest.php index f5aab0ddc6..bd5d22fefe 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateValueTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateValueTest.php @@ -4,7 +4,7 @@ use DateTimeImmutable; use DateTimeInterface; -use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\DateValue; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\ZYXDateValue; class DateValueTest extends AllSetupTeardown { @@ -26,7 +26,7 @@ public function testDATEVALUE($expectedResult, string $dateValue): void if (is_string($expectedResult)) { $replYMD = str_replace('Y', date('Y'), $expectedResult); if ($replYMD !== $expectedResult) { - $expectedResult = Datevalue::funcDateValue($replYMD); + $expectedResult = ZYXDateValue::funcDateValue($replYMD); } } $this->sheet->getCell("A$row")->setValue("=DATEVALUE($dateValue)"); @@ -46,7 +46,7 @@ public function testDATEVALUEtoUnixTimestamp(): void { self::setUnixReturn(); - $result = Datevalue::funcDateValue('2012-1-31'); + $result = ZYXDateValue::funcDateValue('2012-1-31'); self::assertEquals(1327968000, $result); self::assertEqualsWithDelta(1327968000, $result, 1E-8); } @@ -55,7 +55,7 @@ public function testDATEVALUEtoDateTimeObject(): void { self::setObjectReturn(); - $result = Datevalue::funcDateValue('2012-1-31'); + $result = ZYXDateValue::funcDateValue('2012-1-31'); // Must return an object... self::assertIsObject($result); // ... of the correct type @@ -67,9 +67,9 @@ public function testDATEVALUEtoDateTimeObject(): void public function testDATEVALUEwith1904Calendar(): void { self::setMac1904(); - self::assertEquals(5428, Datevalue::funcDateValue('1918-11-11')); - self::assertEquals(0, Datevalue::funcDateValue('1904-01-01')); - self::assertEquals('#VALUE!', Datevalue::funcDateValue('1903-12-31')); - self::assertEquals('#VALUE!', Datevalue::funcDateValue('1900-02-29')); + self::assertEquals(5428, ZYXDateValue::funcDateValue('1918-11-11')); + self::assertEquals(0, ZYXDateValue::funcDateValue('1904-01-01')); + self::assertEquals('#VALUE!', ZYXDateValue::funcDateValue('1903-12-31')); + self::assertEquals('#VALUE!', ZYXDateValue::funcDateValue('1900-02-29')); } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EDateTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EDateTest.php index 30bba2336d..a2713330a0 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EDateTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EDateTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Edate; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\ZYXEDate; class EDateTest extends AllSetupTeardown { @@ -29,7 +29,7 @@ public function testEDATEtoUnixTimestamp(): void { self::setUnixReturn(); - $result = Edate::funcEdate('2012-1-26', -1); + $result = ZYXEDate::funcEDate('2012-1-26', -1); self::assertEquals(1324857600, $result); self::assertEqualsWithDelta(1324857600, $result, 1E-8); } @@ -38,7 +38,7 @@ public function testEDATEtoDateTimeObject(): void { self::setObjectReturn(); - $result = Edate::funcEdate('2012-1-26', -1); + $result = ZYXEDate::funcEDate('2012-1-26', -1); // Must return an object... self::assertIsObject($result); // ... of the correct type diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EoMonthTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EoMonthTest.php index ae1a4a9ef1..9bbbb8197f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EoMonthTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EoMonthTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Eomonth; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\ZYXEoMonth; class EoMonthTest extends AllSetupTeardown { @@ -29,7 +29,7 @@ public function testEOMONTHtoUnixTimestamp(): void { self::setUnixReturn(); - $result = Eomonth::funcEomonth('2012-1-26', -1); + $result = ZYXEoMonth::funcEomonth('2012-1-26', -1); self::assertEquals(1325289600, $result); } @@ -37,7 +37,7 @@ public function testEOMONTHtoDateTimeObject(): void { self::setObjectReturn(); - $result = Eomonth::funcEomonth('2012-1-26', -1); + $result = ZYXEoMonth::funcEomonth('2012-1-26', -1); // Must return an object... self::assertIsObject($result); // ... of the correct type diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NetworkDaysTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NetworkDaysTest.php index d14487c545..fb8b94c016 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NetworkDaysTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NetworkDaysTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Networkdays; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\ZYXNetworkDays; class NetworkDaysTest extends AllSetupTeardown { @@ -13,7 +13,7 @@ class NetworkDaysTest extends AllSetupTeardown */ public function testNETWORKDAYS($expectedResult, ...$args): void { - $result = Networkdays::funcNetworkdays(...$args); + $result = ZYXNetworkDays::funcNetworkDays(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-8); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeValueTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeValueTest.php index aec9dfda80..6dc25e46be 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeValueTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeValueTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Timevalue; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\ZYXTimeValue; class TimeValueTest extends AllSetupTeardown { @@ -31,7 +31,7 @@ public function testTIMEVALUEtoUnixTimestamp(): void { self::setUnixReturn(); - $result = Timevalue::funcTimevalue('7:30:20'); + $result = ZYXTimeValue::funcTimeValue('7:30:20'); self::assertEquals(23420, $result); self::assertEqualsWithDelta(23420, $result, 1E-8); } @@ -40,7 +40,7 @@ public function testTIMEVALUEtoDateTimeObject(): void { self::setObjectReturn(); - $result = Timevalue::funcTimevalue('7:30:20'); + $result = ZYXTimeValue::funcTimeValue('7:30:20'); // Must return an object... self::assertIsObject($result); // ... of the correct type diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekDayTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekDayTest.php index 7303c8d18b..6b48b1b639 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekDayTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekDayTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Weekday; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\ZYXWeekday; class WeekDayTest extends AllSetupTeardown { @@ -28,8 +28,8 @@ public function providerWEEKDAY() public function testWEEKDAYwith1904Calendar(): void { self::setMac1904(); - self::assertEquals(7, Weekday::funcWeekday('1904-01-02')); - self::assertEquals(6, Weekday::funcWeekday('1904-01-01')); - self::assertEquals(6, Weekday::funcWeekday(null)); + self::assertEquals(7, ZYXWeekday::funcWeekDay('1904-01-02')); + self::assertEquals(6, ZYXWeekday::funcWeekDay('1904-01-01')); + self::assertEquals(6, ZYXWeekday::funcWeekDay(null)); } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearFracTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearFracTest.php index 177d7316b7..db759ae03d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearFracTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearFracTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\YearFrac; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\ZYXYearFrac; class YearFracTest extends AllSetupTeardown { @@ -13,7 +13,7 @@ class YearFracTest extends AllSetupTeardown */ public function testYEARFRAC($expectedResult, ...$args): void { - $result = YearFrac::funcYearfrac(...$args); + $result = ZYXYearFrac::funcYearFrac(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-8); } From c1f5376904331e33726940bb81de7525d527e08f Mon Sep 17 00:00:00 2001 From: Owen Leibman Date: Fri, 19 Mar 2021 17:13:27 -0700 Subject: [PATCH 11/12] Multiple Class Renames - Part 2 of 2 I can but hope. --- .../Calculation/Calculation.php | 20 ++++++++--------- src/PhpSpreadsheet/Calculation/DateTime.php | 20 ++++++++--------- .../{ZYXDateValue.php => DateValue.php} | 2 +- .../DateTimeExcel/{ZYXEDate.php => EDate.php} | 2 +- .../{ZYXEoMonth.php => EoMonth.php} | 2 +- .../Calculation/DateTimeExcel/Helpers.php | 4 ++-- .../{ZYXIsoWeekNum.php => IsoWeekNum.php} | 2 +- .../{ZYXNetworkDays.php => NetworkDays.php} | 8 +++---- .../{ZYXTimeValue.php => TimeValue.php} | 2 +- .../{ZYXWeekDay.php => WeekDay.php} | 2 +- .../{ZYXWeekNum.php => WeekNum.php} | 2 +- .../{ZYXWorkDay.php => WorkDay.php} | 22 +++++++++---------- .../{ZYXYearFrac.php => YearFrac.php} | 2 +- .../Functions/DateTime/DateValueTest.php | 16 +++++++------- .../Functions/DateTime/EDateTest.php | 6 ++--- .../Functions/DateTime/EoMonthTest.php | 6 ++--- .../Functions/DateTime/NetworkDaysTest.php | 4 ++-- .../Functions/DateTime/TimeValueTest.php | 6 ++--- .../Functions/DateTime/WeekDayTest.php | 8 +++---- .../Functions/DateTime/YearFracTest.php | 4 ++-- 20 files changed, 70 insertions(+), 70 deletions(-) rename src/PhpSpreadsheet/Calculation/DateTimeExcel/{ZYXDateValue.php => DateValue.php} (99%) rename src/PhpSpreadsheet/Calculation/DateTimeExcel/{ZYXEDate.php => EDate.php} (99%) rename src/PhpSpreadsheet/Calculation/DateTimeExcel/{ZYXEoMonth.php => EoMonth.php} (99%) rename src/PhpSpreadsheet/Calculation/DateTimeExcel/{ZYXIsoWeekNum.php => IsoWeekNum.php} (98%) rename src/PhpSpreadsheet/Calculation/DateTimeExcel/{ZYXNetworkDays.php => NetworkDays.php} (92%) rename src/PhpSpreadsheet/Calculation/DateTimeExcel/{ZYXTimeValue.php => TimeValue.php} (99%) rename src/PhpSpreadsheet/Calculation/DateTimeExcel/{ZYXWeekDay.php => WeekDay.php} (99%) rename src/PhpSpreadsheet/Calculation/DateTimeExcel/{ZYXWeekNum.php => WeekNum.php} (99%) rename src/PhpSpreadsheet/Calculation/DateTimeExcel/{ZYXWorkDay.php => WorkDay.php} (90%) rename src/PhpSpreadsheet/Calculation/DateTimeExcel/{ZYXYearFrac.php => YearFrac.php} (99%) diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 01e8f5f020..10e642cc8c 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -764,7 +764,7 @@ class Calculation ], 'DATEVALUE' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\ZYXDateValue::class, 'funcDateValue'], + 'functionCall' => [DateTimeExcel\DateValue::class, 'funcDateValue'], 'argumentCount' => '1', ], 'DAVERAGE' => [ @@ -919,7 +919,7 @@ class Calculation ], 'EDATE' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\ZYXEDate::class, 'funcEDate'], + 'functionCall' => [DateTimeExcel\EDate::class, 'funcEDate'], 'argumentCount' => '2', ], 'EFFECT' => [ @@ -934,7 +934,7 @@ class Calculation ], 'EOMONTH' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\ZYXEoMonth::class, 'funcEoMonth'], + 'functionCall' => [DateTimeExcel\EoMonth::class, 'funcEoMonth'], 'argumentCount' => '2', ], 'ERF' => [ @@ -1500,7 +1500,7 @@ class Calculation ], 'ISOWEEKNUM' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\ZYXIsoWeekNum::class, 'funcIsoWeekNum'], + 'functionCall' => [DateTimeExcel\IsoWeekNum::class, 'funcIsoWeekNum'], 'argumentCount' => '1', ], 'ISPMT' => [ @@ -1760,7 +1760,7 @@ class Calculation ], 'NETWORKDAYS' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\ZYXNetworkDays::class, 'funcNetworkDays'], + 'functionCall' => [DateTimeExcel\NetworkDays::class, 'funcNetworkDays'], 'argumentCount' => '2-3', ], 'NETWORKDAYS.INTL' => [ @@ -2424,7 +2424,7 @@ class Calculation ], 'TIMEVALUE' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\ZYXTimeValue::class, 'funcTimeValue'], + 'functionCall' => [DateTimeExcel\TimeValue::class, 'funcTimeValue'], 'argumentCount' => '1', ], 'TINV' => [ @@ -2569,12 +2569,12 @@ class Calculation ], 'WEEKDAY' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\ZYXWeekDay::class, 'funcWeekDay'], + 'functionCall' => [DateTimeExcel\WeekDay::class, 'funcWeekDay'], 'argumentCount' => '1,2', ], 'WEEKNUM' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\ZYXWeekNum::class, 'funcWeekNum'], + 'functionCall' => [DateTimeExcel\WeekNum::class, 'funcWeekNum'], 'argumentCount' => '1,2', ], 'WEIBULL' => [ @@ -2589,7 +2589,7 @@ class Calculation ], 'WORKDAY' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\ZYXWorkDay::class, 'funcWorkDay'], + 'functionCall' => [DateTimeExcel\WorkDay::class, 'funcWorkDay'], 'argumentCount' => '2-3', ], 'WORKDAY.INTL' => [ @@ -2629,7 +2629,7 @@ class Calculation ], 'YEARFRAC' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [DateTimeExcel\ZYXYearFrac::class, 'funcYearFrac'], + 'functionCall' => [DateTimeExcel\YearFrac::class, 'funcYearFrac'], 'argumentCount' => '2,3', ], 'YIELD' => [ diff --git a/src/PhpSpreadsheet/Calculation/DateTime.php b/src/PhpSpreadsheet/Calculation/DateTime.php index bd32b98394..712ccfcbd0 100644 --- a/src/PhpSpreadsheet/Calculation/DateTime.php +++ b/src/PhpSpreadsheet/Calculation/DateTime.php @@ -200,7 +200,7 @@ public static function TIME($hour = 0, $minute = 0, $second = 0) */ public static function DATEVALUE($dateValue = 1) { - return DateTimeExcel\ZYXDateValue::funcDateValue($dateValue); + return DateTimeExcel\DateValue::funcDateValue($dateValue); } /** @@ -228,7 +228,7 @@ public static function DATEVALUE($dateValue = 1) */ public static function TIMEVALUE($timeValue) { - return DateTimeExcel\ZYXTimeValue::funcTimeValue($timeValue); + return DateTimeExcel\TimeValue::funcTimeValue($timeValue); } /** @@ -336,7 +336,7 @@ public static function DAYS360($startDate = 0, $endDate = 0, $method = false) */ public static function YEARFRAC($startDate = 0, $endDate = 0, $method = 0) { - return DateTimeExcel\ZYXYearFrac::funcYearFrac($startDate, $endDate, $method); + return DateTimeExcel\YearFrac::funcYearFrac($startDate, $endDate, $method); } /** @@ -361,7 +361,7 @@ public static function YEARFRAC($startDate = 0, $endDate = 0, $method = 0) */ public static function NETWORKDAYS($startDate, $endDate, ...$dateArgs) { - return DateTimeExcel\ZYXNetworkDays::funcNetworkDays($startDate, $endDate, ...$dateArgs); + return DateTimeExcel\NetworkDays::funcNetworkDays($startDate, $endDate, ...$dateArgs); } /** @@ -388,7 +388,7 @@ public static function NETWORKDAYS($startDate, $endDate, ...$dateArgs) */ public static function WORKDAY($startDate, $endDays, ...$dateArgs) { - return DateTimeExcel\ZYXWorkDay::funcWorkDay($startDate, $endDays, ...$dateArgs); + return DateTimeExcel\WorkDay::funcWorkDay($startDate, $endDays, ...$dateArgs); } /** @@ -434,7 +434,7 @@ public static function DAYOFMONTH($dateValue = 1) */ public static function WEEKDAY($dateValue = 1, $style = 1) { - return DateTimeExcel\ZYXWeekDay::funcWeekDay($dateValue, $style); + return DateTimeExcel\WeekDay::funcWeekDay($dateValue, $style); } const STARTWEEK_SUNDAY = 1; @@ -500,7 +500,7 @@ public static function WEEKDAY($dateValue = 1, $style = 1) */ public static function WEEKNUM($dateValue = 1, $method = self::STARTWEEK_SUNDAY) { - return DateTimeExcel\ZYXWeekNum::funcWeekNum($dateValue, $method); + return DateTimeExcel\WeekNum::funcWeekNum($dateValue, $method); } /** @@ -520,7 +520,7 @@ public static function WEEKNUM($dateValue = 1, $method = self::STARTWEEK_SUNDAY) */ public static function ISOWEEKNUM($dateValue = 1) { - return DateTimeExcel\ZYXIsoweekNum::funcIsoWeekNum($dateValue); + return DateTimeExcel\IsoweekNum::funcIsoWeekNum($dateValue); } /** @@ -652,7 +652,7 @@ public static function SECOND($timeValue = 0) */ public static function EDATE($dateValue = 1, $adjustmentMonths = 0) { - return DateTimeExcel\ZYXEDate::funcEDate($dateValue, $adjustmentMonths); + return DateTimeExcel\EDate::funcEDate($dateValue, $adjustmentMonths); } /** @@ -678,6 +678,6 @@ public static function EDATE($dateValue = 1, $adjustmentMonths = 0) */ public static function EOMONTH($dateValue = 1, $adjustmentMonths = 0) { - return DateTimeExcel\ZYXEoMonth::funcEoMonth($dateValue, $adjustmentMonths); + return DateTimeExcel\EoMonth::funcEoMonth($dateValue, $adjustmentMonths); } } diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXDateValue.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/DateValue.php similarity index 99% rename from src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXDateValue.php rename to src/PhpSpreadsheet/Calculation/DateTimeExcel/DateValue.php index 97f7726173..3c15d06a04 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXDateValue.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/DateValue.php @@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Shared\Date; -class ZYXDateValue +class DateValue { /** * DATEVALUE. diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXEDate.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/EDate.php similarity index 99% rename from src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXEDate.php rename to src/PhpSpreadsheet/Calculation/DateTimeExcel/EDate.php index c04a58e191..43af694f07 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXEDate.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/EDate.php @@ -5,7 +5,7 @@ use Exception; use PhpOffice\PhpSpreadsheet\Shared\Date; -class ZYXEDate +class EDate { /** * EDATE. diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXEoMonth.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/EoMonth.php similarity index 99% rename from src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXEoMonth.php rename to src/PhpSpreadsheet/Calculation/DateTimeExcel/EoMonth.php index f178bca58c..6b39a60901 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXEoMonth.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/EoMonth.php @@ -5,7 +5,7 @@ use Exception; use PhpOffice\PhpSpreadsheet\Shared\Date; -class ZYXEoMonth +class EoMonth { /** * EOMONTH. diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php index 2c0fe8d6b6..a88ef1f580 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php @@ -44,7 +44,7 @@ public static function getDateValue($dateValue, bool $allowBool = true) if (!is_numeric($dateValue)) { $saveReturnDateType = Functions::getReturnDateType(); Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - $dateValue = ZYXDateValue::funcDateValue($dateValue); + $dateValue = DateValue::funcDateValue($dateValue); Functions::setReturnDateType($saveReturnDateType); if (!is_numeric($dateValue)) { throw new Exception(Functions::VALUE()); @@ -84,7 +84,7 @@ public static function getTimeValue($timeValue) { $saveReturnDateType = Functions::getReturnDateType(); Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); - $timeValue = ZYXTimeValue::funcTimeValue($timeValue); + $timeValue = TimeValue::funcTimeValue($timeValue); Functions::setReturnDateType($saveReturnDateType); return $timeValue; diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXIsoWeekNum.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/IsoWeekNum.php similarity index 98% rename from src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXIsoWeekNum.php rename to src/PhpSpreadsheet/Calculation/DateTimeExcel/IsoWeekNum.php index ed442d6b6f..41959d9aa4 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXIsoWeekNum.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/IsoWeekNum.php @@ -5,7 +5,7 @@ use Exception; use PhpOffice\PhpSpreadsheet\Shared\Date; -class ZYXIsoWeekNum +class IsoWeekNum { /** * ISOWEEKNUM. diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXNetworkDays.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/NetworkDays.php similarity index 92% rename from src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXNetworkDays.php rename to src/PhpSpreadsheet/Calculation/DateTimeExcel/NetworkDays.php index fdbbbc31aa..c700c83479 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXNetworkDays.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/NetworkDays.php @@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Shared\Date; -class ZYXNetworkDays +class NetworkDays { /** * NETWORKDAYS. @@ -55,7 +55,7 @@ public static function funcNetworkDays($startDate, $endDate, ...$dateArgs) $holidayCountedArray = []; foreach ($holidayArray as $holidayDate) { if (($holidayDate >= $startDate) && ($holidayDate <= $endDate)) { - if ((ZYXWeekDay::funcWeekDay($holidayDate, 2) < 6) && (!in_array($holidayDate, $holidayCountedArray))) { + if ((WeekDay::funcWeekDay($holidayDate, 2) < 6) && (!in_array($holidayDate, $holidayCountedArray))) { --$partWeekDays; $holidayCountedArray[] = $holidayDate; } @@ -67,7 +67,7 @@ public static function funcNetworkDays($startDate, $endDate, ...$dateArgs) private static function calcStartDow(float $startDate): int { - $startDow = 6 - (int) ZYXWeekDay::funcWeekDay($startDate, 2); + $startDow = 6 - (int) WeekDay::funcWeekDay($startDate, 2); if ($startDow < 0) { $startDow = 5; } @@ -77,7 +77,7 @@ private static function calcStartDow(float $startDate): int private static function calcEndDow(float $endDate): int { - $endDow = (int) ZYXWeekDay::funcWeekDay($endDate, 2); + $endDow = (int) WeekDay::funcWeekDay($endDate, 2); if ($endDow >= 6) { $endDow = 0; } diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXTimeValue.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/TimeValue.php similarity index 99% rename from src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXTimeValue.php rename to src/PhpSpreadsheet/Calculation/DateTimeExcel/TimeValue.php index 8dbbc3e4a0..2366b1d69f 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXTimeValue.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/TimeValue.php @@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Shared\Date; -class ZYXTimeValue +class TimeValue { /** * TIMEVALUE. diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXWeekDay.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/WeekDay.php similarity index 99% rename from src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXWeekDay.php rename to src/PhpSpreadsheet/Calculation/DateTimeExcel/WeekDay.php index cd2728dfa3..15811ee5f9 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXWeekDay.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/WeekDay.php @@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Shared\Date; -class ZYXWeekDay +class WeekDay { /** * WEEKDAY. diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXWeekNum.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/WeekNum.php similarity index 99% rename from src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXWeekNum.php rename to src/PhpSpreadsheet/Calculation/DateTimeExcel/WeekNum.php index 06861f134f..81f2b03159 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXWeekNum.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/WeekNum.php @@ -7,7 +7,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Shared\Date; -class ZYXWeekNum +class WeekNum { const STARTWEEK_SUNDAY = 1; const STARTWEEK_MONDAY = 2; diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXWorkDay.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/WorkDay.php similarity index 90% rename from src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXWorkDay.php rename to src/PhpSpreadsheet/Calculation/DateTimeExcel/WorkDay.php index 1badf5c3fd..f812624ebd 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXWorkDay.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/WorkDay.php @@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Shared\Date; -class ZYXWorkDay +class WorkDay { /** * WORKDAY. @@ -65,8 +65,8 @@ private static function incrementing(float $startDate, int $endDays, array $holi { // Adjust the start date if it falls over a weekend - $startDoW = ZYXWeekDay::funcWeekDay($startDate, 3); - if (ZYXWeekDay::funcWeekDay($startDate, 3) >= 5) { + $startDoW = WeekDay::funcWeekDay($startDate, 3); + if (WeekDay::funcWeekDay($startDate, 3) >= 5) { $startDate += 7 - $startDoW; --$endDays; } @@ -77,7 +77,7 @@ private static function incrementing(float $startDate, int $endDays, array $holi while ($endDays > 0) { ++$endDate; // Adjust the calculated end date if it falls over a weekend - $endDow = ZYXWeekDay::funcWeekDay($endDate, 3); + $endDow = WeekDay::funcWeekDay($endDate, 3); if ($endDow >= 5) { $endDate += 7 - $endDow; } @@ -96,7 +96,7 @@ private static function incrementingArray(float $startDate, float $endDate, arra { $holidayCountedArray = $holidayDates = []; foreach ($holidayArray as $holidayDate) { - if (ZYXWeekDay::funcWeekDay($holidayDate, 3) < 5) { + if (WeekDay::funcWeekDay($holidayDate, 3) < 5) { $holidayDates[] = $holidayDate; } } @@ -109,7 +109,7 @@ private static function incrementingArray(float $startDate, float $endDate, arra } } // Adjust the calculated end date if it falls over a weekend - $endDoW = ZYXWeekDay::funcWeekDay($endDate, 3); + $endDoW = WeekDay::funcWeekDay($endDate, 3); if ($endDoW >= 5) { $endDate += 7 - $endDoW; } @@ -127,8 +127,8 @@ private static function decrementing(float $startDate, int $endDays, array $holi { // Adjust the start date if it falls over a weekend - $startDoW = ZYXWeekDay::funcWeekDay($startDate, 3); - if (ZYXWeekDay::funcWeekDay($startDate, 3) >= 5) { + $startDoW = WeekDay::funcWeekDay($startDate, 3); + if (WeekDay::funcWeekDay($startDate, 3) >= 5) { $startDate += -$startDoW + 4; ++$endDays; } @@ -139,7 +139,7 @@ private static function decrementing(float $startDate, int $endDays, array $holi while ($endDays < 0) { --$endDate; // Adjust the calculated end date if it falls over a weekend - $endDow = ZYXWeekDay::funcWeekDay($endDate, 3); + $endDow = WeekDay::funcWeekDay($endDate, 3); if ($endDow >= 5) { $endDate += 4 - $endDow; } @@ -158,7 +158,7 @@ private static function decrementingArray(float $startDate, float $endDate, arra { $holidayCountedArray = $holidayDates = []; foreach ($holidayArray as $holidayDate) { - if (ZYXWeekDay::funcWeekDay($holidayDate, 3) < 5) { + if (WeekDay::funcWeekDay($holidayDate, 3) < 5) { $holidayDates[] = $holidayDate; } } @@ -171,7 +171,7 @@ private static function decrementingArray(float $startDate, float $endDate, arra } } // Adjust the calculated end date if it falls over a weekend - $endDoW = ZYXWeekDay::funcWeekDay($endDate, 3); + $endDoW = WeekDay::funcWeekDay($endDate, 3); if ($endDoW >= 5) { $endDate += -$endDoW + 4; } diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXYearFrac.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/YearFrac.php similarity index 99% rename from src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXYearFrac.php rename to src/PhpSpreadsheet/Calculation/DateTimeExcel/YearFrac.php index 51546007c9..4cd54ac0c0 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/ZYXYearFrac.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/YearFrac.php @@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Shared\Date; -class ZYXYearFrac +class YearFrac { /** * YEARFRAC. diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateValueTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateValueTest.php index bd5d22fefe..fc432bbef4 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateValueTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateValueTest.php @@ -4,7 +4,7 @@ use DateTimeImmutable; use DateTimeInterface; -use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\ZYXDateValue; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\DateValue; class DateValueTest extends AllSetupTeardown { @@ -26,7 +26,7 @@ public function testDATEVALUE($expectedResult, string $dateValue): void if (is_string($expectedResult)) { $replYMD = str_replace('Y', date('Y'), $expectedResult); if ($replYMD !== $expectedResult) { - $expectedResult = ZYXDateValue::funcDateValue($replYMD); + $expectedResult = DateValue::funcDateValue($replYMD); } } $this->sheet->getCell("A$row")->setValue("=DATEVALUE($dateValue)"); @@ -46,7 +46,7 @@ public function testDATEVALUEtoUnixTimestamp(): void { self::setUnixReturn(); - $result = ZYXDateValue::funcDateValue('2012-1-31'); + $result = DateValue::funcDateValue('2012-1-31'); self::assertEquals(1327968000, $result); self::assertEqualsWithDelta(1327968000, $result, 1E-8); } @@ -55,7 +55,7 @@ public function testDATEVALUEtoDateTimeObject(): void { self::setObjectReturn(); - $result = ZYXDateValue::funcDateValue('2012-1-31'); + $result = DateValue::funcDateValue('2012-1-31'); // Must return an object... self::assertIsObject($result); // ... of the correct type @@ -67,9 +67,9 @@ public function testDATEVALUEtoDateTimeObject(): void public function testDATEVALUEwith1904Calendar(): void { self::setMac1904(); - self::assertEquals(5428, ZYXDateValue::funcDateValue('1918-11-11')); - self::assertEquals(0, ZYXDateValue::funcDateValue('1904-01-01')); - self::assertEquals('#VALUE!', ZYXDateValue::funcDateValue('1903-12-31')); - self::assertEquals('#VALUE!', ZYXDateValue::funcDateValue('1900-02-29')); + self::assertEquals(5428, DateValue::funcDateValue('1918-11-11')); + self::assertEquals(0, DateValue::funcDateValue('1904-01-01')); + self::assertEquals('#VALUE!', DateValue::funcDateValue('1903-12-31')); + self::assertEquals('#VALUE!', DateValue::funcDateValue('1900-02-29')); } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EDateTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EDateTest.php index a2713330a0..384e1aece8 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EDateTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EDateTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\ZYXEDate; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\EDate; class EDateTest extends AllSetupTeardown { @@ -29,7 +29,7 @@ public function testEDATEtoUnixTimestamp(): void { self::setUnixReturn(); - $result = ZYXEDate::funcEDate('2012-1-26', -1); + $result = EDate::funcEDate('2012-1-26', -1); self::assertEquals(1324857600, $result); self::assertEqualsWithDelta(1324857600, $result, 1E-8); } @@ -38,7 +38,7 @@ public function testEDATEtoDateTimeObject(): void { self::setObjectReturn(); - $result = ZYXEDate::funcEDate('2012-1-26', -1); + $result = EDate::funcEDate('2012-1-26', -1); // Must return an object... self::assertIsObject($result); // ... of the correct type diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EoMonthTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EoMonthTest.php index 9bbbb8197f..1af81c9fa6 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EoMonthTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EoMonthTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\ZYXEoMonth; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\EoMonth; class EoMonthTest extends AllSetupTeardown { @@ -29,7 +29,7 @@ public function testEOMONTHtoUnixTimestamp(): void { self::setUnixReturn(); - $result = ZYXEoMonth::funcEomonth('2012-1-26', -1); + $result = EoMonth::funcEomonth('2012-1-26', -1); self::assertEquals(1325289600, $result); } @@ -37,7 +37,7 @@ public function testEOMONTHtoDateTimeObject(): void { self::setObjectReturn(); - $result = ZYXEoMonth::funcEomonth('2012-1-26', -1); + $result = EoMonth::funcEomonth('2012-1-26', -1); // Must return an object... self::assertIsObject($result); // ... of the correct type diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NetworkDaysTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NetworkDaysTest.php index fb8b94c016..8c6fd36a77 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NetworkDaysTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NetworkDaysTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\ZYXNetworkDays; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\NetworkDays; class NetworkDaysTest extends AllSetupTeardown { @@ -13,7 +13,7 @@ class NetworkDaysTest extends AllSetupTeardown */ public function testNETWORKDAYS($expectedResult, ...$args): void { - $result = ZYXNetworkDays::funcNetworkDays(...$args); + $result = NetworkDays::funcNetworkDays(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-8); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeValueTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeValueTest.php index 6dc25e46be..f144c6f276 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeValueTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeValueTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\ZYXTimeValue; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\TimeValue; class TimeValueTest extends AllSetupTeardown { @@ -31,7 +31,7 @@ public function testTIMEVALUEtoUnixTimestamp(): void { self::setUnixReturn(); - $result = ZYXTimeValue::funcTimeValue('7:30:20'); + $result = TimeValue::funcTimeValue('7:30:20'); self::assertEquals(23420, $result); self::assertEqualsWithDelta(23420, $result, 1E-8); } @@ -40,7 +40,7 @@ public function testTIMEVALUEtoDateTimeObject(): void { self::setObjectReturn(); - $result = ZYXTimeValue::funcTimeValue('7:30:20'); + $result = TimeValue::funcTimeValue('7:30:20'); // Must return an object... self::assertIsObject($result); // ... of the correct type diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekDayTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekDayTest.php index 6b48b1b639..f1bc51f301 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekDayTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekDayTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\ZYXWeekday; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Weekday; class WeekDayTest extends AllSetupTeardown { @@ -28,8 +28,8 @@ public function providerWEEKDAY() public function testWEEKDAYwith1904Calendar(): void { self::setMac1904(); - self::assertEquals(7, ZYXWeekday::funcWeekDay('1904-01-02')); - self::assertEquals(6, ZYXWeekday::funcWeekDay('1904-01-01')); - self::assertEquals(6, ZYXWeekday::funcWeekDay(null)); + self::assertEquals(7, Weekday::funcWeekDay('1904-01-02')); + self::assertEquals(6, Weekday::funcWeekDay('1904-01-01')); + self::assertEquals(6, Weekday::funcWeekDay(null)); } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearFracTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearFracTest.php index db759ae03d..d831863472 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearFracTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearFracTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\ZYXYearFrac; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\YearFrac; class YearFracTest extends AllSetupTeardown { @@ -13,7 +13,7 @@ class YearFracTest extends AllSetupTeardown */ public function testYEARFRAC($expectedResult, ...$args): void { - $result = ZYXYearFrac::funcYearFrac(...$args); + $result = YearFrac::funcYearFrac(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-8); } From d020b9351df8407b42c84405576f443447c588c1 Mon Sep 17 00:00:00 2001 From: Owen Leibman Date: Sat, 20 Mar 2021 20:37:58 -0700 Subject: [PATCH 12/12] Deprecate Now-unused Constants, Fix Yearfrac bug, Change 3 Tests Per discussion with Mark Baker, deprecate constants remaining in DateTime class. Add new DateTime/Constants class, initially populated with constants used in Weeknum. MS has another inconsistency with how it handles null cells in Yearfrac. Change PhpSpreadsheet to behave compatibly with this bug. I have modified YearFrac, WorkDay, and NetworkDays tests to be more to my liking. Many tests added to YearFrac because of the bug above. Only minor modifications to the existing tests for the others. --- src/PhpSpreadsheet/Calculation/DateTime.php | 143 ++++++++++++++++++ .../Calculation/DateTimeExcel/Constants.php | 37 +++++ .../Calculation/DateTimeExcel/Days.php | 5 +- .../Calculation/DateTimeExcel/Helpers.php | 3 +- .../Calculation/DateTimeExcel/WeekNum.php | 46 +----- .../Calculation/DateTimeExcel/YearFrac.php | 25 ++- .../Functions/DateTime/DaysTest.php | 8 + .../Functions/DateTime/NetworkDaysTest.php | 38 ++++- .../Functions/DateTime/WorkDayTest.php | 38 ++++- .../Functions/DateTime/YearFracTest.php | 30 +++- .../data/Calculation/DateTime/NETWORKDAYS.php | 19 +-- tests/data/Calculation/DateTime/WORKDAY.php | 10 +- tests/data/Calculation/DateTime/YEARFRAC.php | 49 ++++++ 13 files changed, 377 insertions(+), 74 deletions(-) create mode 100644 src/PhpSpreadsheet/Calculation/DateTimeExcel/Constants.php diff --git a/src/PhpSpreadsheet/Calculation/DateTime.php b/src/PhpSpreadsheet/Calculation/DateTime.php index 712ccfcbd0..744d958976 100644 --- a/src/PhpSpreadsheet/Calculation/DateTime.php +++ b/src/PhpSpreadsheet/Calculation/DateTime.php @@ -437,23 +437,166 @@ public static function WEEKDAY($dateValue = 1, $style = 1) return DateTimeExcel\WeekDay::funcWeekDay($dateValue, $style); } + /** + * STARTWEEK_SUNDAY. + * + * @Deprecated 2.0.0 + * + * @see Use DateTimeExcel\Constants\STARTWEEK_SUNDAY instead + */ const STARTWEEK_SUNDAY = 1; + + /** + * STARTWEEK_MONDAY. + * + * @Deprecated 2.0.0 + * + * @see Use DateTimeExcel\Constants\STARTWEEK_MONDAY instead + */ const STARTWEEK_MONDAY = 2; + + /** + * STARTWEEK_MONDAY_ALT. + * + * @Deprecated 2.0.0 + * + * @see Use DateTimeExcel\Constants\STARTWEEK_MONDAY_ALT instead + */ const STARTWEEK_MONDAY_ALT = 11; + + /** + * STARTWEEK_TUESDAY. + * + * @Deprecated 2.0.0 + * + * @see Use DateTimeExcel\Constants\STARTWEEK_TUESDAY instead + */ const STARTWEEK_TUESDAY = 12; + + /** + * STARTWEEK_WEDNESDAY. + * + * @Deprecated 2.0.0 + * + * @see Use DateTimeExcel\Constants\STARTWEEK_WEDNESDAY instead + */ const STARTWEEK_WEDNESDAY = 13; + + /** + * STARTWEEK_THURSDAY. + * + * @Deprecated 2.0.0 + * + * @see Use DateTimeExcel\Constants\STARTWEEK_THURSDAY instead + */ const STARTWEEK_THURSDAY = 14; + + /** + * STARTWEEK_FRIDAY. + * + * @Deprecated 2.0.0 + * + * @see Use DateTimeExcel\Constants\STARTWEEK_FRIDAY instead + */ const STARTWEEK_FRIDAY = 15; + + /** + * STARTWEEK_SATURDAY. + * + * @Deprecated 2.0.0 + * + * @see Use DateTimeExcel\Constants\STARTWEEK_SATURDAY instead + */ const STARTWEEK_SATURDAY = 16; + + /** + * STARTWEEK_SUNDAY_ALT. + * + * @Deprecated 2.0.0 + * + * @see Use DateTimeExcel\Constants\STARTWEEK_SUNDAY_ALT instead + */ const STARTWEEK_SUNDAY_ALT = 17; + + /** + * DOW_SUNDAY. + * + * @Deprecated 2.0.0 + * + * @see Use DateTimeExcel\Constants\DOW_SUNDAY instead + */ const DOW_SUNDAY = 1; + + /** + * DOW_MONDAY. + * + * @Deprecated 2.0.0 + * + * @see Use DateTimeExcel\Constants\DOW_MONDAY instead + */ const DOW_MONDAY = 2; + + /** + * DOW_TUESDAY. + * + * @Deprecated 2.0.0 + * + * @see Use DateTimeExcel\Constants\DOW_TUESDAY instead + */ const DOW_TUESDAY = 3; + + /** + * DOW_WEDNESDAY. + * + * @Deprecated 2.0.0 + * + * @see Use DateTimeExcel\Constants\DOW_WEDNESDAY instead + */ const DOW_WEDNESDAY = 4; + + /** + * DOW_THURSDAY. + * + * @Deprecated 2.0.0 + * + * @see Use DateTimeExcel\Constants\DOW_THURSDAY instead + */ const DOW_THURSDAY = 5; + + /** + * DOW_FRIDAY. + * + * @Deprecated 2.0.0 + * + * @see Use DateTimeExcel\Constants\DOW_FRIDAY instead + */ const DOW_FRIDAY = 6; + + /** + * DOW_SATURDAY. + * + * @Deprecated 2.0.0 + * + * @see Use DateTimeExcel\Constants\DOW_SATURDAY instead + */ const DOW_SATURDAY = 7; + + /** + * STARTWEEK_MONDAY_ISO. + * + * @Deprecated 2.0.0 + * + * @see Use DateTimeExcel\Constants\STARTWEEK_MONDAY_ISO instead + */ const STARTWEEK_MONDAY_ISO = 21; + + /** + * METHODARR. + * + * @Deprecated 2.0.0 + * + * @see Use DateTimeExcel\Constants\METHODARR instead + */ const METHODARR = [ self::STARTWEEK_SUNDAY => self::DOW_SUNDAY, self::DOW_MONDAY, diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Constants.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Constants.php new file mode 100644 index 0000000000..da1b81c10b --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Constants.php @@ -0,0 +1,37 @@ + self::DOW_SUNDAY, + self::DOW_MONDAY, + self::STARTWEEK_MONDAY_ALT => self::DOW_MONDAY, + self::DOW_TUESDAY, + self::DOW_WEDNESDAY, + self::DOW_THURSDAY, + self::DOW_FRIDAY, + self::DOW_SATURDAY, + self::DOW_SUNDAY, + self::STARTWEEK_MONDAY_ISO => self::STARTWEEK_MONDAY_ISO, + ]; +} diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days.php index c8083a61ba..2c814e8e76 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Days.php @@ -37,16 +37,15 @@ public static function funcDays($endDate, $startDate) $PHPStartDateObject = Date::excelToDateTimeObject($startDate); $PHPEndDateObject = Date::excelToDateTimeObject($endDate); + $days = Functions::VALUE(); $diff = $PHPStartDateObject->diff($PHPEndDateObject); if ($diff !== false && !is_bool($diff->days)) { $days = $diff->days; if ($diff->invert) { $days = -$days; } - - return $days; } - return Functions::VALUE(); + return $days; } } diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php index a88ef1f580..4830064297 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php @@ -3,7 +3,6 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel; use DateTime; -use DateTimeInterface; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Shared\Date; @@ -31,7 +30,7 @@ public static function isLeapYear($year) */ public static function getDateValue($dateValue, bool $allowBool = true) { - if ($dateValue instanceof DateTimeInterface) { + if (is_object($dateValue)) { $retval = Date::PHPToExcel($dateValue); if (is_bool($retval)) { throw new Exception(Functions::VALUE()); diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/WeekNum.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/WeekNum.php index 81f2b03159..1dd15edb9a 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/WeekNum.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/WeekNum.php @@ -9,36 +9,6 @@ class WeekNum { - const STARTWEEK_SUNDAY = 1; - const STARTWEEK_MONDAY = 2; - const STARTWEEK_MONDAY_ALT = 11; - const STARTWEEK_TUESDAY = 12; - const STARTWEEK_WEDNESDAY = 13; - const STARTWEEK_THURSDAY = 14; - const STARTWEEK_FRIDAY = 15; - const STARTWEEK_SATURDAY = 16; - const STARTWEEK_SUNDAY_ALT = 17; - const DOW_SUNDAY = 1; - const DOW_MONDAY = 2; - const DOW_TUESDAY = 3; - const DOW_WEDNESDAY = 4; - const DOW_THURSDAY = 5; - const DOW_FRIDAY = 6; - const DOW_SATURDAY = 7; - const STARTWEEK_MONDAY_ISO = 21; - const METHODARR = [ - self::STARTWEEK_SUNDAY => self::DOW_SUNDAY, - self::DOW_MONDAY, - self::STARTWEEK_MONDAY_ALT => self::DOW_MONDAY, - self::DOW_TUESDAY, - self::DOW_WEDNESDAY, - self::DOW_THURSDAY, - self::DOW_FRIDAY, - self::DOW_SATURDAY, - self::DOW_SUNDAY, - self::STARTWEEK_MONDAY_ISO => self::STARTWEEK_MONDAY_ISO, - ]; - /** * WEEKNUM. * @@ -68,14 +38,14 @@ class WeekNum * * @return int|string Week Number */ - public static function funcWeekNum($dateValue, $method = self::STARTWEEK_SUNDAY) + public static function funcWeekNum($dateValue, $method = Constants::STARTWEEK_SUNDAY) { $origDateValueNull = empty($dateValue); try { $method = self::validateMethod($method); if ($dateValue === null) { // boolean not allowed - $dateValue = (Date::getExcelCalendar() === DATE::CALENDAR_MAC_1904 || $method === self::DOW_SUNDAY) ? 0 : 1; + $dateValue = (Date::getExcelCalendar() === DATE::CALENDAR_MAC_1904 || $method === Constants::DOW_SUNDAY) ? 0 : 1; } $dateValue = self::validateDateValue($dateValue); if (!$dateValue && self::buggyWeekNum1900($method)) { @@ -88,7 +58,7 @@ public static function funcWeekNum($dateValue, $method = self::STARTWEEK_SUNDAY) // Execute function $PHPDateObject = Date::excelToDateTimeObject($dateValue); - if ($method == self::STARTWEEK_MONDAY_ISO) { + if ($method == Constants::STARTWEEK_MONDAY_ISO) { Helpers::silly1900($PHPDateObject); return (int) $PHPDateObject->format('W'); @@ -130,7 +100,7 @@ private static function validateDateValue($dateValue): float private static function validateMethod($method): int { if ($method === null) { - $method = self::STARTWEEK_SUNDAY; + $method = Constants::STARTWEEK_SUNDAY; } $method = Functions::flattenSingleValue($method); if (!is_numeric($method)) { @@ -138,23 +108,23 @@ private static function validateMethod($method): int } $method = (int) $method; - if (!array_key_exists($method, self::METHODARR)) { + if (!array_key_exists($method, Constants::METHODARR)) { throw new Exception(Functions::NAN()); } - $method = self::METHODARR[$method]; + $method = Constants::METHODARR[$method]; return $method; } private static function buggyWeekNum1900(int $method): bool { - return $method === self::DOW_SUNDAY && Date::getExcelCalendar() === Date::CALENDAR_WINDOWS_1900; + return $method === Constants::DOW_SUNDAY && Date::getExcelCalendar() === Date::CALENDAR_WINDOWS_1900; } private static function buggyWeekNum1904(int $method, bool $origNull, DateTime $dateObject): bool { // This appears to be another Excel bug. - return $method === self::DOW_SUNDAY && Date::getExcelCalendar() === Date::CALENDAR_MAC_1904 && !$origNull && $dateObject->format('Y-m-d') === '1904-01-01'; + return $method === Constants::DOW_SUNDAY && Date::getExcelCalendar() === Date::CALENDAR_MAC_1904 && !$origNull && $dateObject->format('Y-m-d') === '1904-01-01'; } } diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/YearFrac.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/YearFrac.php index 4cd54ac0c0..a99b1c7f36 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/YearFrac.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/YearFrac.php @@ -37,11 +37,13 @@ class YearFrac public static function funcYearFrac($startDate, $endDate, $method = 0) { try { + $method = (int) Helpers::validateNumericNull($method); $sDate = Helpers::getDateValue($startDate); $eDate = Helpers::getDateValue($endDate); + $sDate = self::excelBug($sDate, $startDate, $endDate, $method); + $eDate = self::excelBug($eDate, $endDate, $startDate, $method); $startDate = min($sDate, $eDate); $endDate = max($sDate, $eDate); - $method = (int) Helpers::validateNumericNull($method); } catch (Exception $e) { return $e->getMessage(); } @@ -62,6 +64,27 @@ public static function funcYearFrac($startDate, $endDate, $method = 0) return Functions::NAN(); } + /** + * Excel 1900 calendar treats date argument of null as 1900-01-00. Really. + * + * @param mixed $startDate + * @param mixed $endDate + */ + private static function excelBug(float $sDate, $startDate, $endDate, int $method): float + { + if (Functions::getCompatibilityMode() !== Functions::COMPATIBILITY_OPENOFFICE && Date::getExcelCalendar() !== Date::CALENDAR_MAC_1904) { + if ($endDate === null && $startDate !== null) { + if (Month::funcMonth($sDate) == 12 && Day::funcDay($sDate) === 31 && $method === 0) { + $sDate += 2; + } else { + ++$sDate; + } + } + } + + return $sDate; + } + private static function method1(float $startDate, float $endDate): float { $days = DateDif::funcDateDif($startDate, $endDate); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DaysTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DaysTest.php index e016d064b3..8b3ea39257 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DaysTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DaysTest.php @@ -4,6 +4,7 @@ use DateTime; use DateTimeImmutable; +use Exception; use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Days; class DaysTest extends AllSetupTeardown @@ -34,4 +35,11 @@ public function testObject(): void $obj2 = new DateTimeImmutable('2000-2-29'); self::assertSame(31, Days::funcDays($obj1, $obj2)); } + + public function testNonDateObject(): void + { + $obj1 = new Exception(); + $obj2 = new DateTimeImmutable('2000-2-29'); + self::assertSame('#VALUE!', Days::funcDays($obj1, $obj2)); + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NetworkDaysTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NetworkDaysTest.php index 8c6fd36a77..568c661c9a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NetworkDaysTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NetworkDaysTest.php @@ -2,19 +2,47 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\NetworkDays; - class NetworkDaysTest extends AllSetupTeardown { /** * @dataProvider providerNETWORKDAYS * * @param mixed $expectedResult + * @param mixed $arg1 + * @param mixed $arg2 */ - public function testNETWORKDAYS($expectedResult, ...$args): void + public function testNETWORKDAYS($expectedResult, $arg1 = 'omitted', $arg2 = 'omitted', ?array $arg3 = null): void { - $result = NetworkDays::funcNetworkDays(...$args); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); + $this->mightHaveException($expectedResult); + $sheet = $this->sheet; + if ($arg1 !== null) { + $sheet->getCell('A1')->setValue($arg1); + } + if ($arg2 !== null) { + $sheet->getCell('A2')->setValue($arg2); + } + $dateArray = []; + if (is_array($arg3)) { + if (array_key_exists(0, $arg3) && is_array($arg3[0])) { + $dateArray = $arg3[0]; + } else { + $dateArray = $arg3; + } + } + $dateIndex = 0; + foreach ($dateArray as $date) { + ++$dateIndex; + $sheet->getCell("C$dateIndex")->setValue($date); + } + $arrayArg = $dateIndex ? ", C1:C$dateIndex" : ''; + if ($arg1 === 'omitted') { + $sheet->getCell('B1')->setValue('=NETWORKDAYS()'); + } elseif ($arg2 === 'omitted') { + $sheet->getCell('B1')->setValue('=NETWORKDAYS(A1)'); + } else { + $sheet->getCell('B1')->setValue("=NETWORKDAYS(A1, A2$arrayArg)"); + } + self::assertEquals($expectedResult, $sheet->getCell('B1')->getCalculatedValue()); } public function providerNETWORKDAYS() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WorkDayTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WorkDayTest.php index 72c5aa52b4..ec2a5402a3 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WorkDayTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WorkDayTest.php @@ -2,19 +2,47 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTime; - class WorkDayTest extends AllSetupTeardown { /** * @dataProvider providerWORKDAY * * @param mixed $expectedResult + * @param mixed $arg1 + * @param mixed $arg2 */ - public function testWORKDAY($expectedResult, ...$args): void + public function testWORKDAY($expectedResult, $arg1 = 'omitted', $arg2 = 'omitted', ?array $arg3 = null): void { - $result = DateTime::WORKDAY(...$args); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); + $this->mightHaveException($expectedResult); + $sheet = $this->sheet; + if ($arg1 !== null) { + $sheet->getCell('A1')->setValue($arg1); + } + if ($arg2 !== null) { + $sheet->getCell('A2')->setValue($arg2); + } + $dateArray = []; + if (is_array($arg3)) { + if (array_key_exists(0, $arg3) && is_array($arg3[0])) { + $dateArray = $arg3[0]; + } else { + $dateArray = $arg3; + } + } + $dateIndex = 0; + foreach ($dateArray as $date) { + ++$dateIndex; + $sheet->getCell("C$dateIndex")->setValue($date); + } + $arrayArg = $dateIndex ? ", C1:C$dateIndex" : ''; + if ($arg1 === 'omitted') { + $sheet->getCell('B1')->setValue('=WORKDAY()'); + } elseif ($arg2 === 'omitted') { + $sheet->getCell('B1')->setValue('=WORKDAY(A1)'); + } else { + $sheet->getCell('B1')->setValue("=WORKDAY(A1, A2$arrayArg)"); + } + self::assertEquals($expectedResult, $sheet->getCell('B1')->getCalculatedValue()); } public function providerWORKDAY() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearFracTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearFracTest.php index d831863472..e6ac823a52 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearFracTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearFracTest.php @@ -2,19 +2,39 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime; -use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\YearFrac; - class YearFracTest extends AllSetupTeardown { /** * @dataProvider providerYEARFRAC * * @param mixed $expectedResult + * @param mixed $arg1 + * @param mixed $arg2 + * @param mixed $arg3 */ - public function testYEARFRAC($expectedResult, ...$args): void + public function testYEARFRAC($expectedResult, $arg1 = 'omitted', $arg2 = 'omitted', $arg3 = 'omitted'): void { - $result = YearFrac::funcYearFrac(...$args); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); + $this->mightHaveException($expectedResult); + $sheet = $this->sheet; + if ($arg1 !== null) { + $sheet->getCell('A1')->setValue($arg1); + } + if ($arg2 !== null) { + $sheet->getCell('A2')->setValue($arg2); + } + if ($arg3 !== null) { + $sheet->getCell('A3')->setValue($arg3); + } + if ($arg1 === 'omitted') { + $sheet->getCell('B1')->setValue('=YEARFRAC()'); + } elseif ($arg2 === 'omitted') { + $sheet->getCell('B1')->setValue('=YEARFRAC(A1)'); + } elseif ($arg3 === 'omitted') { + $sheet->getCell('B1')->setValue('=YEARFRAC(A1, A2)'); + } else { + $sheet->getCell('B1')->setValue('=YEARFRAC(A1, A2, A3)'); + } + self::assertEqualswithDelta($expectedResult, $sheet->getCell('B1')->getCalculatedValue(), 1E-6); } public function providerYEARFRAC() diff --git a/tests/data/Calculation/DateTime/NETWORKDAYS.php b/tests/data/Calculation/DateTime/NETWORKDAYS.php index db548ddc95..f6f7b3af03 100644 --- a/tests/data/Calculation/DateTime/NETWORKDAYS.php +++ b/tests/data/Calculation/DateTime/NETWORKDAYS.php @@ -35,14 +35,13 @@ 0, '20-Jun-2008', '20-Jun-2008', - '20-Jun-2008', + ['20-Jun-2008'], ], [ 0, '20-Jun-2008', '20-Jun-2008', - '20-Jun-2008', - '20-Jun-2008', + ['20-Jun-2008', '20-Jun-2008'], ], [ 8, @@ -63,17 +62,13 @@ 16, '19-Dec-1960', '10-Jan-1961', - '25-Dec-1960', - '26-Dec-1960', - '01-Jan-1961', + ['25-Dec-1960', '26-Dec-1960', '01-Jan-1961'], ], [ -16, '10-Jan-1961', '19-Dec-1960', - '25-Dec-1960', - '26-Dec-1960', - '01-Jan-1961', + ['25-Dec-1960', '26-Dec-1960', '01-Jan-1961'], ], [ 65, @@ -114,8 +109,8 @@ '#VALUE!', '10-Jan-1961', '19-Dec-1960', - '25-Dec-1960', - 'ABQZ', - '01-Jan-1961', + ['25-Dec-1960', 'ABQZ', '01-Jan-1961'], ], + ['exception', '2000-01-01', 'omitted'], + ['exception', 'omitted'], ]; diff --git a/tests/data/Calculation/DateTime/WORKDAY.php b/tests/data/Calculation/DateTime/WORKDAY.php index e94404f8b1..fca99f6c4f 100644 --- a/tests/data/Calculation/DateTime/WORKDAY.php +++ b/tests/data/Calculation/DateTime/WORKDAY.php @@ -50,9 +50,11 @@ 39820, '19-Dec-2008', 10, - '25-Dec-2008', - '26-Dec-2008', - '01-Jan-2009', + [ + '25-Dec-2008', + '26-Dec-2008', + '01-Jan-2009', + ], ], [ 39820, @@ -121,4 +123,6 @@ [44264, '2021-03-19', -8], // issue 1936 Friday [44265, '2021-03-20', -8], // issue 1936 Saturday [44265, '2021-03-21', -8], // issue 1936 Sunday + ['exception', '2000-01-01', 'omitted'], + ['exception', 'omitted'], ]; diff --git a/tests/data/Calculation/DateTime/YEARFRAC.php b/tests/data/Calculation/DateTime/YEARFRAC.php index 3942086854..522f9e9d1e 100644 --- a/tests/data/Calculation/DateTime/YEARFRAC.php +++ b/tests/data/Calculation/DateTime/YEARFRAC.php @@ -7,6 +7,18 @@ '2007-1-10', 0, ], + [ + 0.025, + '2007-1-1', + '2007-1-10', + null, + ], + [ + 0.025, + '2007-1-1', + '2007-1-10', + 'omitted', + ], [ 0.025, '2007-1-10', @@ -562,4 +574,41 @@ ['#VALUE!', '2023-04-27', 'ABQZ', 1], ['#VALUE!', 'ABQZ', '2023-04-07', 1], ['#NUM!', '2023-04-27', '2025-05-28', 6], + ['exception', '2023-04-27', 'omitted'], + ['exception', 'omitted'], + [0, null, null], + // Excel 1900 calendar gets all of the following wrong (null second arg). + // PhpSpreadsheet is bug-compatible. + [108, '2007-12-30', null], + [107.11111111, '2007-02-10', null], + [107, '2006-12-30', null], + [107.00277778, '2006-12-31', null], + [107.00277778, '2007-01-01', null], + [106.99722222, null, '2006-12-29'], + [100.419444, '2000-06-01', null, 0], + [100.419572, '2000-06-01', null, 1], + [101.883333, '2000-06-01', null, 2], + [100.487671, '2000-06-01', null, 3], + [100.419444, '2000-06-01', null, 4], + [108.555556, '2006-12-29', null, 2], + [108.558333, '2006-12-30', null, 2], + [108.561111, '2006-12-31', null, 2], + [108.563889, '2007-01-01', null, 2], + [108.566667, '2007-01-02', null, 2], + // Excel 1900 calendar gets all of the following wrong (null first arg). + // PhpSpreadsheet is bug-compatible. + [107, null, '2006-12-30'], + [107.00277778, null, '2006-12-31'], + [107.00277778, null, '2007-01-01'], + [107.00555556, null, '2007-01-02'], + [107.06849315, null, '2006-12-29', 3], + [107.07123288, null, '2006-12-30', 3], + [107.07397260, null, '2006-12-31', 3], + [107.07671233, null, '2007-01-01', 3], + [107.07945205, null, '2007-01-02', 3], + [100.419444, null, '2000-06-01', 0], + [100.419572, null, '2000-06-01', 1], + [101.883333, null, '2000-06-01', 2], + [100.487671, null, '2000-06-01', 3], + [100.419444, null, '2000-06-01', 4], ];