easter_date
(PHP 4, PHP 5, PHP 7)
easter_date — Метка времени Unix соответствующая полуночи на Пасху в заданном году
Описание
$year
= date("Y")
] )Возвращает метку времени Unix соответствующую полуночи на Пасху в заданном году.
Функция выдаст предупреждение, если заданный год будет выходить за пределы диапазона меток времени Unix (с 1970 по 2037 гг).
Дата Пасхального дня была введена Консулом Никеи в 325 году до н.э. Это первое воскресенье, следующее за первым полнолунием после весеннего равноденствия. Днем весеннего равноденствия принято считать 21 марта, так что расчет дня Пасхи сводится к определению даты полнолуния и следующего за ней воскресенья. Используемый здесь алгоритм введен Дионисием Малым в 532 году. В Юлианском летоисчислении (до 1753 года) для отслеживания фаз луны использовался простой 19-летний цикл. В Грегорианском календаре (годы после 1753 - разработан Христофором Клавиусом и Алоизием Лилиусом и введен Папой Григорием XIII в октябре 1582г., а в Великобритании и ее колониях в сентябре 1752г.) было добавлено 2 поправочных коэффициента увеличивающих точность расчета дат.
Список параметров
-
year
-
Год - число между 1970 и 2037. Если не указан, то по умолчанию равен текущему года, согласно местному времени.
Возвращаемые значения
Дата Пасхи в виде метки времени Unix.
Примеры
Пример #1 Пример использования easter_date()
<?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
?>
Примечания
Замечание:
Функция easter_date() зависит от вашей системной библиотеки C функций работы со временем, а не от внутренних функций PHP. Как следствие, функция easter_date() использует переменную окружения TZ для определения временной зоны, которую она использует, а не заданную в PHP временную зону по умолчанию. Это может привести к неожиданному поведению при использовании этой функции совместно с другими функциями для работы с датами в PHP.
Решением может стать использование функции easter_days() с объектами DateTime и DateInterval для подсчета начала Пасхи в вашей временной зоне, как в этом примере:
<?php
function get_easter_datetime($year) {
$base = new DateTime("$year-03-21");
$days = easter_days($year);
return $base->add(new DateInterval("P{$days}D"));
}
foreach (range(2012, 2015) as $year) {
printf("Пасха в %d году приходится на %s\n",
$year,
get_easter_datetime($year)->format('F j'));
}
?>Результат выполнения данного примера:
Пасха в 2012 году приходится на April 8 Пасха в 2013 году приходится на March 31 Пасха в 2014 году приходится на April 20 Пасха в 2015 году приходится на April 5
Смотрите также
- Функция easter_days() - Получение количества дней между 21 марта и Пасхой в заданном году расчета дня Пасхи для годов до 1970 или после 2037
Коментарии
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;
}
?>
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;
}
?>
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;
}
?>
I found a problem with holidays timestamp computation and daylight saving time.
An article about it at http://goo.gl/76t31 (in french only, sorry).
In summary, this year (2013) easter begins before adding an hour for daylight saving time (occured sunday at 3:00). It means that if you do $easter + X, where x is a number of seconds equivalent to one day, 39 days or 50 days, the result is not equals to a midnight timestamp...
Here a function to check if a midnight timestamp is equals to an holiday :
function isHoliday( $ts ) {
// Licence : Creative Commons (BY)
// By Webpulser - http://goo.gl/76t31
$fixed_holidays = array( ’01-01′, ’01-05′, ’08-05′, ’14-07′, ’15-08′, ’11-11′, ’25-12′ );
$format = ‘d-m’;
$dm = date($format, $ts);
if ( in_array($dm, $fixed_holidays) ) return true;
$easter = easter_date( date(‘Y’, $ts) );
if ( date($format, $easter + 86400) == $dm ) return true;
if ( date($format, $easter + 3369600) == $dm ) return true;
if ( date($format, $easter + 4320000) == $dm ) return true;
return false;
}
feel free to use / modify.
Hey, recently I needed a function to get realization dates in online shop, so here it is (ready to go for polish users, please adjust your dates for any other country):
<?php
function getWorkday($date1,$workDays) {
$workDays = (int)$workDays;
if ($workDays <= 0)
return null;
$date1=strtotime('-1 day',strtotime($date1));
$lastYear = null;
$hol=array('01-01','01-06','05-01','05-03','08-15','11-01','11-11','12-25','12-26'); //array of month-date of static holidays (these are from Poland)
$i = 0;
while ($i<=$workDays) {
$year = date('Y', $date1);
if ($year !== $lastYear){
$lastYear = $year;
$easter = date('m-d', easter_date($year));
$date = strtotime($year . '-' . $easter); // easter
$easterSec = date('m-d', strtotime('+1 day', $date)); // easter monday
$greens = date('m-d', strtotime('+49 days', $date)); // zielone swiatki
$cc = date('m-d', strtotime('+60 days', $date)); // boze cialo
$hol[] = $easter;
$hol[] = $easterSec;
$hol[] = $greens;
$hol[] = $cc;
}
$weekDay=date('w',$date1);
if (!($weekDay==0 || $weekDay==6 || in_array(date('m-d',$date1),$hol)))
$i++;
$date1=strtotime('+1 day',$date1);
}
return date('Y-m-d',$date1);
}
?>
Thank you, @Maxie, for algorythm for computing Orthodox Easter date.
It can be improved though. You added 13 days in order to map Julian calendar to Gregorian. But 13 days is not a constant. It's an accumulated error fixed in Gregorian and should be calculated with this formula: (int)($year / 100) - (int)($year / 400) - 2