Почивни дни

dakata__92

Super Moderator
Колеги, някой писал ли е генератор с който може автоматично да се вземат всички почивни дати събота и неделя и дните от официалните празници за годината?
 
dakata__92 каза:
Колеги, някой писал ли е генератор с който може автоматично да се вземат всички почивни дати събота и неделя и дните от официалните празници за годината?

Аз го правя ръчна всяка година за проекта си. Не съм открил друг вариант за момента

За Америка ползвам нещо подобно:

Код:
/**
 * National American Holidays
 * @param string $year
 * @return array
 */
public static function getNationalAmericanHolidays($year) {


    //  January 1 - New Year’s Day (Observed)
    //  Calc Last Monday in May - Memorial Day  strtotime("last Monday of May 2011");
    //  July 4 Independence Day
    //  First monday in september - Labor Day strtotime("first Monday of September 2011")
    //  November 11 - Veterans’ Day (Observed)
    //  Fourth Thursday in November Thanksgiving strtotime("fourth Thursday of November 2011");
    //  December 25 - Christmas Day        
    $bankHolidays = array(
          $year . "-01-01" // New Years
        , "". date("Y-m-d",strtotime("last Monday of May " . $year) ) // Memorial Day
        , $year . "-07-04" // Independence Day (corrected)
        , "". date("Y-m-d",strtotime("first Monday of September " . $year) ) // Labor Day
        , $year . "-11-11" // Veterans Day
        , "". date("Y-m-d",strtotime("fourth Thursday of November " . $year) ) // Thanksgiving
        , $year . "-12-25" // XMAS
        );

    return $bankHolidays;
}
 
Добре. А има ли някой формула за изчисляване на Великден?

easter_date();
https://www.php.net/manual/en/function.easter-date.php

Имате ли и доверие?
 
Успях да създам това. Някой да каже дали правилно съм имплементирал логиката за почивните дни попаднали в Събота или Неделя. Ако 1-ви Януари се падне в Събота, то почивен ще е 3-ти в Понеделник, нали?

Код:
private function setHolidays()
    {
        $holidays = [
            '01-01' => 'Нова година.',
            '03-03' => 'Ден на Освобождението на България от османско иго - национален празник.',
            '05-01' => 'Ден на труда и на международната работническа солидарност.',
            '05-06' => 'Гергьовден, Ден на храбростта и Българската армия.',
            '05-24' => 'Ден на българската просвета и култура и на славянската писменост.',
            '09-06' => 'Ден на Съединението.',
            '09-22' => 'Ден на Независимостта на България.',
            '12-24' => 'Бъдни вечер.',
            '12-25' => 'Рождество Христово (Коледа).',
            '12-26' => 'Рождество Христово (Коледа).',
        ];
        $year = $this->dateTime->format('Y');
        foreach ($holidays as $monthDay => $description) {
            $date = new \DateTime($year . '-' . $monthDay, new \DateTimeZone($this->dateTimeZone));
            if ($date->format('N') > 5) {
                $dateModify = $date->modify('+1 day');
                if ($dateModify->format('N') == 7) {
                    $dateModify = $date->modify('+1 day');
                }
                $holidays[$dateModify->format('m-d')] = $description;
            }
        }
        if ($easterDate = new \DateTime(date($this->dateFormat, $this->orthodoxEaster($year)))) {
            $easterDateDescription = 'Великден.';
            $holidays[$easterDate->format('m-d')] = $easterDateDescription;
            $easterDate->modify('+1 day');
            $holidays[$easterDate->format('m-d')] = $easterDateDescription;
            $easterDate->modify('-2 day');
            $holidays[$easterDate->format('m-d')] = $easterDateDescription;
            $easterDate->modify('-1 day');
            $holidays[$easterDate->format('m-d')] = $easterDateDescription;
        }
        ksort($holidays);
        $this->debug('Official Holidays: '.print_r($holidays, true));
        $this->holidays = $holidays;
        return $this;
    }
 
Не ми се рови в кода и затова направо - ако национален празник се падне неделя то и понеделника е почивен.
 
Аз как съм го направил в един счетоводен софтуер - маркирам само точните празници и уикендите и давам право да си добавят останалите + по фирмената логика почивни дни.
kalendar.PNG
 
Някой може ли да ми даде година в която:
„Когато официалните празници по ал. 1, с изключение на Великденските празници, съвпадат със събота и/или неделя, първият или първите два работни дни след тях са неприсъствени.
Празнични дни
Чл. 154. (Изм. и доп. - ДВ, бр. 30 от 1990 г., изм. - ДВ, бр. 27 от 1991 г., изм. - ДВ, бр. 104 от 1991 г., изм. - ДВ, бр. 88 от 1992 г., изм. - ДВ, бр. 2 от 1996 г.) (1) (Доп. - ДВ, бр. 22 от 1998 г., изм. и доп. - ДВ, бр. 56 от 1998 г., доп. - ДВ, бр. 108 от 1998 г., изм. - ДВ, бр. 15 от 2010 г.) Официални празници са:
1 януари - Нова година;
3 март - Ден на Освобождението на България от османско иго - национален празник;
1 май - Ден на труда и на международната работническа солидарност;
6 май - Гергьовден, Ден на храбростта и Българската армия;
24 май - Ден на българската просвета и култура и на славянската писменост;
6 септември - Ден на Съединението;
22 септември - Ден на Независимостта на България;
1 ноември - Ден на народните будители - неприсъствен за всички учебни заведения;
24 декември - Бъдни вечер, 25 и 26 декември - Рождество Христово;
Велики петък, Велика събота и Великден - неделя и понеделник, които в съответната година са определени за празнуването му.
(2) (Нова - ДВ, бр. 105 от 2016 г., в сила от 01.01.2017 г.) Когато официалните празници по ал. 1, с изключение на Великденските празници, съвпадат със събота и/или неделя, първият или първите два работни дни след тях са неприсъствени.
(3) (Доп. - ДВ, бр. 52 от 2004 г., в сила от 01.08.2004 г., изм. - ДВ, бр. 15 от 2010 г., предишна ал. 2, изм. - ДВ, бр. 105 от 2016 г., в сила от 01.01.2017 г.) Министерският съвет може да обявява еднократно и други дни за неприсъствени за оказване на обществена почит към важни исторически, политически, културни или други особено значими събития, както и дни за честване на определени професии и за оказване на признателност.
 
Ticketa каза:
2020. Ъпхиро е дал коректен календар

Това е ясно. Мен ме интересува условието в което се казва:

„Когато официалните празници по ал. 1, с изключение на Великденските празници, съвпадат със събота и/или неделя, първият или първите два работни дни след тях са неприсъствени.“

Търся година в която два празника съвпадат по това условие. Тоест са се паднали в Събота и Неделя, като трябва да се почива Понеделник и Вторник. Така като гледам празниците на пръв поглед вариант това да се случи има около Коледа.

Тоест 2021 е такава година!
 
uphero каза:
Кое не ти е ясно от условието, кое те затруднява за да го приложиш.

Всъщност условието не ме затруднява. Ориентирах се, че то е приложимо само за Коледните празници.
 
Забих тотално. Как да си извадя за годината всички дати за съботи и недели в един масив? Днес забивам на такива дребни неща...

Edit:
След едно хубаво кафе се справих.

Код:
$year = '2020';
$begin = new \DateTime($year."-01-01 00:00:00");
$end = new \DateTime($year."-12-31 00:00:00");
$range = new \DatePeriod($begin, new \DateInterval('P1D'), $end);

$weekends = [];
foreach($range as $date){
	if ($date->format("N") == 6 ) {
		$weekends[$date->format("Y-m-d")] = 'Събота';
	}
	if ($date->format("N") == 7 ) {
		$weekends[$date->format("Y-m-d")] = 'Неделя';
	}
}
 
Така циклиш ненужно през всичките 365 дни, а ти трябват само уикендите:

Код:
$range = new \DatePeriod(new \DateTime('@'.$first),
                         new \DateInterval('P1W'),
                         new \DateTime('@'.$last));

$weekends = [];

foreach($range as $date){
	$weekends[$date->format("Y-m-d")] = 'Събота';
	$weekends[$date->add($one_day)->format("Y-m-d")] = 'Неделя';
}

Demo: https://ideone.com/jvBZ3y#stdin

А може да се позабавляваш и така: https://thisinterestsme.com/php-get-first-monday-of-month/
И да вземеш крайните дати така:

Код:
$first = strtotime("first saturday of 2020-01");
$last = strtotime("last sunday of 2020-12");
 
anonimen каза:
Така циклиш ненужно през всичките 365 дни, а ти трябват само уикендите:

Код:
$range = new \DatePeriod(new \DateTime('@'.$first),
                         new \DateInterval('P1W'),
                         new \DateTime('@'.$last));

$weekends = [];

foreach($range as $date){
	$weekends[$date->format("Y-m-d")] = 'Събота';
	$weekends[$date->add($one_day)->format("Y-m-d")] = 'Неделя';
}

Demo: https://ideone.com/jvBZ3y#stdin

А може да се позабавляваш и така: https://thisinterestsme.com/php-get-first-monday-of-month/
И да вземеш крайните дати така:

Код:
$first = strtotime("first saturday of 2020-01");
$last = strtotime("last sunday of 2020-12");

Благодаря ти! Това ми трябваше. Смених моя код с твоя по-оптимизиран е!
+1
 

Горе