Skip to content

Commit

Permalink
Xls Writer - Correct Timestamp Bug, Improve Coverage (#1493)
Browse files Browse the repository at this point in the history
* Xls Writer - Correct Timestamp Bug, Improve Coverage

I believe that Xls Writer is 100% covered now.

The Xls Writer sets its timestamp incorrectly. The problem is actually
in Shared/Ole::localDateToOLE, which converts its timestamp using
gmmktime; mktime is correct. If I save a file at 3:00 p.m. in San Francisco,
this bug means the time is actually recorded as 3:00 p.m. UTC.
A consequence of this is that if you use Phpspreadsheet to read the
file and save it as a new Xls, the creation timestamp goes further
and further back in time with each generation (or further forward
if east of Greenwich). One of the tests added confirms that
the creation timestamp is consistent with the start and end times
of the test.

The major change in coverage is adding tests to save GIF and BMP
images, which aren't supported in Xls, but are converted to PNG
in the PhpSpreadsheet code.
  • Loading branch information
oleibman authored Jun 19, 2020
1 parent a5a0268 commit b3d30f4
Show file tree
Hide file tree
Showing 5 changed files with 235 additions and 197 deletions.
Binary file added samples/images/bmp.bmp
Binary file not shown.
Binary file added samples/images/gif.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 4 additions & 5 deletions src/PhpSpreadsheet/Shared/OLE.php
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ public static function localDateToOLE($date)
// days from 1-1-1601 until the beggining of UNIX era
$days = 134774;
// calculate seconds
$big_date = $days * 24 * 3600 + gmmktime(date('H', $date), date('i', $date), date('s', $date), date('m', $date), date('d', $date), date('Y', $date));
$big_date = $days * 24 * 3600 + mktime((int) date('H', $date), (int) date('i', $date), (int) date('s', $date), (int) date('m', $date), (int) date('d', $date), (int) date('Y', $date));
// multiply just to make MS happy
$big_date *= 10000000;

Expand Down Expand Up @@ -558,10 +558,9 @@ public static function OLE2LocalDate($oleTimestamp)
// translate to seconds since 1970:
$unixTimestamp = floor(65536.0 * 65536.0 * $timestampHigh + $timestampLow - $days * 24 * 3600 + 0.5);

if ((int) $unixTimestamp == $unixTimestamp) {
return (int) $unixTimestamp;
}
$iTimestamp = (int) $unixTimestamp;

return $unixTimestamp >= 0.0 ? PHP_INT_MAX : PHP_INT_MIN;
// Overflow conditions can't happen on 64-bit system
return ($iTimestamp == $unixTimestamp) ? $iTimestamp : ($unixTimestamp >= 0.0 ? PHP_INT_MAX : PHP_INT_MIN);
}
}
Loading

0 comments on commit b3d30f4

Please sign in to comment.