diff --git a/UPGRADING b/UPGRADING index 1bc576d007ce6..a9306231eaf87 100644 --- a/UPGRADING +++ b/UPGRADING @@ -303,6 +303,10 @@ PHP 8.3 UPGRADE NOTES significant digits before the decimal point. Previously negative $decimals got silently ignored and the number got rounded to zero decimal places. +- Calendar + . easter_date() now supports years from 1970 to 2,000,000,000 on 64-bit systems, + previously it only supported years in the range from 1970 to 2037. + ======================================== 6. New Functions ======================================== diff --git a/ext/calendar/easter.c b/ext/calendar/easter.c index c319abd17fef0..579e8af72eac2 100644 --- a/ext/calendar/easter.c +++ b/ext/calendar/easter.c @@ -13,6 +13,7 @@ | Authors: Shane Caraveo | | Colin Viebrock | | Hartmut Holzgraefe | + | Arne Perschke | +----------------------------------------------------------------------+ */ @@ -21,6 +22,10 @@ #include "sdncal.h" #include +/** + * If `gm` is true this will return the timestamp at midnight on Easter of the given year. If it is false this + * will return the number of days Easter is after March 21st. + */ static void _cal_easter(INTERNAL_FUNCTION_PARAMETERS, bool gm) { /* based on code by Simon Kershaw, */ @@ -48,10 +53,27 @@ static void _cal_easter(INTERNAL_FUNCTION_PARAMETERS, bool gm) } } - if (gm && (year<1970 || year>2037)) { /* out of range for timestamps */ + #ifdef ZEND_ENABLE_ZVAL_LONG64 + /* Compiling for 64bit, allow years between 1970 and 2.000.000.000 */ + if (gm && year < 1970) { + /* timestamps only start after 1970 */ + zend_argument_value_error(1, "must be a year after 1970 (inclusive)"); + RETURN_THROWS(); + } + + if (gm && year > 2000000000) { + /* timestamps only go up to the year 2.000.000.000 */ + zend_argument_value_error(1, "must be a year before 2.000.000.000 (inclusive)"); + RETURN_THROWS(); + } + #else + /* Compiling for 32bit, allow years between 1970 and 2037 */ + if (gm && (year < 1970 || year > 2037)) { zend_argument_value_error(1, "must be between 1970 and 2037 (inclusive)"); RETURN_THROWS(); } + #endif + golden = (year % 19) + 1; /* the Golden number */ diff --git a/ext/calendar/tests/easter_date.phpt b/ext/calendar/tests/easter_date_32bit.phpt similarity index 81% rename from ext/calendar/tests/easter_date.phpt rename to ext/calendar/tests/easter_date_32bit.phpt index a41c310de9b89..52f880edc1131 100644 --- a/ext/calendar/tests/easter_date.phpt +++ b/ext/calendar/tests/easter_date_32bit.phpt @@ -1,5 +1,7 @@ --TEST-- -easter_date() +Test easter_date() on 32bit systems +--SKIPIF-- + --INI-- date.timezone=UTC --ENV-- diff --git a/ext/calendar/tests/easter_date_64bit.phpt b/ext/calendar/tests/easter_date_64bit.phpt new file mode 100644 index 0000000000000..3939b7e4a4d41 --- /dev/null +++ b/ext/calendar/tests/easter_date_64bit.phpt @@ -0,0 +1,33 @@ +--TEST-- +Test easter_date() on 64bit systems +--SKIPIF-- + +--INI-- +date.timezone=UTC +--ENV-- +TZ=UTC +--EXTENSIONS-- +calendar +--FILE-- +getMessage()}\n"; +} +?> +--EXPECT-- +2000-04-23 +2001-04-15 +2002-03-31 +2045-04-09 +2046-03-25 +2047-04-14 +easter_date(): Argument #1 ($year) must be a year after 1970 (inclusive) diff --git a/ext/calendar/tests/easter_date_checks_upper_bound_32bit.phpt b/ext/calendar/tests/easter_date_checks_upper_bound_32bit.phpt new file mode 100644 index 0000000000000..6a9cee8027fb7 --- /dev/null +++ b/ext/calendar/tests/easter_date_checks_upper_bound_32bit.phpt @@ -0,0 +1,21 @@ +--TEST-- +Test easter_date() on 32bit systems checks the upper year limit +--SKIPIF-- + +--INI-- +date.timezone=UTC +--ENV-- +TZ=UTC +--EXTENSIONS-- +calendar +--FILE-- +getMessage()}\n"; +} +?> +--EXPECT-- +easter_date(): Argument #1 ($year) must be between 1970 and 2037 (inclusive) diff --git a/ext/calendar/tests/easter_date_checks_upper_bound_64bit.phpt b/ext/calendar/tests/easter_date_checks_upper_bound_64bit.phpt new file mode 100644 index 0000000000000..2c7afbdfa2d97 --- /dev/null +++ b/ext/calendar/tests/easter_date_checks_upper_bound_64bit.phpt @@ -0,0 +1,21 @@ +--TEST-- +Test easter_date() on 64bit systems checks the upper year limit +--SKIPIF-- + +--INI-- +date.timezone=UTC +--ENV-- +TZ=UTC +--EXTENSIONS-- +calendar +--FILE-- +getMessage()}\n"; +} +?> +--EXPECT-- +easter_date(): Argument #1 ($year) must be a year before 2.000.000.000 (inclusive)