AutorÃa | Ultima modificación | Ver Log |
<?phpnamespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;use DateTime;use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;use PhpOffice\PhpSpreadsheet\Calculation\Exception;use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;class Week{use ArrayEnabled;/*** WEEKNUM.** Returns the week of the year for a specified date.* The WEEKNUM function considers the week containing January 1 to be the first week of the year.* However, there is a European standard that defines the first week as the one with the majority* of days (four or more) falling in the new year. This means that for years in which there are* three days or less in the first week of January, the WEEKNUM function returns week numbers* that are incorrect according to the European standard.** Excel Function:* WEEKNUM(dateValue[,style])** @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),* PHP DateTime object, or a standard date string* Or can be an array of date values* @param array|int $method Week begins on Sunday or Monday* 1 or omitted Week begins on Sunday.* 2 Week begins on Monday.* 11 Week begins on Monday.* 12 Week begins on Tuesday.* 13 Week begins on Wednesday.* 14 Week begins on Thursday.* 15 Week begins on Friday.* 16 Week begins on Saturday.* 17 Week begins on Sunday.* 21 ISO (Jan. 4 is week 1, begins on Monday).* Or can be an array of methods** @return array|int|string Week Number* If an array of values is passed as the argument, then the returned result will also be an array* with the same dimensions*/public static function number(mixed $dateValue, array|int|string|null $method = Constants::STARTWEEK_SUNDAY): array|int|string{if (is_array($dateValue) || is_array($method)) {return self::evaluateArrayArguments([self::class, __FUNCTION__], $dateValue, $method);}$origDateValueNull = empty($dateValue);try {$method = self::validateMethod($method);if ($dateValue === null) { // boolean not allowed$dateValue = (SharedDateHelper::getExcelCalendar() === SharedDateHelper::CALENDAR_MAC_1904 || $method === Constants::DOW_SUNDAY) ? 0 : 1;}$dateValue = self::validateDateValue($dateValue);if (!$dateValue && self::buggyWeekNum1900($method)) {// This seems to be an additional Excel bug.return 0;}} catch (Exception $e) {return $e->getMessage();}// Execute function$PHPDateObject = SharedDateHelper::excelToDateTimeObject($dateValue);if ($method == Constants::STARTWEEK_MONDAY_ISO) {Helpers::silly1900($PHPDateObject);return (int) $PHPDateObject->format('W');}if (self::buggyWeekNum1904($method, $origDateValueNull, $PHPDateObject)) {return 0;}Helpers::silly1900($PHPDateObject, '+ 5 years'); // 1905 calendar matches$dayOfYear = (int) $PHPDateObject->format('z');$PHPDateObject->modify('-' . $dayOfYear . ' days');$firstDayOfFirstWeek = (int) $PHPDateObject->format('w');$daysInFirstWeek = (6 - $firstDayOfFirstWeek + $method) % 7;$daysInFirstWeek += 7 * !$daysInFirstWeek;$endFirstWeek = $daysInFirstWeek - 1;$weekOfYear = floor(($dayOfYear - $endFirstWeek + 13) / 7);return (int) $weekOfYear;}/*** ISOWEEKNUM.** Returns the ISO 8601 week number of the year for a specified date.** Excel Function:* ISOWEEKNUM(dateValue)** @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),* PHP DateTime object, or a standard date string* Or can be an array of date values** @return array|int|string Week Number* If an array of numbers is passed as the argument, then the returned result will also be an array* with the same dimensions*/public static function isoWeekNumber(mixed $dateValue): array|int|string{if (is_array($dateValue)) {return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $dateValue);}if (self::apparentBug($dateValue)) {return 52;}try {$dateValue = Helpers::getDateValue($dateValue);} catch (Exception $e) {return $e->getMessage();}// Execute function$PHPDateObject = SharedDateHelper::excelToDateTimeObject($dateValue);Helpers::silly1900($PHPDateObject);return (int) $PHPDateObject->format('W');}/*** WEEKDAY.** Returns the day of the week for a specified date. The day is given as an integer* ranging from 0 to 7 (dependent on the requested style).** Excel Function:* WEEKDAY(dateValue[,style])** @param null|array|bool|float|int|string $dateValue Excel date serial value (float), PHP date timestamp (integer),* PHP DateTime object, or a standard date string* Or can be an array of date values* @param mixed $style A number that determines the type of return value* 1 or omitted Numbers 1 (Sunday) through 7 (Saturday).* 2 Numbers 1 (Monday) through 7 (Sunday).* 3 Numbers 0 (Monday) through 6 (Sunday).* Or can be an array of styles** @return array|int|string Day of the week value* If an array of values is passed as the argument, then the returned result will also be an array* with the same dimensions*/public static function day(null|array|float|int|string|bool $dateValue, mixed $style = 1): array|string|int{if (is_array($dateValue) || is_array($style)) {return self::evaluateArrayArguments([self::class, __FUNCTION__], $dateValue, $style);}try {$dateValue = Helpers::getDateValue($dateValue);$style = self::validateStyle($style);} catch (Exception $e) {return $e->getMessage();}// Execute function$PHPDateObject = SharedDateHelper::excelToDateTimeObject($dateValue);Helpers::silly1900($PHPDateObject);$DoW = (int) $PHPDateObject->format('w');switch ($style) {case 1:++$DoW;break;case 2:$DoW = self::dow0Becomes7($DoW);break;case 3:$DoW = self::dow0Becomes7($DoW) - 1;break;}return $DoW;}/*** @param mixed $style expect int*/private static function validateStyle(mixed $style): int{if (!is_numeric($style)) {throw new Exception(ExcelError::VALUE());}$style = (int) $style;if (($style < 1) || ($style > 3)) {throw new Exception(ExcelError::NAN());}return $style;}private static function dow0Becomes7(int $DoW): int{return ($DoW === 0) ? 7 : $DoW;}/*** @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer),* PHP DateTime object, or a standard date string*/private static function apparentBug(mixed $dateValue): bool{if (SharedDateHelper::getExcelCalendar() !== SharedDateHelper::CALENDAR_MAC_1904) {if (is_bool($dateValue)) {return true;}if (is_numeric($dateValue) && !((int) $dateValue)) {return true;}}return false;}/*** Validate dateValue parameter.*/private static function validateDateValue(mixed $dateValue): float{if (is_bool($dateValue)) {throw new Exception(ExcelError::VALUE());}return Helpers::getDateValue($dateValue);}/*** Validate method parameter.*/private static function validateMethod(mixed $method): int{if ($method === null) {$method = Constants::STARTWEEK_SUNDAY;}if (!is_numeric($method)) {throw new Exception(ExcelError::VALUE());}$method = (int) $method;if (!array_key_exists($method, Constants::METHODARR)) {throw new Exception(ExcelError::NAN());}$method = Constants::METHODARR[$method];return $method;}private static function buggyWeekNum1900(int $method): bool{return $method === Constants::DOW_SUNDAY && SharedDateHelper::getExcelCalendar() === SharedDateHelper::CALENDAR_WINDOWS_1900;}private static function buggyWeekNum1904(int $method, bool $origNull, DateTime $dateObject): bool{// This appears to be another Excel bug.return $method === Constants::DOW_SUNDAY && SharedDateHelper::getExcelCalendar() === SharedDateHelper::CALENDAR_MAC_1904&& !$origNull && $dateObject->format('Y-m-d') === '1904-01-01';}}