| 1 |
<?php |
| 2 |
|
| 3 |
namespace TablePress\PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel; |
| 4 |
|
| 5 |
use TablePress\Composer\Pcre\Preg; |
| 6 |
use DateTime; |
| 7 |
use TablePress\PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; |
| 8 |
use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Functions; |
| 9 |
use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; |
| 10 |
use TablePress\PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper; |
| 11 |
|
| 12 |
class TimeValue |
| 13 |
{ |
| 14 |
use ArrayEnabled; |
| 15 |
|
| 16 |
private const EXTRACT_TIME = '/\b' |
| 17 |
. '(\d+)' // match[1] - hour |
| 18 |
. '(:' // start of match[2] (rest of string) - colon |
| 19 |
. '(\d+' // start of match[3] - minute |
| 20 |
. '(:\d+' // start of match[4] - colon and seconds |
| 21 |
. '([.]\d+)?' // match[5] - optional decimal point followed by fractional seconds |
| 22 |
. ')?' // end of match[4], which is optional |
| 23 |
. ')' // end of match 3 |
| 24 |
// Excel does not require 'm' to trail 'a' or 'p'; Php does |
| 25 |
. '(\s*(a|p))?' // match[6] optional whitespace followed by optional match[7] a or p |
| 26 |
. ')' // end of match[2] |
| 27 |
. '/i'; |
| 28 |
|
| 29 |
/** |
| 30 |
* TIMEVALUE. |
| 31 |
* |
| 32 |
* Returns a value that represents a particular time. |
| 33 |
* Use TIMEVALUE to convert a time represented by a text string to an Excel or PHP date/time stamp |
| 34 |
* value. |
| 35 |
* |
| 36 |
* NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the time |
| 37 |
* format of your regional settings. PhpSpreadsheet does not change cell formatting in this way. |
| 38 |
* |
| 39 |
* Excel Function: |
| 40 |
* TIMEVALUE(timeValue) |
| 41 |
* |
| 42 |
* @param null|array<mixed>|bool|float|int|string $timeValue A text string that represents a time in any one of the Microsoft |
| 43 |
* Excel time formats; for example, "6:45 PM" and "18:45" text strings |
| 44 |
* within quotation marks that represent time. |
| 45 |
* Date information in time_text is ignored. |
| 46 |
* Or can be an array of date/time values |
| 47 |
* |
| 48 |
* @return array<mixed>|DateTime|float|int|string Excel date/time serial value, PHP date/time serial value or PHP date/time object, |
| 49 |
* depending on the value of the ReturnDateType flag |
| 50 |
* If an array of numbers is passed as the argument, then the returned result will also be an array |
| 51 |
* with the same dimensions |
| 52 |
*/ |
| 53 |
public static function fromString($timeValue) |
| 54 |
{ |
| 55 |
if (is_array($timeValue)) { |
| 56 |
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $timeValue); |
| 57 |
} |
| 58 |
|
| 59 |
// try to parse as time iff there is at least one digit |
| 60 |
if (is_string($timeValue) && !Preg::isMatch('/\d/', $timeValue)) { |
| 61 |
return ExcelError::VALUE(); |
| 62 |
} |
| 63 |
|
| 64 |
$timeValue = trim((string) $timeValue, '"'); |
| 65 |
if (Preg::isMatch(self::EXTRACT_TIME, $timeValue, $matches)) { |
| 66 |
if (empty($matches[6])) { // am/pm |
| 67 |
$hour = (int) $matches[0]; |
| 68 |
$timeValue = ($hour % 24) . $matches[2]; |
| 69 |
} elseif ($matches[6] === $matches[7]) { // Excel wants space before am/pm |
| 70 |
return ExcelError::VALUE(); |
| 71 |
} else { |
| 72 |
$timeValue = $matches[0] . 'm'; |
| 73 |
} |
| 74 |
} |
| 75 |
|
| 76 |
$PHPDateArray = Helpers::dateParse($timeValue); |
| 77 |
$retValue = ExcelError::VALUE(); |
| 78 |
if (Helpers::dateParseSucceeded($PHPDateArray)) { |
| 79 |
$hour = $PHPDateArray['hour']; |
| 80 |
$minute = $PHPDateArray['minute']; |
| 81 |
$second = $PHPDateArray['second']; |
| 82 |
// OpenOffice-specific code removed - it works just like Excel |
| 83 |
$excelDateValue = SharedDateHelper::formattedPHPToExcel(1900, 1, 1, $hour, $minute, $second) - 1; |
| 84 |
|
| 85 |
$retType = Functions::getReturnDateType(); |
| 86 |
if ($retType === Functions::RETURNDATE_EXCEL) { |
| 87 |
$retValue = (float) $excelDateValue; |
| 88 |
} elseif ($retType === Functions::RETURNDATE_UNIX_TIMESTAMP) { |
| 89 |
$retValue = (int) SharedDateHelper::excelToTimestamp($excelDateValue + 25569) - 3600; |
| 90 |
} else { |
| 91 |
$retValue = new DateTime('1900-01-01 ' . $PHPDateArray['hour'] . ':' . $PHPDateArray['minute'] . ':' . $PHPDateArray['second']); |
| 92 |
} |
| 93 |
} |
| 94 |
|
| 95 |
return $retValue; |
| 96 |
} |
| 97 |
} |
| 98 |
|