Group some of the newly extracted Excel DateTime function implementations into groups of related functions with appropriate and meaningful class names, and rename the public methods to be more descriptive of their purpose

This commit is contained in:
MarkBaker 2021-05-12 13:25:28 +02:00 committed by Mark Baker
parent 7903827475
commit cd667500e0
24 changed files with 463 additions and 528 deletions

View File

@ -778,7 +778,7 @@ class Calculation
],
'DAY' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTimeExcel\Day::class, 'evaluate'],
'functionCall' => [DateTimeExcel\DateParts::class, 'day'],
'argumentCount' => '1',
],
'DAYS' => [
@ -1240,7 +1240,7 @@ class Calculation
],
'HOUR' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTimeExcel\Hour::class, 'evaluate'],
'functionCall' => [DateTimeExcel\TimeParts::class, 'hour'],
'argumentCount' => '1',
],
'HYPERLINK' => [
@ -1504,7 +1504,7 @@ class Calculation
],
'ISOWEEKNUM' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTimeExcel\IsoWeekNum::class, 'evaluate'],
'functionCall' => [DateTimeExcel\Week::class, 'isoWeekNumber'],
'argumentCount' => '1',
],
'ISPMT' => [
@ -1684,7 +1684,7 @@ class Calculation
],
'MINUTE' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTimeExcel\Minute::class, 'evaluate'],
'functionCall' => [DateTimeExcel\TimeParts::class, 'minute'],
'argumentCount' => '1',
],
'MINVERSE' => [
@ -1724,7 +1724,7 @@ class Calculation
],
'MONTH' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTimeExcel\Month::class, 'evaluate'],
'functionCall' => [DateTimeExcel\DateParts::class, 'month'],
'argumentCount' => '1',
],
'MROUND' => [
@ -1824,7 +1824,7 @@ class Calculation
],
'NOW' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTimeExcel\Now::class, 'evaluate'],
'functionCall' => [DateTimeExcel\Current::class, 'now'],
'argumentCount' => '0',
],
'NPER' => [
@ -2178,7 +2178,7 @@ class Calculation
],
'SECOND' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTimeExcel\Second::class, 'evaluate'],
'functionCall' => [DateTimeExcel\TimeParts::class, 'second'],
'argumentCount' => '1',
],
'SEQUENCE' => [
@ -2449,7 +2449,7 @@ class Calculation
],
'TODAY' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTimeExcel\Today::class, 'evaluate'],
'functionCall' => [DateTimeExcel\Current::class, 'today'],
'argumentCount' => '0',
],
'TRANSPOSE' => [
@ -2574,12 +2574,12 @@ class Calculation
],
'WEEKDAY' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTimeExcel\WeekDay::class, 'evaluate'],
'functionCall' => [DateTimeExcel\Week::class, 'day'],
'argumentCount' => '1,2',
],
'WEEKNUM' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTimeExcel\WeekNum::class, 'evaluate'],
'functionCall' => [DateTimeExcel\Week::class, 'number'],
'argumentCount' => '1,2',
],
'WEIBULL' => [
@ -2629,7 +2629,7 @@ class Calculation
],
'YEAR' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
'functionCall' => [DateTimeExcel\Year::class, 'evaluate'],
'functionCall' => [DateTimeExcel\DateParts::class, 'year'],
'argumentCount' => '1',
],
'YEARFRAC' => [

View File

@ -63,15 +63,15 @@ class DateTime
*
* @Deprecated 1.18.0
*
* @See DateTimeExcel\Now::evaluate()
* Use the evaluate method in the DateTimeExcel\Now class instead
* @See DateTimeExcel\Current::now()
* Use the now method in the DateTimeExcel\Current class instead
*
* @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 DATETIMENOW()
{
return DateTimeExcel\Now::evaluate();
return DateTimeExcel\Current::now();
}
/**
@ -90,15 +90,15 @@ class DateTime
*
* @Deprecated 1.18.0
*
* @See DateTimeExcel\Today::evaluate()
* Use the evaluate method in the DateTimeExcel\Today class instead
* @See DateTimeExcel\Current::today()
* Use the today method in the DateTimeExcel\Current class instead
*
* @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 DATENOW()
{
return DateTimeExcel\Today::evaluate();
return DateTimeExcel\Current::today();
}
/**
@ -458,8 +458,8 @@ class DateTime
*
* @Deprecated 1.18.0
*
* @See DateTimeExcel\Day::evaluate()
* Use the evaluate method in the DateTimeExcel\Day class instead
* @See DateTimeExcel\DateParts::day()
* Use the day method in the DateTimeExcel\DateParts class instead
*
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard date string
@ -468,7 +468,7 @@ class DateTime
*/
public static function DAYOFMONTH($dateValue = 1)
{
return DateTimeExcel\Day::evaluate($dateValue);
return DateTimeExcel\DateParts::day($dateValue);
}
/**
@ -482,8 +482,8 @@ class DateTime
*
* @Deprecated 1.18.0
*
* @See DateTimeExcel\WeekDay::evaluate()
* Use the evaluate method in the DateTimeExcel\WeekDay class instead
* @See DateTimeExcel\Week::day()
* Use the day method in the DateTimeExcel\Week class instead
*
* @param float|int|string $dateValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard date string
@ -496,7 +496,7 @@ class DateTime
*/
public static function WEEKDAY($dateValue = 1, $style = 1)
{
return DateTimeExcel\WeekDay::evaluate($dateValue, $style);
return DateTimeExcel\Week::day($dateValue, $style);
}
/**
@ -687,8 +687,8 @@ class DateTime
*
* @Deprecated 1.18.0
*
* @See DateTimeExcel\WeekNum::evaluate()
* Use the evaluate method in the DateTimeExcel\WeekNum class instead
* @See DateTimeExcel\Week::number(()
* Use the number method in the DateTimeExcel\Week class instead
*
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard date string
@ -708,7 +708,7 @@ class DateTime
*/
public static function WEEKNUM($dateValue = 1, $method = self::STARTWEEK_SUNDAY)
{
return DateTimeExcel\WeekNum::evaluate($dateValue, $method);
return DateTimeExcel\Week::number($dateValue, $method);
}
/**
@ -721,8 +721,8 @@ class DateTime
*
* @Deprecated 1.18.0
*
* @See DateTimeExcel\IsoWeekNum::evaluate()
* Use the evaluate method in the DateTimeExcel\IsoWeekNum class instead
* @See DateTimeExcel\Week::isoWeekNumber()
* Use the isoWeekNumber method in the DateTimeExcel\Week class instead
*
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard date string
@ -731,7 +731,7 @@ class DateTime
*/
public static function ISOWEEKNUM($dateValue = 1)
{
return DateTimeExcel\IsoWeekNum::evaluate($dateValue);
return DateTimeExcel\Week::isoWeekNumber($dateValue);
}
/**
@ -745,8 +745,8 @@ class DateTime
*
* @Deprecated 1.18.0
*
* @See DateTimeExcel\Month::evaluate()
* Use the evaluate method in the DateTimeExcel\Month class instead
* @See DateTimeExcel\DateParts::month()
* Use the month method in the DateTimeExcel\DateParts class instead
*
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard date string
@ -755,7 +755,7 @@ class DateTime
*/
public static function MONTHOFYEAR($dateValue = 1)
{
return DateTimeExcel\Month::evaluate($dateValue);
return DateTimeExcel\DateParts::month($dateValue);
}
/**
@ -769,8 +769,8 @@ class DateTime
*
* @Deprecated 1.18.0
*
* @See DateTimeExcel\Year::evaluate()
* Use the evaluate method in the DateTimeExcel\Year class instead
* @See DateTimeExcel\DateParts::year()
* Use the ear method in the DateTimeExcel\DateParts class instead
*
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard date string
@ -779,7 +779,7 @@ class DateTime
*/
public static function YEAR($dateValue = 1)
{
return DateTimeExcel\Year::evaluate($dateValue);
return DateTimeExcel\DateParts::year($dateValue);
}
/**
@ -793,8 +793,8 @@ class DateTime
*
* @Deprecated 1.18.0
*
* @See DateTimeExcel\Hour::evaluate()
* Use the evaluate method in the DateTimeExcel\Hour class instead
* @See DateTimeExcel\TimeParts::hour()
* Use the hour method in the DateTimeExcel\TimeParts class instead
*
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard time string
@ -803,7 +803,7 @@ class DateTime
*/
public static function HOUROFDAY($timeValue = 0)
{
return DateTimeExcel\Hour::evaluate($timeValue);
return DateTimeExcel\TimeParts::hour($timeValue);
}
/**
@ -817,8 +817,8 @@ class DateTime
*
* @Deprecated 1.18.0
*
* @See DateTimeExcel\Minute::evaluate()
* Use the evaluate method in the DateTimeExcel\Minute class instead
* @See DateTimeExcel\TimeParts::minute()
* Use the minute method in the DateTimeExcel\TimeParts class instead
*
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard time string
@ -827,7 +827,7 @@ class DateTime
*/
public static function MINUTE($timeValue = 0)
{
return DateTimeExcel\Minute::evaluate($timeValue);
return DateTimeExcel\TimeParts::minute($timeValue);
}
/**
@ -841,8 +841,8 @@ class DateTime
*
* @Deprecated 1.18.0
*
* @See DateTimeExcel\Second::evaluate()
* Use the evaluate method in the DateTimeExcel\Second class instead
* @See DateTimeExcel\TimeParts::second()
* Use the second method in the DateTimeExcel\TimeParts class instead
*
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard time string
@ -851,7 +851,7 @@ class DateTime
*/
public static function SECOND($timeValue = 0)
{
return DateTimeExcel\Second::evaluate($timeValue);
return DateTimeExcel\TimeParts::second($timeValue);
}
/**

View File

@ -5,8 +5,33 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
use DateTimeImmutable;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
class Now
class Current
{
/**
* DATENOW.
*
* Returns the current date.
* The NOW function is useful when you need to display the current date and time on a worksheet or
* calculate a value based on the current date and time, and have that value updated each time you
* open the worksheet.
*
* 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.
*
* Excel Function:
* TODAY()
*
* @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 today()
{
$dti = new DateTimeImmutable();
$dateArray = date_parse($dti->format('c'));
return is_array($dateArray) ? Helpers::returnIn3FormatsArray($dateArray, true) : Functions::VALUE();
}
/**
* DATETIMENOW.
*
@ -24,7 +49,7 @@ class Now
* @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 evaluate()
public static function now()
{
$dti = new DateTimeImmutable();
$dateArray = date_parse($dti->format('c'));

View File

@ -0,0 +1,127 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Shared\Date;
class DateParts
{
/**
* DAYOFMONTH.
*
* Returns the day of the month, for a specified date. The day is given as an integer
* ranging from 1 to 31.
*
* Excel Function:
* DAY(dateValue)
*
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard date string
*
* @return int|string Day of the month
*/
public static function day($dateValue)
{
$weirdResult = self::weirdCondition($dateValue);
if ($weirdResult >= 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');
}
/**
* MONTHOFYEAR.
*
* 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).
*
* Excel Function:
* MONTH(dateValue)
*
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard date string
*
* @return int|string Month of the year
*/
public static function month($dateValue)
{
try {
$dateValue = Helpers::getDateValue($dateValue);
} catch (Exception $e) {
return $e->getMessage();
}
if ($dateValue < 1 && Date::getExcelCalendar() === DATE::CALENDAR_WINDOWS_1900) {
return 1;
}
// Execute function
$PHPDateObject = Date::excelToDateTimeObject($dateValue);
return (int) $PHPDateObject->format('n');
}
/**
* YEAR.
*
* Returns the year corresponding to a date.
* The year is returned as an integer in the range 1900-9999.
*
* Excel Function:
* YEAR(dateValue)
*
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard date string
*
* @return int|string Year
*/
public static function year($dateValue)
{
try {
$dateValue = Helpers::getDateValue($dateValue);
} catch (Exception $e) {
return $e->getMessage();
}
if ($dateValue < 1 && Date::getExcelCalendar() === DATE::CALENDAR_WINDOWS_1900) {
return 1900;
}
// Execute function
$PHPDateObject = Date::excelToDateTimeObject($dateValue);
return (int) $PHPDateObject->format('Y');
}
/**
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard date string
*/
private static function weirdCondition($dateValue): int
{
// Excel does not treat 0 consistently for DAY vs. (MONTH or YEAR)
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;
}
}

View File

@ -1,65 +0,0 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
use Exception;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Shared\Date;
class Day
{
/**
* DAYOFMONTH.
*
* Returns the day of the month, for a specified date. The day is given as an integer
* ranging from 1 to 31.
*
* Excel Function:
* DAY(dateValue)
*
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard date string
*
* @return int|string Day of the month
*/
public static function evaluate($dateValue)
{
$weirdResult = self::weirdCondition($dateValue);
if ($weirdResult >= 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');
}
/**
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard date string
*/
private static function weirdCondition($dateValue): int
{
// Excel does not treat 0 consistently for DAY vs. (MONTH or YEAR)
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;
}
}

View File

@ -1,44 +0,0 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
use Exception;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Shared\Date;
class Hour
{
/**
* HOUROFDAY.
*
* 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.).
*
* Excel Function:
* HOUR(timeValue)
*
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard time string
*
* @return int|string Hour
*/
public static function evaluate($timeValue)
{
try {
$timeValue = Functions::flattenSingleValue($timeValue);
Helpers::nullFalseTrueToNumber($timeValue);
if (!is_numeric($timeValue)) {
$timeValue = Helpers::getTimeValue($timeValue);
}
Helpers::validateNotNegative($timeValue);
} catch (Exception $e) {
return $e->getMessage();
}
// Execute function
$timeValue = fmod($timeValue, 1);
$timeValue = Date::excelToDateTimeObject($timeValue);
return (int) $timeValue->format('H');
}
}

View File

@ -1,59 +0,0 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
use Exception;
use PhpOffice\PhpSpreadsheet\Shared\Date;
class IsoWeekNum
{
/**
* ISOWEEKNUM.
*
* Returns the ISO 8601 week number of the year for a specified date.
*
* Excel Function:
* ISOWEEKNUM(dateValue)
*
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard date string
*
* @return int|string Week Number
*/
public static function evaluate($dateValue)
{
if (self::apparentBug($dateValue)) {
return 52;
}
try {
$dateValue = Helpers::getDateValue($dateValue);
} catch (Exception $e) {
return $e->getMessage();
}
// Execute function
$PHPDateObject = Date::excelToDateTimeObject($dateValue);
Helpers::silly1900($PHPDateObject);
return (int) $PHPDateObject->format('W');
}
/**
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard date string
*/
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;
}
}

View File

@ -1,44 +0,0 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
use Exception;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Shared\Date;
class Minute
{
/**
* MINUTE.
*
* Returns the minutes of a time value.
* The minute is given as an integer, ranging from 0 to 59.
*
* Excel Function:
* MINUTE(timeValue)
*
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard time string
*
* @return int|string Minute
*/
public static function evaluate($timeValue)
{
try {
$timeValue = Functions::flattenSingleValue($timeValue);
Helpers::nullFalseTrueToNumber($timeValue);
if (!is_numeric($timeValue)) {
$timeValue = Helpers::getTimeValue($timeValue);
}
Helpers::validateNotNegative($timeValue);
} catch (Exception $e) {
return $e->getMessage();
}
// Execute function
$timeValue = fmod($timeValue, 1);
$timeValue = Date::excelToDateTimeObject($timeValue);
return (int) $timeValue->format('i');
}
}

View File

@ -1,40 +0,0 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
use Exception;
use PhpOffice\PhpSpreadsheet\Shared\Date;
class Month
{
/**
* MONTHOFYEAR.
*
* 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).
*
* Excel Function:
* MONTH(dateValue)
*
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard date string
*
* @return int|string Month of the year
*/
public static function evaluate($dateValue)
{
try {
$dateValue = Helpers::getDateValue($dateValue);
} catch (Exception $e) {
return $e->getMessage();
}
if ($dateValue < 1 && Date::getExcelCalendar() === DATE::CALENDAR_WINDOWS_1900) {
return 1;
}
// Execute function
$PHPDateObject = Date::excelToDateTimeObject($dateValue);
return (int) $PHPDateObject->format('n');
}
}

View File

@ -56,7 +56,7 @@ class NetworkDays
$holidayCountedArray = [];
foreach ($holidayArray as $holidayDate) {
if (($holidayDate >= $startDate) && ($holidayDate <= $endDate)) {
if ((WeekDay::evaluate($holidayDate, 2) < 6) && (!in_array($holidayDate, $holidayCountedArray))) {
if ((Week::day($holidayDate, 2) < 6) && (!in_array($holidayDate, $holidayCountedArray))) {
--$partWeekDays;
$holidayCountedArray[] = $holidayDate;
}
@ -68,7 +68,7 @@ class NetworkDays
private static function calcStartDow(float $startDate): int
{
$startDow = 6 - (int) WeekDay::evaluate($startDate, 2);
$startDow = 6 - (int) Week::day($startDate, 2);
if ($startDow < 0) {
$startDow = 5;
}
@ -78,7 +78,7 @@ class NetworkDays
private static function calcEndDow(float $endDate): int
{
$endDow = (int) WeekDay::evaluate($endDate, 2);
$endDow = (int) Week::day($endDate, 2);
if ($endDow >= 6) {
$endDow = 0;
}

View File

@ -1,44 +0,0 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
use Exception;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Shared\Date;
class Second
{
/**
* MINUTE.
*
* Returns the minutes of a time value.
* The minute is given as an integer, ranging from 0 to 59.
*
* Excel Function:
* MINUTE(timeValue)
*
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard time string
*
* @return int|string Minute
*/
public static function evaluate($timeValue)
{
try {
$timeValue = Functions::flattenSingleValue($timeValue);
Helpers::nullFalseTrueToNumber($timeValue);
if (!is_numeric($timeValue)) {
$timeValue = Helpers::getTimeValue($timeValue);
}
Helpers::validateNotNegative($timeValue);
} catch (Exception $e) {
return $e->getMessage();
}
// Execute function
$timeValue = fmod($timeValue, 1);
$timeValue = Date::excelToDateTimeObject($timeValue);
return (int) $timeValue->format('s');
}
}

View File

@ -0,0 +1,112 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Shared\Date;
class TimeParts
{
/**
* HOUROFDAY.
*
* 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.).
*
* Excel Function:
* HOUR(timeValue)
*
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard time string
*
* @return int|string Hour
*/
public static function hour($timeValue)
{
try {
$timeValue = Functions::flattenSingleValue($timeValue);
Helpers::nullFalseTrueToNumber($timeValue);
if (!is_numeric($timeValue)) {
$timeValue = Helpers::getTimeValue($timeValue);
}
Helpers::validateNotNegative($timeValue);
} catch (Exception $e) {
return $e->getMessage();
}
// Execute function
$timeValue = fmod($timeValue, 1);
$timeValue = Date::excelToDateTimeObject($timeValue);
return (int) $timeValue->format('H');
}
/**
* MINUTE.
*
* Returns the minutes of a time value.
* The minute is given as an integer, ranging from 0 to 59.
*
* Excel Function:
* MINUTE(timeValue)
*
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard time string
*
* @return int|string Minute
*/
public static function minute($timeValue)
{
try {
$timeValue = Functions::flattenSingleValue($timeValue);
Helpers::nullFalseTrueToNumber($timeValue);
if (!is_numeric($timeValue)) {
$timeValue = Helpers::getTimeValue($timeValue);
}
Helpers::validateNotNegative($timeValue);
} catch (Exception $e) {
return $e->getMessage();
}
// Execute function
$timeValue = fmod($timeValue, 1);
$timeValue = Date::excelToDateTimeObject($timeValue);
return (int) $timeValue->format('i');
}
/**
* SECOND.
*
* Returns the seconds of a time value.
* The minute is given as an integer, ranging from 0 to 59.
*
* Excel Function:
* SECOND(timeValue)
*
* @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard time string
*
* @return int|string Second
*/
public static function second($timeValue)
{
try {
$timeValue = Functions::flattenSingleValue($timeValue);
Helpers::nullFalseTrueToNumber($timeValue);
if (!is_numeric($timeValue)) {
$timeValue = Helpers::getTimeValue($timeValue);
}
Helpers::validateNotNegative($timeValue);
} catch (Exception $e) {
return $e->getMessage();
}
// Execute function
$timeValue = fmod($timeValue, 1);
$timeValue = Date::excelToDateTimeObject($timeValue);
return (int) $timeValue->format('s');
}
}

View File

@ -1,34 +0,0 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
use DateTimeImmutable;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
class Today
{
/**
* DATENOW.
*
* Returns the current date.
* The NOW function is useful when you need to display the current date and time on a worksheet or
* calculate a value based on the current date and time, and have that value updated each time you
* open the worksheet.
*
* 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.
*
* Excel Function:
* TODAY()
*
* @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 evaluate()
{
$dti = new DateTimeImmutable();
$dateArray = date_parse($dti->format('c'));
return is_array($dateArray) ? Helpers::returnIn3FormatsArray($dateArray, true) : Functions::VALUE();
}
}

View File

@ -3,11 +3,11 @@
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
use DateTime;
use Exception;
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Shared\Date;
class WeekNum
class Week
{
/**
* WEEKNUM.
@ -38,7 +38,7 @@ class WeekNum
*
* @return int|string Week Number
*/
public static function evaluate($dateValue, $method = Constants::STARTWEEK_SUNDAY)
public static function number($dateValue, $method = Constants::STARTWEEK_SUNDAY)
{
$origDateValueNull = empty($dateValue);
@ -78,6 +78,129 @@ class WeekNum
return (int) $weekOfYear;
}
/**
* ISOWEEKNUM.
*
* Returns the ISO 8601 week number of the year for a specified date.
*
* Excel Function:
* ISOWEEKNUM(dateValue)
*
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard date string
*
* @return int|string Week Number
*/
public static function isoWeekNumber($dateValue)
{
if (self::apparentBug($dateValue)) {
return 52;
}
try {
$dateValue = Helpers::getDateValue($dateValue);
} catch (Exception $e) {
return $e->getMessage();
}
// Execute function
$PHPDateObject = Date::excelToDateTimeObject($dateValue);
Helpers::silly1900($PHPDateObject);
return (int) $PHPDateObject->format('W');
}
/**
* WEEKDAY.
*
* 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).
*
* Excel Function:
* WEEKDAY(dateValue[,style])
*
* @param null|float|int|string $dateValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard date string
* @param mixed $style A number that determines the type of return value
* 1 or omitted Numbers 1 (Sunday) through 7 (Saturday).
* 2 Numbers 1 (Monday) through 7 (Sunday).
* 3 Numbers 0 (Monday) through 6 (Sunday).
*
* @return int|string Day of the week value
*/
public static function day($dateValue, $style = 1)
{
try {
$dateValue = Helpers::getDateValue($dateValue);
$style = self::validateStyle($style);
} catch (Exception $e) {
return $e->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;
}
/**
* @param mixed $style expect int
*/
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;
}
/**
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard date string
*/
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;
}
/**
* Validate dateValue parameter.
*
@ -125,6 +248,7 @@ class WeekNum
{
// This appears to be another Excel bug.
return $method === Constants::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';
}
}

View File

@ -1,83 +0,0 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Shared\Date;
class WeekDay
{
/**
* WEEKDAY.
*
* 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).
*
* Excel Function:
* WEEKDAY(dateValue[,style])
*
* @param null|float|int|string $dateValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard date string
* @param mixed $style A number that determines the type of return value
* 1 or omitted Numbers 1 (Sunday) through 7 (Saturday).
* 2 Numbers 1 (Monday) through 7 (Sunday).
* 3 Numbers 0 (Monday) through 6 (Sunday).
*
* @return int|string Day of the week value
*/
public static function evaluate($dateValue, $style = 1)
{
try {
$dateValue = Helpers::getDateValue($dateValue);
$style = self::validateStyle($style);
} catch (Exception $e) {
return $e->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;
}
/**
* @param mixed $style expect int
*/
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;
}
}

View File

@ -183,7 +183,7 @@ class WorkDay
private static function getWeekDay(float $date, int $wd): int
{
$result = WeekDay::evaluate($date, $wd);
$result = Week::day($date, $wd);
return is_string($result) ? -1 : $result;
}

View File

@ -1,40 +0,0 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
use Exception;
use PhpOffice\PhpSpreadsheet\Shared\Date;
class Year
{
/**
* YEAR.
*
* Returns the year corresponding to a date.
* The year is returned as an integer in the range 1900-9999.
*
* Excel Function:
* YEAR(dateValue)
*
* @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard date string
*
* @return int|string Year
*/
public static function evaluate($dateValue)
{
try {
$dateValue = Helpers::getDateValue($dateValue);
} catch (Exception $e) {
return $e->getMessage();
}
if ($dateValue < 1 && Date::getExcelCalendar() === DATE::CALENDAR_WINDOWS_1900) {
return 1900;
}
// Execute function
$PHPDateObject = Date::excelToDateTimeObject($dateValue);
return (int) $PHPDateObject->format('Y');
}
}

View File

@ -74,7 +74,7 @@ class YearFrac
{
if (Functions::getCompatibilityMode() !== Functions::COMPATIBILITY_OPENOFFICE && Date::getExcelCalendar() !== Date::CALENDAR_MAC_1904) {
if ($endDate === null && $startDate !== null) {
if (Month::evaluate($sDate) == 12 && Day::evaluate($sDate) === 31 && $method === 0) {
if (DateParts::month($sDate) == 12 && DateParts::day($sDate) === 31 && $method === 0) {
$sDate += 2;
} else {
++$sDate;
@ -88,13 +88,13 @@ class YearFrac
private static function method1(float $startDate, float $endDate): float
{
$days = DateDif::evaluate($startDate, $endDate);
$startYear = (int) Year::evaluate($startDate);
$endYear = (int) Year::evaluate($endDate);
$startYear = (int) DateParts::year($startDate);
$endYear = (int) DateParts::year($endDate);
$years = $endYear - $startYear + 1;
$startMonth = (int) Month::evaluate($startDate);
$startDay = (int) Day::evaluate($startDate);
$endMonth = (int) Month::evaluate($endDate);
$endDay = (int) Day::evaluate($endDate);
$startMonth = (int) DateParts::month($startDate);
$startDay = (int) DateParts::day($startDate);
$endMonth = (int) DateParts::month($endDate);
$endDay = (int) DateParts::day($endDate);
$startMonthDay = 100 * $startMonth + $startDay;
$endMonthDay = 100 * $endMonth + $endDay;
if ($years == 1) {

View File

@ -160,7 +160,7 @@ class Amortization
$fOneRate = $cost * $rate;
$fCostDelta = $cost - $salvage;
// Note, quirky variation for leap years on the YEARFRAC for this function
$purchasedYear = DateTimeExcel\Year::evaluate($purchased);
$purchasedYear = DateTimeExcel\DateParts::year($purchased);
$yearFrac = DateTimeExcel\YearFrac::evaluate($purchased, $firstPeriod, $basis);
if (is_string($yearFrac)) {
return $yearFrac;

View File

@ -63,7 +63,7 @@ class Coupons
return $e->getMessage();
}
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\Year::evaluate($settlement), $basis);
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\DateParts::year($settlement), $basis);
if (is_string($daysPerYear)) {
return Functions::VALUE();
}
@ -133,7 +133,7 @@ class Coupons
case FinancialConstants::BASIS_DAYS_PER_YEAR_ACTUAL:
// Actual/actual
if ($frequency == FinancialConstants::FREQUENCY_ANNUAL) {
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\Year::evaluate($settlement), $basis);
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\DateParts::year($settlement), $basis);
return $daysPerYear / $frequency;
}
@ -197,7 +197,7 @@ class Coupons
return $e->getMessage();
}
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\Year::evaluate($settlement), $basis);
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\DateParts::year($settlement), $basis);
$next = self::couponFirstPeriodDate($settlement, $maturity, $frequency, self::PERIOD_DATE_NEXT);
if ($basis === FinancialConstants::BASIS_DAYS_PER_YEAR_NASD) {

View File

@ -194,7 +194,7 @@ class Price
return $e->getMessage();
}
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\Year::evaluate($settlement), $basis);
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\DateParts::year($settlement), $basis);
if (!is_numeric($daysPerYear)) {
return $daysPerYear;
}

View File

@ -57,7 +57,7 @@ class Yields
return $e->getMessage();
}
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\Year::evaluate($settlement), $basis);
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\DateParts::year($settlement), $basis);
if (!is_numeric($daysPerYear)) {
return $daysPerYear;
}
@ -122,7 +122,7 @@ class Yields
return $e->getMessage();
}
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\Year::evaluate($settlement), $basis);
$daysPerYear = Helpers::daysPerYear(DateTimeExcel\DateParts::year($settlement), $basis);
if (!is_numeric($daysPerYear)) {
return $daysPerYear;
}

View File

@ -43,7 +43,7 @@ class TreasuryBill
$daysBetweenSettlementAndMaturity = $maturity - $settlement;
$daysPerYear = Helpers::daysPerYear(
DateTimeExcel\Year::evaluate($maturity),
DateTimeExcel\DateParts::year($maturity),
FinancialConstants::BASIS_DAYS_PER_YEAR_ACTUAL
);
@ -88,7 +88,7 @@ class TreasuryBill
$daysBetweenSettlementAndMaturity = $maturity - $settlement;
$daysPerYear = Helpers::daysPerYear(
DateTimeExcel\Year::evaluate($maturity),
DateTimeExcel\DateParts::year($maturity),
FinancialConstants::BASIS_DAYS_PER_YEAR_ACTUAL
);
@ -134,7 +134,7 @@ class TreasuryBill
$daysBetweenSettlementAndMaturity = $maturity - $settlement;
$daysPerYear = Helpers::daysPerYear(
DateTimeExcel\Year::evaluate($maturity),
DateTimeExcel\DateParts::year($maturity),
FinancialConstants::BASIS_DAYS_PER_YEAR_ACTUAL
);

View File

@ -2,7 +2,7 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\WeekDay;
use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Week;
class WeekDayTest extends AllSetupTeardown
{
@ -28,8 +28,8 @@ class WeekDayTest extends AllSetupTeardown
public function testWEEKDAYwith1904Calendar(): void
{
self::setMac1904();
self::assertEquals(7, WeekDay::evaluate('1904-01-02'));
self::assertEquals(6, WeekDay::evaluate('1904-01-01'));
self::assertEquals(6, WeekDay::evaluate(null));
self::assertEquals(7, Week::day('1904-01-02'));
self::assertEquals(6, Week::day('1904-01-01'));
self::assertEquals(6, Week::day(null));
}
}