Fix DAY() function with 0<x<1 input (#230)
Also bring support for OpenOffice DATE() calculation method
This commit is contained in:
parent
13265581a9
commit
088a76737e
|
@ -1137,10 +1137,14 @@ class DateTime
|
||||||
$dateValue = 1;
|
$dateValue = 1;
|
||||||
} elseif (is_string($dateValue = self::getDateValue($dateValue))) {
|
} elseif (is_string($dateValue = self::getDateValue($dateValue))) {
|
||||||
return Functions::VALUE();
|
return Functions::VALUE();
|
||||||
} elseif ($dateValue == 0.0) {
|
}
|
||||||
return 0;
|
|
||||||
} elseif ($dateValue < 0.0) {
|
if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_EXCEL) {
|
||||||
return Functions::NAN();
|
if ($dateValue < 0.0) {
|
||||||
|
return Functions::NAN();
|
||||||
|
} elseif ($dateValue < 1.0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute function
|
// Execute function
|
||||||
|
|
|
@ -165,18 +165,23 @@ class Date
|
||||||
public static function excelToDateTimeObject($excelTimestamp, $timeZone = null)
|
public static function excelToDateTimeObject($excelTimestamp, $timeZone = null)
|
||||||
{
|
{
|
||||||
$timeZone = ($timeZone === null) ? self::getDefaultTimezone() : self::validateTimeZone($timeZone);
|
$timeZone = ($timeZone === null) ? self::getDefaultTimezone() : self::validateTimeZone($timeZone);
|
||||||
if ($excelTimestamp < 1.0) {
|
if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_EXCEL) {
|
||||||
// Unix timestamp base date
|
if ($excelTimestamp < 1.0) {
|
||||||
$baseDate = new \DateTime('1970-01-01', $timeZone);
|
// Unix timestamp base date
|
||||||
} else {
|
$baseDate = new \DateTime('1970-01-01', $timeZone);
|
||||||
// MS Excel calendar base dates
|
|
||||||
if (self::$excelCalendar == self::CALENDAR_WINDOWS_1900) {
|
|
||||||
// Allow adjustment for 1900 Leap Year in MS Excel
|
|
||||||
$baseDate = ($excelTimestamp < 60) ? new \DateTime('1899-12-31', $timeZone) : new \DateTime('1899-12-30', $timeZone);
|
|
||||||
} else {
|
} else {
|
||||||
$baseDate = new \DateTime('1904-01-01', $timeZone);
|
// MS Excel calendar base dates
|
||||||
|
if (self::$excelCalendar == self::CALENDAR_WINDOWS_1900) {
|
||||||
|
// Allow adjustment for 1900 Leap Year in MS Excel
|
||||||
|
$baseDate = ($excelTimestamp < 60) ? new \DateTime('1899-12-31', $timeZone) : new \DateTime('1899-12-30', $timeZone);
|
||||||
|
} else {
|
||||||
|
$baseDate = new \DateTime('1904-01-01', $timeZone);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$baseDate = new \DateTime('1899-12-30', $timeZone);
|
||||||
}
|
}
|
||||||
|
|
||||||
$days = floor($excelTimestamp);
|
$days = floor($excelTimestamp);
|
||||||
$partDay = $excelTimestamp - $days;
|
$partDay = $excelTimestamp - $days;
|
||||||
$hours = floor($partDay * 24);
|
$hours = floor($partDay * 24);
|
||||||
|
@ -185,7 +190,10 @@ class Date
|
||||||
$partDay = $partDay * 60 - $minutes;
|
$partDay = $partDay * 60 - $minutes;
|
||||||
$seconds = round($partDay * 60);
|
$seconds = round($partDay * 60);
|
||||||
|
|
||||||
$interval = '+' . $days . ' days';
|
if ($days >= 0) {
|
||||||
|
$days = '+' . $days;
|
||||||
|
}
|
||||||
|
$interval = $days . ' days';
|
||||||
|
|
||||||
return $baseDate->modify($interval)
|
return $baseDate->modify($interval)
|
||||||
->setTime($hours, $minutes, $seconds);
|
->setTime($hours, $minutes, $seconds);
|
||||||
|
|
|
@ -174,12 +174,17 @@ class DateTimeTest extends PHPUnit_Framework_TestCase
|
||||||
/**
|
/**
|
||||||
* @dataProvider providerDAY
|
* @dataProvider providerDAY
|
||||||
*
|
*
|
||||||
* @param mixed $expectedResult
|
* @param mixed $expectedResultExcel
|
||||||
|
* @param mixed $expectedResultOpenOffice
|
||||||
*/
|
*/
|
||||||
public function testDAY($expectedResult, ...$args)
|
public function testDAY($expectedResultExcel, $expectedResultOpenOffice, ...$args)
|
||||||
{
|
{
|
||||||
$result = DateTime::DAYOFMONTH(...$args);
|
$resultExcel = DateTime::DAYOFMONTH(...$args);
|
||||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
self::assertEquals($expectedResultExcel, $resultExcel, null, 1E-8);
|
||||||
|
|
||||||
|
Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
|
||||||
|
$resultOpenOffice = DateTime::DAYOFMONTH(...$args);
|
||||||
|
self::assertEquals($expectedResultOpenOffice, $resultOpenOffice, null, 1E-8);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function providerDAY()
|
public function providerDAY()
|
||||||
|
|
|
@ -4,31 +4,53 @@
|
||||||
|
|
||||||
return [
|
return [
|
||||||
[
|
[
|
||||||
19,
|
19, // Result for Excel
|
||||||
|
19, // Result for OpenOffice
|
||||||
22269,
|
22269,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
1,
|
1, // Result for Excel
|
||||||
|
1, // Result for OpenOffice
|
||||||
30348,
|
30348,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
10,
|
10, // Result for Excel
|
||||||
|
10, // Result for OpenOffice
|
||||||
30843,
|
30843,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
11,
|
11, // Result for Excel
|
||||||
|
11, // Result for OpenOffice
|
||||||
'11-Nov-1918',
|
'11-Nov-1918',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
28,
|
28, // Result for Excel
|
||||||
|
28, // Result for OpenOffice
|
||||||
'28-Feb-1904',
|
'28-Feb-1904',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'#VALUE!',
|
'#VALUE!', // Result for Excel
|
||||||
|
'#VALUE!', // Result for OpenOffice
|
||||||
'Invalid',
|
'Invalid',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'#NUM!',
|
'#NUM!', // Result for Excel
|
||||||
|
29, // Result for OpenOffice
|
||||||
-1,
|
-1,
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
1, // Result for Excel
|
||||||
|
31, // Result for OpenOffice
|
||||||
|
1,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0, // Result for Excel
|
||||||
|
30, // Result for OpenOffice
|
||||||
|
0.5,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0, // Result for Excel
|
||||||
|
30, // Result for OpenOffice
|
||||||
|
0,
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
Loading…
Reference in New Issue