mirror of
https://github.com/PHPOffice/PhpSpreadsheet.git
synced 2026-08-24 17:38:16 +00:00
80a20fc991
* 100% Coverage for Calculation/DateTime
The code in DateTime is now completely covered.
Along the way, some errors were discovered and corrected.
- The tests which have had to be changed at the start of every year are
replaced by more robust equivalents which do not require annual changes.
- Several places in the code where Gnumeric and OpenOffice were thought to differ
from Excel do not appear to have had any justification.
I have left a comment where such code has been removed.
- Use DateTime when possible rather than date, time, or strftime functions to avoid
potential Y2038 problems.
- Some impossible code has been removed, replaced by an explanatory comment.
- NETWORKDAYS had a bug when the start date was Sunday. There had been no tests
of this condition.
- Some functions allow boolean and null arguments where a number is expected.
This is more complicated than the equivalent situations in MathTrig because
the initial date for these calculations can be Day 1 rather than Day 0.
- More testing for dates from 1900-01-01 through the fictitious
everywhere-but-Excel 1900-01-29.
- This showed that there is an additional Excel bug - Excel evaluates
WEEKNUM(emptycell) as 0, which is not a valid result for
WEEKNUM without a second argument.
PhpSpreadsheet now duplicates this bug.
- There is a similar and even worse bug for 1904-01-01 in 1904 calculations.
Weeknum returns 0 for this,
but returns the correct value for arguments of 0 or null.
- DATEVALUE should accept 1900-02-29 (sigh) and relatives.
PhpSpreadsheet now duplicates this bug.
- Testing bootstrap sets default timezone. This appears to be a relic from
the releases of PHP where the unwise decision, subsequenly reversed,
was made to issue messages for
"no default timezone is set" rather than just use a sensible default.
This was a disruptive setting for some of the tests I added.
There is only one test in the entire suite which is default-timezone-dependent.
Setting and resetting of default timezone is moved to that test
(Reader/ODS/ODSTest), and out of bootstrap.
- There had been no testing of NOW() function.
- DATEVALUE test had no tests for 1904 calendar and needs some.
- DATE test changed 1900/1904 calendar in use without restoring it.
- WEEKDAY test had no tests for 1904 calendar and needs some.
- Which revealed a bug in Shared/Date (excelToDateTimeObject was not
recognizing 1904-01-01 as valid when 1904 calendar is in use).
- And an additional bug in that legal 1904-calendar values in the 0.0-1.0
range yielded the same "wrong" answers as 1900-calendar (see "One note" below).
Also the comment for one of the calendar-1904 tests was wrong in attempting
to identify what time of day the fraction represented.
I had wanted to break this up into a set of smaller modules, a process already
started for Engineering and MathTrig.
However the number of source code changes was sufficient that I wanted
a clean delta for this request.
If it is merged, I will work on breaking it up afterwards.
One note - Shared/Date/excelToDateTimeObject, when calendar-1900 is in use,
returns an unexpected result if its argument is between 0 and 1,
which is nominally invalid for that calendar.
It uses a base-1970 calendar in that instance. That check is not justifiable
for calendar-1904, where values in that range are legal,
so I made the check specific to calendar-1900,
and adjusted 3 1904 unit test results accordingly. However, I have to admit that
I don't understand why that check should be made even for calendar-1900.
It certainly doesn't match anything that Excel does.
I would recommend scrapping that code altogether.
If agreed, I would do this as part of the break-up into smaller modules.
Another note -
more controversially, it is clear that PhpSpreadsheet needs to support
the Excel and PHP date formats. Although it requires further study,
I am not convinced that it needs to support Unix timestamp format.
Since that is a potential source of Y2038 problems on 32-bit systems,
I would like to open a PR to deprecate the use of that format.
Please let me know if you are aware of a valid reason to continue to support it.
317 lines
5.8 KiB
PHP
317 lines
5.8 KiB
PHP
<?php
|
|
|
|
// Date String, Result
|
|
|
|
return [
|
|
[
|
|
'#VALUE!',
|
|
'25-Dec-1899',
|
|
],
|
|
[
|
|
'#VALUE!',
|
|
'31-Dec-1899',
|
|
],
|
|
[
|
|
1,
|
|
'1-Jan-1900',
|
|
],
|
|
[
|
|
59,
|
|
'1900/2/28',
|
|
],
|
|
[
|
|
'60',
|
|
'29-02-1900',
|
|
],
|
|
// MS Excel will fail with a #VALUE return, but PhpSpreadsheet can parse this date
|
|
[
|
|
'60',
|
|
'29th February 1900',
|
|
],
|
|
[
|
|
61,
|
|
'1900/3/1',
|
|
],
|
|
[
|
|
713,
|
|
'13-12-1901',
|
|
],
|
|
[
|
|
714,
|
|
'14-12-1901',
|
|
],
|
|
[
|
|
1461,
|
|
'1903/12/31',
|
|
],
|
|
[
|
|
1462,
|
|
'1-Jan-1904',
|
|
],
|
|
// MS Excel will fail with a #VALUE return, but PhpSpreadsheet can parse this date
|
|
[
|
|
1463,
|
|
'2nd-Jan-1904',
|
|
],
|
|
[
|
|
22269,
|
|
'19-12-1960',
|
|
],
|
|
// MS Excel will fail with a #VALUE return, but PhpSpreadsheet can parse this date
|
|
[
|
|
25569,
|
|
'1st January 1970',
|
|
],
|
|
[
|
|
30292,
|
|
'7-Dec-1982',
|
|
],
|
|
[
|
|
39448,
|
|
'1-1-2008',
|
|
],
|
|
[
|
|
50424,
|
|
'2038-01-19',
|
|
],
|
|
[
|
|
39601,
|
|
'2-6-2008',
|
|
],
|
|
// MS Excel will fail with a #VALUE return, but PhpSpreadsheet can parse this date
|
|
[
|
|
39807,
|
|
'December 25th 2008',
|
|
],
|
|
[
|
|
39448,
|
|
'1 Jan-2008',
|
|
],
|
|
// MS Excel success or failure dependent on country settings
|
|
[
|
|
39813,
|
|
'12-31-2008',
|
|
],
|
|
// PhpSpreadsheet tries to handle both US and UK formats, irrespective of country settings
|
|
[
|
|
39813,
|
|
'31-12-2008',
|
|
],
|
|
// MS Excel success or failure dependent on country settings
|
|
[
|
|
39682,
|
|
'8/22/2008',
|
|
],
|
|
// PhpSpreadsheet tries to handle both US and UK formats, irrespective of country settings
|
|
[
|
|
39682,
|
|
'22/8/2008',
|
|
],
|
|
[
|
|
39682,
|
|
'22/8/08',
|
|
],
|
|
[
|
|
39682,
|
|
'22-AUG-2008',
|
|
],
|
|
[
|
|
39501,
|
|
'2008/02/23',
|
|
],
|
|
[
|
|
39635,
|
|
'6-7-2008',
|
|
],
|
|
// MS Excel success or failure dependent on country settings
|
|
[
|
|
39141,
|
|
'28-2-2007',
|
|
],
|
|
// PhpSpreadsheet tries to handle both US and UK formats, irrespective of country settings
|
|
[
|
|
39141,
|
|
'2-28-2007',
|
|
],
|
|
// Should fail because it's an invalid date, but PhpSpreadsheet currently adjusts to 1-3-2007 - FIX NEEDED
|
|
[
|
|
'#VALUE!',
|
|
'29-2-2007',
|
|
],
|
|
[
|
|
36161,
|
|
'1/1/1999',
|
|
],
|
|
[
|
|
19925,
|
|
'1954-07-20',
|
|
],
|
|
[
|
|
36029,
|
|
'22 August 98',
|
|
],
|
|
// MS Excel will fail with a #VALUE return, but PhpSpreadsheet can parse this date
|
|
[
|
|
39142,
|
|
'1st March 2007',
|
|
],
|
|
[
|
|
'#VALUE!',
|
|
'The 1st day of March 2007',
|
|
],
|
|
// Jan 1 of the current year
|
|
[
|
|
'Y-01-01',
|
|
'1 Jan',
|
|
],
|
|
// Dec 31 of the current year
|
|
[
|
|
'Y-12-31',
|
|
'31/12',
|
|
],
|
|
// Excel reads as 1st December 1931, not 31st December in current year.
|
|
// This result is locale-dependent in Excel, in a manner not
|
|
// supported by PhpSpreadsheet.
|
|
[
|
|
11658,
|
|
'12/31',
|
|
],
|
|
// July 5 of the current year
|
|
[
|
|
'Y-07-05',
|
|
'5-JUL',
|
|
],
|
|
// July 5 of the current year
|
|
[
|
|
'Y-07-05',
|
|
'5 July',
|
|
],
|
|
[
|
|
39783,
|
|
'12/2008',
|
|
],
|
|
[
|
|
11963,
|
|
'10/32',
|
|
],
|
|
[
|
|
'#VALUE!',
|
|
11,
|
|
],
|
|
[
|
|
'#VALUE!',
|
|
true,
|
|
],
|
|
[
|
|
'#VALUE!',
|
|
false,
|
|
],
|
|
[
|
|
'#VALUE!',
|
|
1,
|
|
],
|
|
[
|
|
'#VALUE!',
|
|
12345,
|
|
],
|
|
[
|
|
'#VALUE!',
|
|
12,
|
|
],
|
|
// implicit day of month is 1
|
|
[
|
|
40210,
|
|
'Feb-2010',
|
|
],
|
|
[
|
|
40221,
|
|
'12-Feb-2010',
|
|
],
|
|
// MS Excel will fail with a #VALUE return, but PhpSpreadsheet can parse this date
|
|
[
|
|
40221,
|
|
'Feb-12-2010',
|
|
],
|
|
// MS Excel will fail with a #VALUE return, but PhpSpreadsheet can parse this date
|
|
[
|
|
40221,
|
|
'February-12-2010',
|
|
],
|
|
// MS Excel will fail with a #VALUE return, but PhpSpreadsheet can parse this date
|
|
[
|
|
40221,
|
|
'February 12 2010',
|
|
],
|
|
[
|
|
40227,
|
|
'18 Feb 2010',
|
|
],
|
|
// MS Excel will fail with a #VALUE return, but PhpSpreadsheet can parse this date
|
|
[
|
|
40254,
|
|
'17th 3rd 2010',
|
|
],
|
|
// MS Excel will fail with a #VALUE return, but PhpSpreadsheet can parse this date
|
|
[
|
|
40227,
|
|
'Feb 18th 2010',
|
|
],
|
|
// MS Excel will fail with a #VALUE return, but PhpSpreadsheet can parse this date
|
|
[
|
|
40210,
|
|
'1st Feb 2010',
|
|
],
|
|
// MS Excel will fail with a #VALUE return, but PhpSpreadsheet can parse this date
|
|
[
|
|
40210,
|
|
'1st-Feb-2010',
|
|
],
|
|
[
|
|
'#VALUE!',
|
|
'1me Fev 2010',
|
|
],
|
|
// MS Excel will fail with a #VALUE return, but PhpSpreadsheet can parse this date
|
|
[
|
|
40210,
|
|
'February 1st 2010',
|
|
],
|
|
// MS Excel will fail with a #VALUE return, but PhpSpreadsheet can parse this date
|
|
[
|
|
40211,
|
|
'2nd Feb 2010',
|
|
],
|
|
[
|
|
'#VALUE!',
|
|
'Second Feb 2010',
|
|
],
|
|
[
|
|
'#VALUE!',
|
|
'First August 2010',
|
|
],
|
|
// MS Excel will fail with a #VALUE return, but PhpSpreadsheet can parse this date
|
|
[
|
|
40391,
|
|
'1st August 2010',
|
|
],
|
|
[
|
|
0,
|
|
'15:30:25',
|
|
],
|
|
[
|
|
'#VALUE!',
|
|
'ABCDEFGHIJKMNOPQRSTUVWXYZ',
|
|
],
|
|
[
|
|
'#VALUE!',
|
|
'1999',
|
|
],
|
|
['#VALUE!', '32/32'],
|
|
['#VALUE!', '1910-'],
|
|
['#VALUE!', '10--'],
|
|
['#VALUE!', '--10'],
|
|
['#VALUE!', '--1910'],
|
|
//['#VALUE!', '-JUL-1910'], We can parse this, Excel can't
|
|
['#VALUE!', '2008-08-'],
|
|
[36751, '0-08-13'],
|
|
];
|