Skip to content

easter_date() reports inconsistent year ranges in errors and returns -1 for years after 3000 on Windows #23915

Description

@marc-mabe

Description

easter_date() has two problems with its year range:

  1. Inconsistent errors. The message depends on which internal check a year fails, not on the range that is actually valid:
  • 0 reports easter_days()'s range, "between 1 and 7378697629483820644", although easter_date() only accepts years from 1970.
  • 1969 reports only the lower bound, "must be a year after 1970 (inclusive)".
  • 2000000001 reports only the upper bound, "must be a year before 2.000.000.000 (inclusive)".
  • On 32-bit it is "between 1970 and 2037 (inclusive)".
  1. Windows: silent -1 above 3000. On 64-bit, years up to 2000000000 are allowed, but on Windows mktime() only goes up to the year 3000. For 3001 to 2000000000, easter_date() returns -1, which is mktime()'s error value, instead of throwing. date() then shows it as 1969-12-31.
<?php
putenv('TZ=UTC');
date_default_timezone_set('UTC');

foreach ([0, 1969, 1970, 3000, 3001, 2000000000, 2000000001] as $year) {
    echo $year, ': ';
    try {
        echo date('Y-m-d', easter_date($year)), PHP_EOL;
    } catch (ValueError $e) {
        echo $e->getMessage(), PHP_EOL;
    }
}

Resulted in this output (Linux 64-bit, PHP 8.4):

0: easter_date(): Argument #1 ($year) must be between 1 and 7378697629483820644
1969: easter_date(): Argument #1 ($year) must be a year after 1970 (inclusive)
1970: 1970-03-29
3000: 3000-04-13
3001: 3001-04-05
2000000000: 2000000000-04-23
2000000001: easter_date(): Argument #1 ($year) must be a year before 2.000.000.000 (inclusive)

Resulted in this output (Windows x64):

0: easter_date(): Argument #1 ($year) must be between 1 and 7378697629483820644
1969: easter_date(): Argument #1 ($year) must be a year after 1970 (inclusive)
1970: 1970-03-29
3000: 3000-04-13
3001: 1969-12-31
2000000000: 1969-12-31
2000000001: easter_date(): Argument #1 ($year) must be a year before 2.000.000.000 (inclusive)

But I expected this output instead (Linux 64-bit):

0: easter_date(): Argument #1 ($year) must be between 1970 and 2000000000
1969: easter_date(): Argument #1 ($year) must be between 1970 and 2000000000
1970: 1970-03-29
3000: 3000-04-13
3001: 3001-04-05
2000000000: 2000000000-04-23
2000000001: easter_date(): Argument #1 ($year) must be between 1970 and 2000000000

But I expected this output instead (Windows x64):

0: easter_date(): Argument #1 ($year) must be between 1970 and 3000
1969: easter_date(): Argument #1 ($year) must be between 1970 and 3000
1970: 1970-03-29
3000: 3000-04-13
3001: easter_date(): Argument #1 ($year) must be between 1970 and 3000
2000000000: easter_date(): Argument #1 ($year) must be between 1970 and 3000
2000000001: easter_date(): Argument #1 ($year) must be between 1970 and 3000

PHP Version

Linux + Windows x64

Operating System

Linux + Windows x64

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions