# tablepress/3.4/libraries/vendor/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php

TablePress – Tables in WordPress made easy, version 3.4. 331 lines.

- Page: https://pluginprobe.com/plugins/tablepress/3.4/code/libraries/vendor/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php
- Raw: https://pluginprobe.com/plugins/tablepress/3.4/raw/libraries/vendor/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php
- Modified: 2026-09-30T03:50:46+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/tablepress/3.4/code/libraries/vendor/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php#L10-L20`.

```php
<?php

namespace TablePress\PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;

use DateTime;
use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Exception;
use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Functions;
use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
use TablePress\PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
use Throwable;

class Helpers
{
	/**
	 * Identify if a year is a leap year or not.
	 *
	 * @param int|string $year The year to test
	 *
	 * @return bool TRUE if the year is a leap year, otherwise FALSE
	 */
	public static function isLeapYear($year): bool
	{
		$year = (int) $year;

		return (($year % 4) === 0) && (($year % 100) !== 0) || (($year % 400) === 0);
	}

	/**
				 * getDateValue.
				 *
				 * @return float Excel date/time serial value
				 * @param mixed $dateValue
				 */
				public static function getDateValue($dateValue, bool $allowBool = true, ?int $calendar = null): float
	{
		if (is_object($dateValue)) {
			$retval = SharedDateHelper::PHPToExcel($dateValue, $calendar);
			if (is_bool($retval)) {
				throw new Exception(ExcelError::VALUE());
			}

			return $retval;
		}

		self::nullFalseTrueToNumber($dateValue, $allowBool, $calendar);
		if (!is_numeric($dateValue)) {
			$saveReturnDateType = Functions::getReturnDateType();
			Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
			if (is_string($dateValue)) {
				$dateValue = DateValue::fromString($dateValue);
			}
			Functions::setReturnDateType($saveReturnDateType);
			if (!is_numeric($dateValue)) {
				throw new Exception(ExcelError::VALUE());
			}
		}
		if ($dateValue < 0 && Functions::getCompatibilityMode() !== Functions::COMPATIBILITY_OPENOFFICE) {
			throw new Exception(ExcelError::NAN());
		}

		try {
			SharedDateHelper::excelToDateTimeObject((float) $dateValue, null, $calendar);
		} catch (Throwable $exception) {
			throw new Exception(ExcelError::NAN());
		}

		return (float) $dateValue;
	}

	/**
	 * getTimeValue.
	 *
	 * @return float|string Excel date/time serial value, or string if error
	 */
	public static function getTimeValue(string $timeValue)
	{
		$saveReturnDateType = Functions::getReturnDateType();
		Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
		/** @var float|string $timeValue */
		$timeValue = TimeValue::fromString($timeValue);
		Functions::setReturnDateType($saveReturnDateType);

		return $timeValue;
	}

	/**
	 * Adjust date by given months.
	 *
	 * @param float|int $dateValue date to be adjusted
	 */
	public static function adjustDateByMonths($dateValue = 0, float $adjustmentMonths = 0, ?int $calendar = null): DateTime
	{
		// Execute function
		$PHPDateObject = SharedDateHelper::excelToDateTimeObject($dateValue, null, $calendar);
		$oMonth = (int) $PHPDateObject->format('m');
		$oYear = (int) $PHPDateObject->format('Y');

		$adjustmentMonthsString = (string) $adjustmentMonths;
		if ($adjustmentMonths > 0) {
			$adjustmentMonthsString = '+' . $adjustmentMonths;
		}
		if ($adjustmentMonths != 0) {
			$PHPDateObject->modify($adjustmentMonthsString . ' months');
		}
		$nMonth = (int) $PHPDateObject->format('m');
		$nYear = (int) $PHPDateObject->format('Y');

		$monthDiff = ($nMonth - $oMonth) + (($nYear - $oYear) * 12);
		if ($monthDiff != $adjustmentMonths) {
			$adjustDays = (int) $PHPDateObject->format('d');
			$adjustDaysString = '-' . $adjustDays . ' days';
			$PHPDateObject->modify($adjustDaysString);
		}

		return $PHPDateObject;
	}

	/**
				 * Help reduce perceived complexity of some tests.
				 * @param mixed $value
				 * @param mixed $altValue
				 */
				public static function replaceIfEmpty(&$value, $altValue): void
	{
		$value = $value ?: $altValue;
	}

	/**
	 * Adjust year in ambiguous situations.
	 */
	public static function adjustYear(string $testVal1, string $testVal2, string &$testVal3): void
	{
		if (!is_numeric($testVal1) || $testVal1 < 31) {
			if (!is_numeric($testVal2) || $testVal2 < 12) {
				if (is_numeric($testVal3) && $testVal3 < 12) {
					$testVal3 = (string) ($testVal3 + 2000);
				}
			}
		}
	}

	/**
				 * Return result in one of three formats.
				 *
				 * @param array{year: int, month: int, day: int, hour: int, minute: int, second: int} $dateArray
				 * @return \DateTime|float|int
				 */
				public static function returnIn3FormatsArray(array $dateArray, bool $noFrac = false, ?int $calendar = null)
	{
		$retType = Functions::getReturnDateType();
		if ($retType === Functions::RETURNDATE_PHP_DATETIME_OBJECT) {
			return new DateTime(
				$dateArray['year']
				. '-' . $dateArray['month']
				. '-' . $dateArray['day']
				. ' ' . $dateArray['hour']
				. ':' . $dateArray['minute']
				. ':' . $dateArray['second']
			);
		}
		$excelDateValue
			= SharedDateHelper::formattedPHPToExcel(
				$dateArray['year'],
				$dateArray['month'],
				$dateArray['day'],
				$dateArray['hour'],
				$dateArray['minute'],
				$dateArray['second'],
				$calendar
			);
		if ($retType === Functions::RETURNDATE_EXCEL) {
			return $noFrac ? floor($excelDateValue) : $excelDateValue;
		}
		// RETURNDATE_UNIX_TIMESTAMP)

		return SharedDateHelper::excelToTimestamp($excelDateValue, null, $calendar);
	}

	/**
				 * Return result in one of three formats.
				 * @return float|int|\DateTime
				 */
				public static function returnIn3FormatsFloat(float $excelDateValue, ?int $calendar = null)
	{
		$retType = Functions::getReturnDateType();
		if ($retType === Functions::RETURNDATE_EXCEL) {
			return $excelDateValue;
		}
		if ($retType === Functions::RETURNDATE_UNIX_TIMESTAMP) {
			return SharedDateHelper::excelToTimestamp($excelDateValue, null, $calendar);
		}
		// RETURNDATE_PHP_DATETIME_OBJECT

		return SharedDateHelper::excelToDateTimeObject($excelDateValue, null, $calendar);
	}

	/**
				 * Return result in one of three formats.
				 * @return \DateTime|float|int
				 */
				public static function returnIn3FormatsObject(DateTime $PHPDateObject, ?int $calendar = null)
	{
		$retType = Functions::getReturnDateType();
		if ($retType === Functions::RETURNDATE_PHP_DATETIME_OBJECT) {
			return $PHPDateObject;
		}
		if ($retType === Functions::RETURNDATE_EXCEL) {
			return (float) SharedDateHelper::PHPToExcel($PHPDateObject, $calendar);
		}
		// RETURNDATE_UNIX_TIMESTAMP
		$stamp = SharedDateHelper::PHPToExcel($PHPDateObject, $calendar);
		$stamp = is_bool($stamp) ? ((int) $stamp) : $stamp;

		return SharedDateHelper::excelToTimestamp($stamp, null, $calendar);
	}

	private static function baseDate(?int $calendar): int
	{
		if (Functions::getCompatibilityMode() === Functions::COMPATIBILITY_OPENOFFICE) {
			return 0;
		}
		$calendar ??= SharedDateHelper::getExcelCalendar();
		if ($calendar === SharedDateHelper::CALENDAR_MAC_1904) {
			return 0;
		}

		return 1;
	}

	/**
				 * Many functions accept null/false/true argument treated as 0/0/1.
				 * @param mixed $number
				 */
				public static function nullFalseTrueToNumber(&$number, bool $allowBool = true, ?int $calendar = null): void
	{
		$number = Functions::flattenSingleValue($number);
		$nullVal = self::baseDate($calendar);
		if ($number === null) {
			$number = $nullVal;
		} elseif ($allowBool && is_bool($number)) {
			$number = $nullVal + (int) $number;
		}
	}

	/**
				 * Many functions accept null argument treated as 0.
				 * @return int|float
				 * @param mixed $number
				 */
				public static function validateNumericNull($number)
	{
		$number = Functions::flattenSingleValue($number);
		if ($number === null) {
			return 0;
		}
		if (is_int($number)) {
			return $number;
		}
		if (is_numeric($number)) {
			return (float) $number;
		}

		throw new Exception(ExcelError::VALUE());
	}

	/**
				 * Many functions accept null/false/true argument treated as 0/0/1.
				 *
				 * @phpstan-assert float $number
				 * @param mixed $number
				 */
				public static function validateNotNegative($number): float
	{
		if (!is_numeric($number)) {
			throw new Exception(ExcelError::VALUE());
		}
		if ($number >= 0) {
			return (float) $number;
		}

		throw new Exception(ExcelError::NAN());
	}

	public static function silly1900(DateTime $PHPDateObject, string $mod = '-1 day'): void
	{
		$isoDate = $PHPDateObject->format('c');
		if ($isoDate < '1900-03-01') {
			$PHPDateObject->modify($mod);
		}
	}

	/** @return array{year: int, month: int, day: int, hour: int, minute: int, second: int} */
	public static function dateParse(string $string): array
	{
		/** @var array{year: int, month: int, day: int, hour: int, minute: int, second: int} */
		$temp = self::forceArray(date_parse($string));

		return $temp;
	}

	/** @param mixed[] $dateArray */
	public static function dateParseSucceeded(array $dateArray): bool
	{
		return $dateArray['error_count'] === 0;
	}

	/**
	 * Despite documentation, date_parse probably never returns false.
	 * Just in case, this routine helps guarantee it.
	 *
	 * @param array<mixed>|false $dateArray
	 *
	 * @return mixed[]
	 */
	private static function forceArray($dateArray): array
	{
		return is_array($dateArray) ? $dateArray : ['error_count' => 1];
	}

	/**
				 * @return float|int
				 * @param mixed $value
				 */
				public static function floatOrInt($value)
	{
		$result = Functions::scalar($value);

		return is_numeric($result) ? ($result + 0) : 0;
	}
}

```
