Due to range limitations of core functions such as easter_date(), mktime(), strtotime(), I wrote this function to get the Easter Day in string format yyyy-mm-dd.
function myEaster($year)
{
/*Warning: easter_date(): This function is only valid for years between 1970 and 2037
* The easter_days() function can be used instead of easter_date() to calculate Easter for years which fall outside the range.
*/
//The next line would do the work if there were no limitations:
//return date("Y-m-d",easter_date($year));
/*Outside range (1970,2037) they advise to use easter_days().
* Unfortunately, when you have to create a date object as 21-03-yyyy to which add easter_days(), then obtain Easter,
* functions like strtotime(), DateTime::createFromFormat() will fail. (return value is 01-01-1970)
*/
$march21=date("$year-03-21");
$days=easter_days($year);
if($year<=2037)
//The next line would do the work if strtotime() wasn't affected by same limitations. But, the if..else is required to handle all years.
$date = date("Y-m-d",strtotime(date("Y-m-d", strtotime($march21)) . " +$days day"));
else
{
if($days<=10){
$day=str_pad(21+$days, 2, '0', STR_PAD_LEFT);
$date=date("$year-03-$day");
}
else
{
$day=str_pad($days-10, 2, '0', STR_PAD_LEFT);
$date=date("$year-04-$day");
}
}
return $date;
}
easter_date
(PHP 4, PHP 5)
easter_date — Get Unix timestamp for midnight on Easter of a given year
Description
$year
] )Returns the Unix timestamp corresponding to midnight on Easter of the given year.
This function will generate a warning if the year is outside of the range for Unix timestamps (i.e. before 1970 or after 2037).
The date of Easter Day was defined by the Council of Nicaea in AD325 as the Sunday after the first full moon which falls on or after the Spring Equinox. The Equinox is assumed to always fall on 21st March, so the calculation reduces to determining the date of the full moon and the date of the following Sunday. The algorithm used here was introduced around the year 532 by Dionysius Exiguus. Under the Julian Calendar (for years before 1753) a simple 19-year cycle is used to track the phases of the Moon. Under the Gregorian Calendar (for years after 1753 - devised by Clavius and Lilius, and introduced by Pope Gregory XIII in October 1582, and into Britain and its then colonies in September 1752) two correction factors are added to make the cycle more accurate.
Parameters
-
year -
The year as a number between 1970 an 2037
Return Values
The easter date as a unix timestamp.
Changelog
| Version | Description |
|---|---|
| Since 4.3.0 |
The year parameter is optional and defaults
to the current year according to the local time if omitted.
|
Examples
Example #1 easter_date() example
<?php
echo date("M-d-Y", easter_date(1999)); // Apr-04-1999
echo date("M-d-Y", easter_date(2000)); // Apr-23-2000
echo date("M-d-Y", easter_date(2001)); // Apr-15-2001
?>
See Also
- easter_days() - Get number of days after March 21 on which Easter falls for a given year for calculating Easter before 1970 or after 2037
I recently had to write a function that allows me to know if today is a holiday.
And in France, we have some holidays which depends on the easter date. Maybe this will be helpful to someone.
Just modify in the $holidays array the actual holidays dates of your country.
<?php
/**
* This function returns an array of timestamp corresponding to french holidays
*/
protected static function getHolidays($year = null)
{
if ($year === null)
{
$year = intval(date('Y'));
}
$easterDate = easter_date($year);
$easterDay = date('j', $easterDate);
$easterMonth = date('n', $easterDate);
$easterYear = date('Y', $easterDate);
$holidays = array(
// These days have a fixed date
mktime(0, 0, 0, 1, 1, $year), // 1er janvier
mktime(0, 0, 0, 5, 1, $year), // Fête du travail
mktime(0, 0, 0, 5, 8, $year), // Victoire des alliés
mktime(0, 0, 0, 7, 14, $year), // Fête nationale
mktime(0, 0, 0, 8, 15, $year), // Assomption
mktime(0, 0, 0, 11, 1, $year), // Toussaint
mktime(0, 0, 0, 11, 11, $year), // Armistice
mktime(0, 0, 0, 12, 25, $year), // Noel
// These days have a date depending on easter
mktime(0, 0, 0, $easterMonth, $easterDay + 2, $easterYear),
mktime(0, 0, 0, $easterMonth, $easterDay + 40, $easterYear),
mktime(0, 0, 0, $easterMonth, $easterDay + 50, $easterYear),
);
sort($holidays);
return $holidays;
}
?>
In 5.3.1 easter_date() returns GMT of start of Easter Day in UK allowing
for UK Summer Time. If you are in another time zone you need to
calculate offsets.
<?php
$e1 = easter_date(2008);
$e2 = easter_date(2009);
echo "Timestamps " . $e1 . " " . $e2 . "\n";
// Timestamps 1206230400 1239490800
echo "Days between Easter 2008 Easter 2009 = " . ($e2-$e1)/86400 . "\n";
// Days between Easter 2008 Easter 2009 = 384.958333333 - i.e. 384 days 23 hours
date_default_timezone_set("Europe/London");
echo date( " l, jS F Y H:i TO",$e1) . "\n";
echo date( " l, jS F Y H:i TO",$e2) . "\n";
// Sunday, 23rd March 2008 00:00 GMT+0000
// Sunday, 12th April 2009 00:00 BST+0100
date_default_timezone_set("America/New_York");
echo date( " l, jS F Y H:i TO",$e1) . "\n";
echo date( " l, jS F Y H:i TO",$e2) . "\n";
// Saturday, 22nd March 2008 20:00 EDT-0400
// Saturday, 11th April 2009 19:00 EDT-0400
// Daylight saving time in effect - New York 4 hours behind GMT
?>
To compute the correct Easter date for Eastern Orthodox Churches I made a function based on the Meeus Julian algorithm:
<?php
function orthodox_eastern($year) {
$a = $year % 4;
$b = $year % 7;
$c = $year % 19;
$d = (19 * $c + 15) % 30;
$e = (2 * $a + 4 * $b - $d + 34) % 7;
$month = floor(($d + $e + 114) / 31);
$day = (($d + $e + 114) % 31) + 1;
$de = mktime(0, 0, 0, $month, $day + 13, $year);
return $de;
}
?>
v5.2.1 - There is a known bug with easter_date() that can return incorrect dates for some years:
<?php
// 2008 OK
echo date("D d M Y", easter_date(2008)); // Sun 23 Mar 2008
// 2009 returns Saturday
echo date("D d M Y", easter_date(2009)); // Sat 11 Apr 2009
?>
However easter_days() works correctly:
<?php
echo date("D d M Y", strtotime("2009-03-21 +".easter_days(2009)." days")); // Sun 12 Apr 2009
?>
It is apparently related to timezone settings.
I made the function like this ... works fine !
<?php
function ostern
{
$maerz21=date('z',mktime(0,0,0,3,21,$jb));
$d=((15 + $jb/100 - $jb/400 - (8 * $jb/100 + 13) / 25)%30 + 19 * ($jb%19))%30;
if ($d==29)
{
$D=28;
}
elseif($d==28 && ($jb%17)>=11)
{
$D=27;
}
else $D=$d;
$e=(2 * ($jb%4) + 4 *($jb%7) + 6 * $D + (6 + $jb/100 - $jb/400 - 2)%7)%7;
$ostersonntag=$e+$D+1+$maerz21;
return $ostersonntag;
}
?>
The algorithm from Bigtree is correct if you add some (int) cast
<?php
function easter_date ($Year) {
/*
G is the Golden Number-1
H is 23-Epact (modulo 30)
I is the number of days from 21 March to the Paschal full moon
J is the weekday for the Paschal full moon (0=Sunday,
1=Monday, etc.)
L is the number of days from 21 March to the Sunday on or before
the Paschal full moon (a number between -6 and 28)
*/
$G = $Year % 19;
$C = (int)($Year / 100);
$H = (int)($C - (int)($C / 4) - (int)((8*$C+13) / 25) + 19*$G + 15) % 30;
$I = (int)$H - (int)($H / 28)*(1 - (int)($H / 28)*(int)(29 / ($H + 1))*((int)(21 - $G) / 11));
$J = ($Year + (int)($Year/4) + $I + 2 - $C + (int)($C/4)) % 7;
$L = $I - $J;
$m = 3 + (int)(($L + 40) / 44);
$d = $L + 28 - 31 * ((int)($m / 4));
$y = $Year;
$E = mktime(0,0,0, $m, $d, $y);
return $E;
}
?>
