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;
|
||||
} elseif (is_string($dateValue = self::getDateValue($dateValue))) {
|
||||
return Functions::VALUE();
|
||||
} elseif ($dateValue == 0.0) {
|
||||
return 0;
|
||||
} elseif ($dateValue < 0.0) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
|
||||
if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_EXCEL) {
|
||||
if ($dateValue < 0.0) {
|
||||
return Functions::NAN();
|
||||
} elseif ($dateValue < 1.0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Execute function
|
||||
|
|
|
@ -165,18 +165,23 @@ class Date
|
|||
public static function excelToDateTimeObject($excelTimestamp, $timeZone = null)
|
||||
{
|
||||
$timeZone = ($timeZone === null) ? self::getDefaultTimezone() : self::validateTimeZone($timeZone);
|
||||
if ($excelTimestamp < 1.0) {
|
||||
// Unix timestamp base date
|
||||
$baseDate = new \DateTime('1970-01-01', $timeZone);
|
||||
} else {
|
||||
// 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);
|
||||
if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_EXCEL) {
|
||||
if ($excelTimestamp < 1.0) {
|
||||
// Unix timestamp base date
|
||||
$baseDate = new \DateTime('1970-01-01', $timeZone);
|
||||
} 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);
|
||||
$partDay = $excelTimestamp - $days;
|
||||
$hours = floor($partDay * 24);
|
||||
|
@ -185,7 +190,10 @@ class Date
|
|||
$partDay = $partDay * 60 - $minutes;
|
||||
$seconds = round($partDay * 60);
|
||||
|
||||
$interval = '+' . $days . ' days';
|
||||
if ($days >= 0) {
|
||||
$days = '+' . $days;
|
||||
}
|
||||
$interval = $days . ' days';
|
||||
|
||||
return $baseDate->modify($interval)
|
||||
->setTime($hours, $minutes, $seconds);
|
||||
|
|
|
@ -174,12 +174,17 @@ class DateTimeTest extends PHPUnit_Framework_TestCase
|
|||
/**
|
||||
* @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);
|
||||
self::assertEquals($expectedResult, $result, null, 1E-8);
|
||||
$resultExcel = DateTime::DAYOFMONTH(...$args);
|
||||
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()
|
||||
|
|
|
@ -4,31 +4,53 @@
|
|||
|
||||
return [
|
||||
[
|
||||
19,
|
||||
19, // Result for Excel
|
||||
19, // Result for OpenOffice
|
||||
22269,
|
||||
],
|
||||
[
|
||||
1,
|
||||
1, // Result for Excel
|
||||
1, // Result for OpenOffice
|
||||
30348,
|
||||
],
|
||||
[
|
||||
10,
|
||||
10, // Result for Excel
|
||||
10, // Result for OpenOffice
|
||||
30843,
|
||||
],
|
||||
[
|
||||
11,
|
||||
11, // Result for Excel
|
||||
11, // Result for OpenOffice
|
||||
'11-Nov-1918',
|
||||
],
|
||||
[
|
||||
28,
|
||||
28, // Result for Excel
|
||||
28, // Result for OpenOffice
|
||||
'28-Feb-1904',
|
||||
],
|
||||
[
|
||||
'#VALUE!',
|
||||
'#VALUE!', // Result for Excel
|
||||
'#VALUE!', // Result for OpenOffice
|
||||
'Invalid',
|
||||
],
|
||||
[
|
||||
'#NUM!',
|
||||
'#NUM!', // Result for Excel
|
||||
29, // Result for OpenOffice
|
||||
-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