Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pull Request: to handle Excel calendar dates ('Y-m-d') and Excel pure time (values (H:i) #7

Open
schoolshark opened this issue Nov 22, 2024 · 0 comments

Comments

@schoolshark
Copy link

Thank, you! Very nice work! I had to change Date.php and Value.php
to ensure proper conversion of Dates and Times.
Please include it in further releases.

Thank U
Stefan

// value.php
/**
* Transform numeric values, distinguishing between Excel calendar dates and pure time values.
*
* - If the value is associated with a date format (Styles::FORMAT_DATE), it is passed as a float
* to the Date transformer to handle both calendar dates and time values correctly.
* - Otherwise, the value is checked if it contains a decimal point to determine if it should be
* cast as a float (e.g., fractional day representing time) or an integer (e.g., whole numbers).
*/
private function transformNumber(string $style, mixed $value): DateTimeImmutable|float|int
{
return match (true) {
$style && Styles::FORMAT_DATE === $this->styles->get(index: (int) $style) => $this->dateTransformer->transform(value: (float) $value),
default => preg_match(pattern: '/^\d+.\d+$/', subject: $value) ? (float) $value : (int) $value,
};
}

//Date.php
/**
* Transforms an Excel numeric value into a DateTimeImmutable object.
*
* - If the value is less than 1, it represents a pure time (e.g., 0.333333 for 08:00 a.m.).
* The value is converted into seconds since midnight and then transformed into an object
* containing only the time component.
* - If the value is 1 or greater, it represents a calendar date (optionally with time).
* The value is converted into a UNIX timestamp using the Excel epoch (1900-01-01) and
* transformed into a full DateTimeImmutable object.
*/
public function transform(float|int $value): DateTimeImmutable
{
// Handle pure time values (value < 1)
if ($value < 1) {
$totalSeconds = (int) round($value * 86400); // Convert fractional day to total seconds
$hours = floor($totalSeconds / 3600);
$minutes = floor(($totalSeconds % 3600) / 60);
// Create a DateTimeImmutable with only the time component
return new DateTimeImmutable(sprintf('%02d:%02d:00', $hours, $minutes));
}

    // Default/Standard: Handle full date or date-time values (value >= 1)
    $unix = (int) (($value - 25569) * 86400); // Convert Excel date to UNIX timestamp
    $date = gmdate(self::DATETIME_FORMAT, $unix);
    return date_create_immutable_from_format('!' . self::DATETIME_FORMAT, $date);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant