Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

100% Coverage for Calculation/DateTime #1870

Merged
merged 3 commits into from Feb 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
446 changes: 236 additions & 210 deletions src/PhpSpreadsheet/Calculation/DateTime.php

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/PhpSpreadsheet/Shared/Date.php
Expand Up @@ -160,7 +160,7 @@ public static function excelToDateTimeObject($excelTimestamp, $timeZone = null)
{
$timeZone = ($timeZone === null) ? self::getDefaultTimezone() : self::validateTimeZone($timeZone);
if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_EXCEL) {
if ($excelTimestamp < 1.0) {
if ($excelTimestamp < 1 && self::$excelCalendar === self::CALENDAR_WINDOWS_1900) {
// Unix timestamp base date
$baseDate = new \DateTime('1970-01-01', $timeZone);
} else {
Expand Down
Expand Up @@ -9,11 +9,21 @@

class DateTest extends TestCase
{
private $returnDateType;

private $excelCalendar;

protected function setUp(): void
{
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
$this->returnDateType = Functions::getReturnDateType();
$this->excelCalendar = Date::getExcelCalendar();
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
}

protected function tearDown(): void
{
Functions::setReturnDateType($this->returnDateType);
Date::setExcelCalendar($this->excelCalendar);
}

/**
Expand Down
Expand Up @@ -2,6 +2,7 @@

namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;

use DateTimeImmutable;
use DateTimeInterface;
use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
Expand All @@ -10,11 +11,21 @@

class DateValueTest extends TestCase
{
private $returnDateType;

private $excelCalendar;

protected function setUp(): void
{
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
$this->returnDateType = Functions::getReturnDateType();
$this->excelCalendar = Date::getExcelCalendar();
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
}

protected function tearDown(): void
{
Functions::setReturnDateType($this->returnDateType);
Date::setExcelCalendar($this->excelCalendar);
}

/**
Expand All @@ -25,7 +36,21 @@ protected function setUp(): void
*/
public function testDATEVALUE($expectedResult, $dateValue): void
{
$result = DateTime::DATEVALUE($dateValue);
// Loop to avoid extraordinarily rare edge case where first calculation
// and second do not take place on same day.
do {
$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);
}
}
$result = DateTime::DATEVALUE($dateValue);
$dtEnd = new DateTimeImmutable();
$endDay = $dtEnd->format('d');
} while ($startDay !== $endDay);
self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
}

Expand Down Expand Up @@ -55,4 +80,13 @@ public function testDATEVALUEtoDateTimeObject(): void
// ... with the correct value
self::assertEquals($result->format('d-M-Y'), '31-Jan-2012');
}

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'));
}
}
@@ -0,0 +1,38 @@
<?php

namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;

use DateTimeImmutable;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;

class NowTest extends TestCase
{
public function testNow(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
// 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', '=NOW()');
$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)');
$sheet->setCellValue('E1', '=HOUR(A1)');
$sheet->setCellValue('F1', '=MINUTE(A1)');
$sheet->setCellValue('G1', '=SECOND(A1)');
self::assertEquals($dtStart->format('Y'), $sheet->getCell('B1')->getCalculatedValue());
self::assertEquals($dtStart->format('m'), $sheet->getCell('C1')->getCalculatedValue());
self::assertEquals($dtStart->format('d'), $sheet->getCell('D1')->getCalculatedValue());
self::assertEquals($dtStart->format('H'), $sheet->getCell('E1')->getCalculatedValue());
self::assertEquals($dtStart->format('i'), $sheet->getCell('F1')->getCalculatedValue());
self::assertEquals($dtStart->format('s'), $sheet->getCell('G1')->getCalculatedValue());
}
}
Expand Up @@ -9,11 +9,20 @@

class TimeTest extends TestCase
{
private $returnDateType;

private $calendar;

protected function setUp(): void
{
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
$this->returnDateType = Functions::getReturnDateType();
$this->calendar = Date::getExcelCalendar();
}

protected function tearDown(): void
{
Functions::setReturnDateType($this->returnDateType);
Date::setExcelCalendar($this->calendar);
}

/**
Expand All @@ -23,6 +32,7 @@ protected function setUp(): void
*/
public function testTIME($expectedResult, ...$args): void
{
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
$result = DateTime::TIME(...$args);
self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
}
Expand Down Expand Up @@ -52,4 +62,20 @@ public function testTIMEtoDateTimeObject(): void
// ... with the correct value
self::assertEquals($result->format('H:i:s'), '07:30:20');
}

public function testTIME1904(): void
{
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
Date::setExcelCalendar(Date::CALENDAR_MAC_1904);
$result = DateTime::TIME(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);
self::assertEquals(0, $result);
}
}
Expand Up @@ -3,17 +3,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 WeekDayTest extends TestCase
{
private $excelCalendar;

protected function setUp(): void
{
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
$this->excelCalendar = Date::getExcelCalendar();
}

protected function tearDown(): void
{
Date::setExcelCalendar($this->excelCalendar);
}

/**
Expand All @@ -31,4 +35,12 @@ public function providerWEEKDAY()
{
return require 'tests/data/Calculation/DateTime/WEEKDAY.php';
}

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));
}
}
Expand Up @@ -3,17 +3,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 WeekNumTest extends TestCase
{
private $excelCalendar;

protected function setUp(): void
{
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
$this->excelCalendar = Date::getExcelCalendar();
}

protected function tearDown(): void
{
Date::setExcelCalendar($this->excelCalendar);
}

/**
Expand All @@ -31,4 +35,14 @@ public function providerWEEKNUM()
{
return require 'tests/data/Calculation/DateTime/WEEKNUM.php';
}

public function testWEEKNUMwith1904Calendar(): void
{
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'));
}
}
19 changes: 16 additions & 3 deletions tests/PhpSpreadsheetTests/Reader/Ods/OdsTest.php
Expand Up @@ -15,6 +15,19 @@
*/
class OdsTest extends TestCase
{
private $timeZone;

protected function setUp(): void
{
$this->timeZone = date_default_timezone_get();
date_default_timezone_set('UTC');
}

protected function tearDown(): void
{
date_default_timezone_set($this->timeZone);
}

/**
* @var Spreadsheet
*/
Expand Down Expand Up @@ -153,13 +166,13 @@ public function testReadValueAndComments(): void
self::assertEquals(0, $firstSheet->getCell('G10')->getValue());

self::assertEquals(DataType::TYPE_NUMERIC, $firstSheet->getCell('A10')->getDataType()); // Date
self::assertEquals(22269.0, $firstSheet->getCell('A10')->getValue());
self::assertEquals('19-Dec-60', $firstSheet->getCell('A10')->getFormattedValue());

self::assertEquals(DataType::TYPE_NUMERIC, $firstSheet->getCell('A13')->getDataType()); // Time
self::assertEquals(25569.0625, $firstSheet->getCell('A13')->getValue());
self::assertEquals('2:30:00', $firstSheet->getCell('A13')->getFormattedValue());

self::assertEquals(DataType::TYPE_NUMERIC, $firstSheet->getCell('A15')->getDataType()); // Date + Time
self::assertEquals(22269.0625, $firstSheet->getCell('A15')->getValue());
self::assertEquals('19-Dec-60 1:30:00', $firstSheet->getCell('A15')->getFormattedValue());

self::assertEquals(DataType::TYPE_NUMERIC, $firstSheet->getCell('A11')->getDataType()); // Fraction

Expand Down
2 changes: 1 addition & 1 deletion tests/bootstrap.php
Expand Up @@ -3,4 +3,4 @@
setlocale(LC_ALL, 'en_US.utf8');

// PHP 5.3 Compat
date_default_timezone_set('Europe/London');
//date_default_timezone_set('Europe/London');