Štúdia: Vylepšené rodné číslo
26. 6. 2025
Jednoduchá PHP funkcia na zistenie počtu pracovných dní v mesiaci a dní pracovného voľna na Slovensku. Použitá napr. na mzdovej kalkulačke.
Úpravou zoznamu sviatkov v premennej $holidays možno použiť pre ďalšie krajiny.
Napr. v Českej republike nie je sviatkom Veľký piatok, avšak navyše sú sviatky napr. 6.7 (upálenie Jána Husa),
28.9 (Deň Českej štátnosti) a 28.10 (Deň vzniku samostatného Československého štátu 1918).
Pre kontrolu správnosti môžete porovnať aktuálny prehľad štátnych sviatkov a dní pracovného pokoja.
/**
* Helper class to find the number of workdays & the number of holidays
* in a given month in Slovak republic
*/
class CalendarUtils
{
// list of state holidays + days off
// https://www.vlada.gov.sk/slovensko/statne-sviatky/
protected static $holidays = [
// dates in format "d.m" (no zeroes, no trailing dot)
'1.1',
'6.1',
//'19.4', // changes each year - easter friday
//'22.4', // changes each year - easter monday
'1.5',
'8.5', // zruseny v 2025-2026, potom znovu plati - konsolidacia
'5.7',
'29.8',
'1.9', // zruseny natrvalo od 24.03.2024
'15.9', // zruseny v 2025-2026, potom znovu plati - konsolidacia
'1.11',
'17.11', // zruseny natrvalo od 1.11.2025 - https://www.relia.sk/Article.aspx?ID=1324
'24.12',
'25.12',
'26.12',
];
/**
* Vrati pocet prac. dni pre datumy OD - DO
* @param int|string $dateFrom Date or timestamp
* @param int|string $dateTo Date or timestamp
* @return array($cntWorkday, $cntHoliday, $cntWeekend, $days)
*/
public static function countWorkdaysFromToSk($dateFrom, $dateTo)
{
$tsFrom = is_numeric($dateFrom) ? intval($dateFrom) : strtotime($dateFrom);
$tsTo = is_numeric($dateTo) ? intval($dateTo) : strtotime($dateTo);
if(!$tsFrom || !checkdate(date('n', $tsFrom), date('j', $tsFrom), date('Y', $tsFrom))){
throw new CHttpException(500, 'Neplatný dátum od "'.$dateFrom.'".');
}
if(!$tsTo || !checkdate(date('n', $tsTo), date('j', $tsTo), date('Y', $tsTo))){
throw new CHttpException(500, 'Neplatný dátum od "'.$dateTo.'".');
}
// add 23:59:59 for last day
$tsTo = mktime(23,59,59,date('n', $tsTo), date('j', $tsTo), date('Y', $tsTo));
$cntWorkday = $cntHoliday = $cntWeekend = 0;
$days = [];
for($ts = $tsFrom; $ts < $tsTo; $ts += 86400){
$day = date('Y-m-d', $ts);
$dayInWeek = date('N', $ts); // 1 = monday, 6 = saturday, 7 = sunday
if($dayInWeek > 5){
++$cntWeekend;
$days[$day] = 'weekend';
}elseif(self::isHoliday($ts)){
++$cntHoliday;
$days[$day] = 'holiday';
}else{
++$cntWorkday;
$days[$day] = 'workday';
}
}
return [$cntWorkday, $cntHoliday, $cntWeekend, $days];
}
/**
* Return the number of work days and holidays
* @param int $month
* @param int $year
* @return array($cntWorkDays, $cntHolidays)
*/
public static function countWorkdaysAndHolidaysInMonthSk($month, $year)
{
$month = intval($month);
$year = intval($year);
if($month < 1 || $month > 12){
throw new \Exception('Invalid month ['.$month.'].');
}
if($year < 1900 || $year > 2050){
throw new \Exception('Invalid year ['.$year.'].');
}
$ts = mktime(0,0,0,$month,1,$year);
$daysInMonth = date('t', $ts); // 28 - 31
$cntWorkDays = 0;
$cntHolidays = 0;
$days = [];
for($day = 1; $day <= $daysInMonth; ++$day){
$ts = mktime(0,0,0, $month, $day, $year);
$dayInWeek = date('N', $ts); // 1 = monday, 7 = sunday
if($dayInWeek > 5){
$days[$day] = 'weekend';
continue;
}
if(self::isHoliday($ts)){
$days[$day] = 'holiday';
++$cntHolidays;
}else{
$days[$day] = 'work';
++$cntWorkDays;
}
}
return [$cntWorkDays, $cntHolidays, $days];
}
/**
* Return TRUE is supplied timestamp is a holiday
* @param int $ts
*/
protected static function isHoliday($ts)
{
$dayMonth = date('j.n', $ts);
$year = (int) date('Y', $ts);
// je to sviatok z tabulky?
if (in_array($dayMonth, self::$holidays, true)) {
// vynimky / exceptions
if ('1.9' == $dayMonth && $year >= 2024) {
return false; // zruseny od / cancelled since 24.03.2024
} elseif ('17.11' == $dayMonth && $year >= 2025) {
return false; // zruseny od 1.11.2025
} elseif (in_array($dayMonth,['8.5', '15.9']) && in_array($year, [2025, 2026])) {
return false; // zrusene v 2025-2026, potom znovu platia (konsolidacia)
}
return true;
}
// vypocet velkej noci - algoritmus
// https://sk.wikipedia.org/wiki/V%C3%BDpo%C4%8Det_d%C3%A1tumu_Ve%C4%BEkej_noci
// https://en.wikipedia.org/wiki/Computus
$easterTs = easter_date($year); // nedela
// velky piatok
$checkTs = strtotime('-2 day', $easterTs); // nedela minus dva dni
if (date('j.n.Y', $checkTs) == date('j.n.Y', $ts)) {
return true;
}
// velkonocny pondelok
$checkTs = strtotime('+1 day', $easterTs); // nedela + jeden den
if (date('j.n.Y', $checkTs) == date('j.n.Y', $ts)) {
return true;
}
return false;
}
}
Máte otázku?
Profesionálna tvorba webových aplikácií a riešení na mieru. Konzultačné služby.