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;
}
?>
easter_date
(PHP 4, PHP 5)
easter_date — Obtener la fecha Unix para la medianoche de Pascua de un año dado
Descripción
$year
] )Devuelve la fecha Unix correspondiente a la medianoche de Pascua del año dado.
Esta función generará una advertencia si el año está fuera del rango de fechas Unix (esto es, antes de 1970 o después de 2037).
La fecha del Domiongo de Pascua fue definida por el Concilio de Nicea en el año 325 D.C. como el domingo después de la primera luna llena que cae en o después del Equinocio de Primavera. El equinocio se asume que cae en el 21 de marzo, por lo que el cálculo se reduce a determinar la fecha de la luna llena y la fecha del siguiente domingo. El algoritmo que se usa aquí fue introducido alrededor del año 532 por Dionisio el Exiguo. Bajo el Calendario Juliano (para años anteriores a 1753) se usa un simple ciclo de 19 años para rastrear las fases de la luna. Bajo el Calendario Gregoriano (para años posteriores a 1753 - concebido por Clavio y Lilio, e introducido por el papa Gregorio XIII en Octubre de 1582, e introducido en Gran Bretaña y sus colonias en Septiembre de 1752) se añadieron dos factores de corrección para hacer el ciclo más exacto.
Parámetros
-
year -
El año como un número entre 1970 y 2037.
Valores devueltos
El Domingo de Pascua como fecha Unix.
Historial de cambios
| Versión | Descripción |
|---|---|
| 4.3.0 |
El parámetro year es opcional y si se omite, por defecto es
el año actual de acuerdo a la hora actual.
|
Ejemplos
Ejemplo #1 Ejemplo de 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
?>
Notas
Nota:
easter_date() depende de las función de hora en C de su sistema en vez de usar las funciones de fecha y hora internas de PHP. Como consecuencia, easter_date() utiliza la variable de entorno TZ para determinar la zona horaria en la que debería operar, en lugar de usar la zona horaria predeterminada de PHP, la cual podría resultar en un comportamiento inesperado al usar esta función junto con otras funciones de fecha de PHP.
Como atajo, se puede usar easter_days() con DateTime y DateInterval para calcular el inico de la Semana Santa en la zona horario de su PHP como sigue:
<?php
function get_easter_datetime($año) {
$base = new DateTime("$año-03-21");
$días = easter_days($año);
return $base->add(new DateInterval("P{$días}D"));
}
foreach (range(2012, 2015) as $año) {
printf("La Semana Santa del %d cae en %s\n",
$año,
get_easter_datetime($año)->format('F j'));
}
?>El resultado del ejemplo sería:
La Semana Santa del 2012 cae en April 8 La Semana Santa del 2013 cae en March 31 La Semana Santa del 2014 cae en April 20 La Semana Santa del 2015 cae en April 5
Ver también
- easter_days() - Obtener el número de días despúes del 21 de marzo en el cuál cae Pascua para un año dado para calcular la Pascua antes de 1970 o después de 2037
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 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.
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;
}
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
?>
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;
}
?>
