-
-
Notifications
You must be signed in to change notification settings - Fork 14
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
Extend calculations beyond the year 9999 #196
Comments
actually it would seem that PHP can handle dates / timestamps beyond the year 9999, it's ISO-8601 that defines a year to have exactly 4 digits, so ISO-8601 cannot represent a date beyond the year 9999. |
This will work on a 64 bit PHP: <?php
$date = new DateTime();
$date->setTimestamp(569941488000);
echo $date->format(DATE_ISO8601_EXPANDED);
//OUTPUT: +20030-09-23T00:00:00+00:00 However, we can only set the precalculated timestamp for a date. We cannot use any of the This is a way of doing so, say we want to calculate the timestamp for the date <?php
function countLeapYears($start_year, $end_year) {
return floor($end_year / 4) - floor(($start_year - 1) / 4)
- floor($end_year / 100) + floor(($start_year - 1) / 100)
+ floor($end_year / 400) - floor(($start_year - 1) / 400);
}
$baseTimestamp = strtotime('1970-05-11 00:00:00 UTC');
// Calculate the number of seconds from 1970 to 20030
$yearsDifference = 20030 - 1970;
$secondsPerDay = 24 * 60 * 60;
$secondsPerYear = 365 * $secondsPerDay; // Year length in seconds
$additionalSeconds = $yearsDifference * $secondsPerYear;
$leapYears = countLeapYears(1970, 20030);
$additionalSeconds += ($leapYears * $secondsPerDay); // account for leap years
// Add the additional seconds to the base timestamp
$futureTimestamp = $baseTimestamp + $additionalSeconds;
$date = new DateTime();
$date->setTimestamp($futureTimestamp);
echo $date->format(DATE_ISO8601_EXPANDED);
//OUTPUT: +20030-05-11T00:00:00+00:00 |
We can still do date calculations, and the <?php
function countLeapYears($start_year, $end_year) {
return floor($end_year / 4) - floor(($start_year - 1) / 4)
- floor($end_year / 100) + floor(($start_year - 1) / 100)
+ floor($end_year / 400) - floor(($start_year - 1) / 400);
}
$baseTimestamp = strtotime('1970-05-11 00:00:00 UTC');
// Calculate the number of seconds from 1970 to 20030
$yearsDifference = 20030 - 1970;
$secondsPerDay = 24 * 60 * 60;
$secondsPerYear = 365 * $secondsPerDay; // Year length in seconds
$additionalSeconds = $yearsDifference * $secondsPerYear;
$leapYears = countLeapYears(1970, 20030);
$additionalSeconds += ($leapYears * $secondsPerDay); // account for leap years
// Add the additional seconds to the base timestamp
$futureTimestamp = $baseTimestamp + $additionalSeconds;
$date = new DateTime();
$date->setTimestamp($futureTimestamp);
$date->modify('+1 day');
echo $date->format(DATE_ISO8601_EXPANDED); // OUTPUT the desired date plus one day
$formatter = IntlDateFormatter::create(
'it_IT',
IntlDateFormatter::FULL,
IntlDateFormatter::NONE,
'UTC'
);
echo PHP_EOL;
echo $formatter->format($futureTimestamp); // OUPUT the desired date in a specified locale OUTPUT: +20030-05-12T00:00:00+00:00
sabato 11 maggio 20030 |
The only drawback would be when we are validating schemas, timestamps would be fine but RFC formatted dates would not get validated correctly. We would just have to change our schemas to accept an alternative type, validated with regex for example... |
The current limit for dates within the range of the year 9999 is due to ISO8601's limit of a range between 0000-9999.
However PHP does seem to have a way to go beyond this range:
Perhaps we could implement this interface, and allow for years that go far beyond 9999. Making this calculator as close to truly perpetual as is currently possible by common computing standards.
The text was updated successfully, but these errors were encountered: