DateTest.php 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. <?php
  2. namespace PhpOffice\PhpSpreadsheetTests\Shared;
  3. use DateTimeZone;
  4. use PhpOffice\PhpSpreadsheet\Exception;
  5. use PhpOffice\PhpSpreadsheet\Shared\Date;
  6. use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
  7. use PHPUnit\Framework\TestCase;
  8. class DateTest extends TestCase
  9. {
  10. /**
  11. * @var int
  12. */
  13. private $excelCalendar;
  14. /**
  15. * @var null|DateTimeZone
  16. */
  17. private $dttimezone;
  18. protected function setUp(): void
  19. {
  20. $this->dttimezone = Date::getDefaultTimeZoneOrNull();
  21. $this->excelCalendar = Date::getExcelCalendar();
  22. }
  23. protected function tearDown(): void
  24. {
  25. Date::setDefaultTimeZone($this->dttimezone);
  26. Date::setExcelCalendar($this->excelCalendar);
  27. }
  28. public function testSetExcelCalendar(): void
  29. {
  30. $calendarValues = [
  31. Date::CALENDAR_MAC_1904,
  32. Date::CALENDAR_WINDOWS_1900,
  33. ];
  34. foreach ($calendarValues as $calendarValue) {
  35. $result = Date::setExcelCalendar($calendarValue);
  36. self::assertTrue($result);
  37. }
  38. }
  39. public function testSetExcelCalendarWithInvalidValue(): void
  40. {
  41. $unsupportedCalendar = 2012;
  42. $result = Date::setExcelCalendar($unsupportedCalendar);
  43. self::assertFalse($result);
  44. }
  45. /**
  46. * @dataProvider providerDateTimeExcelToTimestamp1900
  47. *
  48. * @param mixed $expectedResult
  49. * @param mixed $excelDateTimeValue
  50. */
  51. public function testDateTimeExcelToTimestamp1900($expectedResult, $excelDateTimeValue): void
  52. {
  53. if (is_numeric($expectedResult) && ($expectedResult > PHP_INT_MAX || $expectedResult < PHP_INT_MIN)) {
  54. self::markTestSkipped('Test invalid on 32-bit system.');
  55. }
  56. Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
  57. $result = Date::excelToTimestamp($excelDateTimeValue);
  58. self::assertEquals($expectedResult, $result);
  59. }
  60. public function providerDateTimeExcelToTimestamp1900(): array
  61. {
  62. return require 'tests/data/Shared/Date/ExcelToTimestamp1900.php';
  63. }
  64. /**
  65. * @dataProvider providerDateTimeTimestampToExcel1900
  66. *
  67. * @param mixed $expectedResult
  68. * @param mixed $unixTimestamp
  69. */
  70. public function testDateTimeTimestampToExcel1900($expectedResult, $unixTimestamp): void
  71. {
  72. Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
  73. $result = Date::timestampToExcel($unixTimestamp);
  74. self::assertEqualsWithDelta($expectedResult, $result, 1E-5);
  75. }
  76. public function providerDateTimeTimestampToExcel1900(): array
  77. {
  78. return require 'tests/data/Shared/Date/TimestampToExcel1900.php';
  79. }
  80. /**
  81. * @dataProvider providerDateTimeDateTimeToExcel
  82. *
  83. * @param mixed $expectedResult
  84. * @param mixed $dateTimeObject
  85. */
  86. public function testDateTimeDateTimeToExcel($expectedResult, $dateTimeObject): void
  87. {
  88. Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
  89. $result = Date::dateTimeToExcel($dateTimeObject);
  90. self::assertEqualsWithDelta($expectedResult, $result, 1E-5);
  91. }
  92. public function providerDateTimeDateTimeToExcel(): array
  93. {
  94. return require 'tests/data/Shared/Date/DateTimeToExcel.php';
  95. }
  96. /**
  97. * @dataProvider providerDateTimeFormattedPHPToExcel1900
  98. *
  99. * @param mixed $expectedResult
  100. */
  101. public function testDateTimeFormattedPHPToExcel1900($expectedResult, ...$args): void
  102. {
  103. Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
  104. $result = Date::formattedPHPToExcel(...$args);
  105. self::assertEqualsWithDelta($expectedResult, $result, 1E-5);
  106. }
  107. public function providerDateTimeFormattedPHPToExcel1900(): array
  108. {
  109. return require 'tests/data/Shared/Date/FormattedPHPToExcel1900.php';
  110. }
  111. /**
  112. * @dataProvider providerDateTimeExcelToTimestamp1904
  113. *
  114. * @param mixed $expectedResult
  115. * @param mixed $excelDateTimeValue
  116. */
  117. public function testDateTimeExcelToTimestamp1904($expectedResult, $excelDateTimeValue): void
  118. {
  119. if (is_numeric($expectedResult) && ($expectedResult > PHP_INT_MAX || $expectedResult < PHP_INT_MIN)) {
  120. self::markTestSkipped('Test invalid on 32-bit system.');
  121. }
  122. Date::setExcelCalendar(Date::CALENDAR_MAC_1904);
  123. $result = Date::excelToTimestamp($excelDateTimeValue);
  124. self::assertEquals($expectedResult, $result);
  125. }
  126. public function providerDateTimeExcelToTimestamp1904(): array
  127. {
  128. return require 'tests/data/Shared/Date/ExcelToTimestamp1904.php';
  129. }
  130. /**
  131. * @dataProvider providerDateTimeTimestampToExcel1904
  132. *
  133. * @param mixed $expectedResult
  134. * @param mixed $unixTimestamp
  135. */
  136. public function testDateTimeTimestampToExcel1904($expectedResult, $unixTimestamp): void
  137. {
  138. Date::setExcelCalendar(Date::CALENDAR_MAC_1904);
  139. $result = Date::timestampToExcel($unixTimestamp);
  140. self::assertEqualsWithDelta($expectedResult, $result, 1E-5);
  141. }
  142. public function providerDateTimeTimestampToExcel1904(): array
  143. {
  144. return require 'tests/data/Shared/Date/TimestampToExcel1904.php';
  145. }
  146. /**
  147. * @dataProvider providerIsDateTimeFormatCode
  148. *
  149. * @param mixed $expectedResult
  150. */
  151. public function testIsDateTimeFormatCode($expectedResult, string $format): void
  152. {
  153. $result = Date::isDateTimeFormatCode($format);
  154. self::assertEquals($expectedResult, $result);
  155. }
  156. public function providerIsDateTimeFormatCode(): array
  157. {
  158. return require 'tests/data/Shared/Date/FormatCodes.php';
  159. }
  160. /**
  161. * @dataProvider providerDateTimeExcelToTimestamp1900Timezone
  162. *
  163. * @param mixed $expectedResult
  164. * @param mixed $excelDateTimeValue
  165. * @param mixed $timezone
  166. */
  167. public function testDateTimeExcelToTimestamp1900Timezone($expectedResult, $excelDateTimeValue, $timezone): void
  168. {
  169. if (is_numeric($expectedResult) && ($expectedResult > PHP_INT_MAX || $expectedResult < PHP_INT_MIN)) {
  170. self::markTestSkipped('Test invalid on 32-bit system.');
  171. }
  172. Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
  173. $result = Date::excelToTimestamp($excelDateTimeValue, $timezone);
  174. self::assertEquals($expectedResult, $result);
  175. }
  176. public function providerDateTimeExcelToTimestamp1900Timezone(): array
  177. {
  178. return require 'tests/data/Shared/Date/ExcelToTimestamp1900Timezone.php';
  179. }
  180. public function testConvertIsoDateError(): void
  181. {
  182. Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
  183. $this->expectException(Exception::class);
  184. $this->expectExceptionMessage('Non-string value supplied for Iso Date conversion');
  185. Date::convertIsoDate(false);
  186. }
  187. public function testVarious(): void
  188. {
  189. Date::setDefaultTimeZone('UTC');
  190. self::assertFalse(Date::stringToExcel('2019-02-29'));
  191. self::assertTrue((bool) Date::stringToExcel('2019-02-28'));
  192. self::assertTrue((bool) Date::stringToExcel('2019-02-28 11:18'));
  193. self::assertFalse(Date::stringToExcel('2019-02-28 11:71'));
  194. $date = Date::PHPToExcel('2020-01-01');
  195. self::assertEquals(43831.0, $date);
  196. $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
  197. $sheet = $spreadsheet->getActiveSheet();
  198. $sheet->setCellValue('B1', 'x');
  199. $val = $sheet->getCell('B1')->getValue();
  200. self::assertFalse(Date::timestampToExcel($val));
  201. $cell = $sheet->getCell('A1');
  202. self::assertNotNull($cell);
  203. $cell->setValue($date);
  204. $sheet->getStyle('A1')
  205. ->getNumberFormat()
  206. ->setFormatCode(NumberFormat::FORMAT_DATE_DATETIME);
  207. self::assertTrue(null !== $cell && Date::isDateTime($cell));
  208. $cella2 = $sheet->getCell('A2');
  209. self::assertNotNull($cella2);
  210. $cella2->setValue('=A1+2');
  211. $sheet->getStyle('A2')
  212. ->getNumberFormat()
  213. ->setFormatCode(NumberFormat::FORMAT_DATE_DATETIME);
  214. self::assertTrue(null !== $cella2 && Date::isDateTime($cella2));
  215. $cella3 = $sheet->getCell('A3');
  216. self::assertNotNull($cella3);
  217. $cella3->setValue('=A1+4');
  218. $sheet->getStyle('A3')
  219. ->getNumberFormat()
  220. ->setFormatCode('0.00E+00');
  221. self::assertFalse(null !== $cella3 && Date::isDateTime($cella3));
  222. }
  223. }