Linux bash script recipes
19. 9. 2022
Jednoduchá utilita počítajúca počet pracovných dní v mesiaci 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 naviac sviatky od Slovenska sú 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ť napr. s online kalendárom.
/**
* Helper class to find the number of work days and the number of holidays in a given month in Slovakia
*/
class CalendarUtils
{
// list of state holidays
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',
'5.7',
'29.8',
'1.9',
'15.9',
'1.11',
'17.11',
'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.'".');
}
$tsTo = mktime(23,59,59,date('n', $tsTo), date('j', $tsTo), date('Y', $tsTo)); // add 23:59:59 for last day
$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)
{
// je to sviatok z tabulky?
$dayMonth = date('j.n', $ts);
if (in_array($dayMonth, self::$holidays)) {
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
$year = (int) date('Y', $ts);
$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.