Liczba dni roboczych

2007-10-10 16:04:51

 

Liczenie ile minęło dni między jedną datą a drugą to dość częsty "problem" piszących w php. Samo policzenie dni bez rozróżniania na dni robocze jest banalnie proste:

1
2
3
<?php
echo (strtotime('2005-03-30 GMT')-strtotime('2005-03-01 GMT'))/86400;
?>

Jednak wyliczenie dni roboczych to już większa sprawa. By ułatwić sobie i Wam życie, napisałem funkcję, która wylicza liczbę dni roboczych. Pierwotnie funkcja nie uwzględniała świąt ruchomych jednak użytkownik kajko84 dopisał do tego i święta ruchome. Ja to trochę zoptymalizowałem i mamy w pełni funkcjonalną funkcję do wyliczania liczby roboczych.

Kod funkcji

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php
function workDays($date1$date2$withStartDay false) {
    
$date1=strtotime($date1);
    
$date2=strtotime($date2);
    if (
$date2===$date1 && !$withStartDay) return 0;
    
$char=1;
    if (
$date1>$date2)
        {
$datePom=$date1;$date1=$date2;$date2=$datePom;$char=-1;}
    
$count=0;
    if (!
$withStartDay)
        
$date1=strtotime('+1 day',$date1);
    
$date2=strtotime('+1 day',$date2);
    
$lastYear null;
    
$hol=array('01-01','05-01','05-03','08-15','11-01','11-11','12-25','12-26');
    while (
$date1<$date2) {
        
$year date('Y'$date1);
        if (
$year !== $lastYear){
            
$lastYear $year;
            
$easter date('m-d'easter_date($year));
            
$date strtotime($year '-' $easter);
            
$easterSec date('m-d'strtotime('+1 day'$date));
            
$cc date('m-d'strtotime('+60 days'$date));
            
$hol[8] = $easter;
            
$hol[9] = $easterSec;
            
$hol[10] = $cc;
        }
        
$weekDay=date('w',$date1);
        if (!(
$weekDay==|| $weekDay==|| in_array(date('m-d',$date1),$hol)))
            
$count++;
        
$date1=strtotime('+1 day',$date1);
    }
    
$count*=$char;
    return 
$count;
}
?>
,gdzie:
  • $date1 - data początkowa w formacie rrrr-mm-dd
  • $date2 - data końcowa w formacie rrrr-mm-dd
  • $withStartDay - określa czy liczyć liczbę dni wraz z dniem początkowym. Domyślnie liczone jest bez tegoż dnia.

W przypadku, gdy data początkowo będzie większa od daty końcowej, dostaniemy wynik ujemny.

Użycie

Użycie funkcji jest banalnie proste:

1
2
3
4
5
6
<?php
echo workDays('2007-10-10','2007-10-12'); //wyświetli 2
echo workDays('2007-10-10','2007-10-14'); //wyświetli 2, gdyż dwa ostanie dni to weekend
echo workDays('2007-10-12','2007-10-10'); //wyświetli -2
echo workDays('2007-10-10','2007-10-12',true);//wyświetli 3, gdyż liczymy z dniem początkowym
?>

 

Komentarze

 

2009-01-05 23:47:23 gość_szakal_kp

 
Bardzo fajny ten przykład, ale do moich potrzeb niestety wymaga jeszcze dopracowania, nie uwzględnia on przypadku kiedy święto jest dniem wolnym od pracy(sobotą, niedzielą). Ustawodawca mówi że w takim przypadku pracodawca musi pracownikowi taki dzień "oddać". Przykład 3 maj 2008 (sobota).

sprostowanie i rozwiązanie Wyłącznie sobót, jeśli święto wypada w niedziele to nic z tym nie robimy.
A oto rozwiązanie:
1
2
3
4
<?php
if ((in_array(date('m-d',$date1),$hol) && $weekDay==6))   
    
$count--;
?>

Mam nadzieję że komuś się przyda

2009-01-06 07:04:27 nospor

 
@szakal_kp dzięki za drobną, aczkolwiek ważną poprawkę
Aczkolwiek nie jestem pewien czy można tak to poprawić. Rozumiem, iż sobotę należy "oddać" ale kto powiedział, że należy oddać akurat w zadanym przez Ciebie okresie czasu, który sprawdzasz. A noż sobota zostanie "oddana" po tym okresie. Wówczas liczba dni roboczych dla okresu, który wyliczasz nie powinna być zmniejszana o jeden dzień.

Wydaje mi się, iż poprawkę należy mieć na uwadze, ale stosować ją należy wg. własnych potrzeb.

2009-01-06 17:39:49 gość_szakal_kp

 
Nospor, bardzo trafna uwaga. Jeszcze nikt nie stworzył algorytmu obliczającego kiedy pracownik odbiera sobie zaległe wolne Mi jest ten algorytm potrzebny do obliczania wymiaru czasu pracy w danym miesiącu w programie płacowym.

2009-01-16 13:43:21 gość_froggy

 
Zgodnie z ustawa, mamy obecnie 12 dni wolnych od pracy - w powyzszej funkcji pominieto pierwszy dzień Zielonych Świątek. (http://www.pit.pl/dni_ustawowo_wolne_od_pracy_287.php)
Aby go uwzględnić, należy do funkcji dodać dwie linijki (np. jako linie 23-24):
1
2
$zs = date('m-d', strtotime('+49 days', $date)); 
$hol[11] = $zs;

2009-04-20 11:52:15 gość_hol

 
froggy, to prawda nie ma tego święta w tej funkcji jednak jest ono świętem ruchomym i przypada 49 dni (7 tygodni) od Niedzieli Zmartwychwstania Pańskiego, a więc przypada zawsze w niedzielę. Oczywiście jeśli ktoś planowo pracuje w niedziele to miałoby to znaczenie, jednak dla takich potrzeb ta funkcja i tak wymaga modyfikacji.

Dodaj komentarz

 

Dostępne bbcode: b, u, i, color, size, quote, img, url, list, il (tylko w list), code, php, css, html, sql, js