Drukowana wersja tematu

Kliknij tu, aby zobaczyć temat w orginalnym formacie

Forum PHP.pl _ Algorytmy, klasy, funkcje _ Liczba dni roboczych

Napisany przez: nospor 18.04.2005, 08:07:01

Napisałem funkcję do wyliczania liczby dni roboczych (bez sobót, niedziel oraz świąt) między dwoma datami:

  1. <?php
  2. function _workDays($date1, $date2)
  3. {
  4.     //święta w postaci mm-dd, pominąłem Wielkanoc i Boże Ciało, gdyż są to święta ruchome
  5.     $hol=http://www.php.net/array('01-01','05-01','05-03','08-15','11-11','12-25','12-26');
  6.  
  7.     $date1=http://www.php.net/strtotime($date1);$date2=http://www.php.net/strtotime($date2);
  8.     if ($date2===$date1) return 0;
  9.     $znak=1;//określa czy to będzie minus (gdy date1>date2) czy plus 
  10.     if ($date1>$date2)// minusy
  11.         {$datePom=$date1;$date1=$date2;$date2=$datePom;$znak=-1;}
  12.     $ilosc=0;
  13.     $date1=http://www.php.net/strtotime('+1 day',$date1);
  14.     $date2=http://www.php.net/strtotime('+1 day',$date2);
  15.     while ($date1<$date2)
  16.     {
  17.         $weekDay=http://www.php.net/date('w',$date1);
  18.         if (!($weekDay==|| $weekDay==|| http://www.php.net/in_array(http://www.php.net/date('m-d',$date1),$hol)))
  19.             $ilosc++;
  20.         $date1=http://www.php.net/strtotime('+1 day',$date1);
  21.     }
  22.     $ilosc*=$znak;
  23.     return $ilosc;
  24. }
  25.  
  26. ?>

wywołanie: echo _workDays('2005-04-11','2005-04-20');
Z założenia pierwsza data ma być miejsza od drugiej, w innym przypadku wynik będzie ujemny (mi to rozwiązanie było potrzebne, więc tak jest. Jak ktoś chce zawsze wynik dodatni, to usunąć linijkę $ilość*=$znak i wcześniej wszystko co dotyczyło zmiennej $znak).
Do liczby dni początkowa data nie jest liczona, czyli
echo _workDays('2005-04-18','2005-04-19');
zwróci 1.

Mam nadzieję że komuś się przyda smile.gif

edit:
Pełna funkcja z uwzględniem świąt ruchomych znajduje się tu:
http://nospor.pl/liczba-dni-roboczych-n23.html

Napisany przez: soldat 8.08.2005, 08:46:11

Przydało się (do statystyk) smile.gif Działa.

Napisany przez: gizmo1982 2.11.2006, 13:32:58

Bardzo się przydało... w sprawdzaniu terminowości zleceń serwisowych...
Duże thx i pozdro smile.gif

Napisany przez: acztery 27.11.2006, 01:15:49

musialo ci sie nudzic, takie sobie, nic specjalnego. Ale jak by liczyl wszystkie dni i swieta "ruchome" to by było cos

Napisany przez: nospor 27.11.2006, 09:28:33

Cytat
musialo ci sie nudzic
nie, nienudzilo mi sie smile.gif
Pisalem to, bo mi bylo w projekcie potrzebne. Pisane to bylo dawno temu, swieta ruchome nie byly wymagane. Opublikowalem, bo a noz komus by sie przydalo.

A teraz dopiero jak sie bede nudzil to dorobie swieta ruchome. ale to dopiero jak sie bede nudzil winksmiley.jpg

Napisany przez: php programmer 27.11.2006, 10:25:42

Hm, a skąd wiadomo kiedy wypadnie ruchome święto w danym roku?

Napisany przez: ARJ 27.11.2006, 10:39:26

trochę samodzielności: http://pl.wikipedia.org/wiki/%C5%9Awi%C4%99ta_ruchome

Napisany przez: php programmer 27.11.2006, 10:47:29

Czyli wyglądana to, że większość świąt zależy od Wielkanocy, a wielkanoc

Cytat
Wielkanoc - przypada w pierwszą niedzielę po pierwszej pełni księżyca po równonocy wiosennej 21 marca.

To już trochę masakra blink.gif

Napisany przez: nospor 27.11.2006, 11:01:12

Cytat
To już trochę masakra
no wlasnie nie, bo i na wielkanoc byl wzor. kiedys znalazlem na necie. a teraz niechce mi sie znowu szukac smile.gif

Napisany przez: uli 27.11.2006, 12:11:36

Cytat(nospor @ 27.11.2006, 11:01:12 ) *
no wlasnie nie, bo i na wielkanoc byl wzor. kiedys znalazlem na necie. a teraz niechce mi sie znowu szukac smile.gif


http://Wielkanoc%20Algorytm

Proszę bardzo:) - I święta 'ruchome' nie powinny już stanowić problemu:)

Napisany przez: kajko84 12.01.2007, 11:21:41

Witam

Jakis czas temu potrzebowalem do jednego z projektow funkcji wyliczajacej dni robocze w danym okresie. Trafilem tutaj smile.gif i wykorzystalem fukcje napisana przez nospora, z tym ze potrzebowalem rowniez "swiat ruchomych" wiec na miare moich mozliwosci rozwinalem troszke ta bardzo fajna funkcje (za ktora serdecznie dziekuje nospor i mam nadzieje ze nie masz nic przeciwko temu za ja troche zmodyfikowalem i zamiescilem)...

A oto kod:

  1. <?php
  2. function workDays($date1, $date2)
  3. {
  4. $date1=http://www.php.net/strtotime($date1);
  5. $date2=http://www.php.net/strtotime($date2);
  6.  
  7. if ($date2===$date1) return 0;
  8. $znak=1; // określa czy to będzie minus (gdy date1>date2) czy plus 
  9. if ($date1>$date2) // minusy
  10. {$datePom=$date1;$date1=$date2;$date2=$datePom;$znak=-1;}
  11. $ilosc=0;
  12. $date1=http://www.php.net/strtotime('+1 day',$date1);
  13. $date2=http://www.php.net/strtotime('+1 day',$date2);
  14.  
  15. while ($date1<$date2)
  16. {
  17. $rok = http://www.php.net/date('Y', http://www.php.net/strtotime('',$date1));
  18. $wielkanoc = http://www.php.net/date('m-d', easter_date($rok)); // data wielkanocy w postaci mm-dd
  19. $data = $rok . '-' . $wielkanoc;
  20. $data = http://www.php.net/strtotime($data);
  21. $drugi = http://www.php.net/date('m-d', http://www.php.net/strtotime('+1 day', $data)); // poniedzialek po wielkanocy
  22. $b_cialo = http://www.php.net/date('m-d', http://www.php.net/strtotime('+60 days', $data)); // boze cialo
  23.  
  24. // święta w postaci mm-dd
  25. $hol=http://www.php.net/array('01-01','05-01','05-03','08-15','11-01','11-11','12-25','12-26',$wielkanoc,$drugi,$b_cialo);
  26.  
  27. $weekDay=http://www.php.net/date('w',$date1);
  28. if (!($weekDay==|| $weekDay==|| http://www.php.net/in_array(http://www.php.net/date('m-d',$date1),$hol)))
  29. $ilosc++;
  30. $date1=http://www.php.net/strtotime('+1 day',$date1);
  31. }
  32. $ilosc*=$znak;
  33. return $ilosc;
  34. }
  35. ?>


pozdrawiam!

Napisany przez: nospor 12.01.2007, 11:33:41

Cytat
ze nie masz nic przeciwko temu za ja troche zmodyfikowalem i zamiescilem
wręcz przeciwnie. sam skorzystam na tych zmianach smile.gif

kurka, jakbym wiedzial ze w php jest funkcja easter_date() to juz sam bym to dawno zrobil. Czlowiek uczy sie cale zycie smile.gif

Napisany przez: drapichrust 3.03.2007, 09:34:15

Właśnie próbowałem użyć funkcji i niestety ma ona "błęda":

  1. <?php
  2. $rok = http://www.php.net/date('Y', http://www.php.net/strtotime('',$date1));
  3. ?>

U mnie się pojawia zawsze rok 1970 (czyli zerowy dla php). Wg php.net powinno być:
  1. <?php
  2. $rok = http://www.php.net/date('Y', http://www.php.net/strtotime('now',$date1));
  3. ?>


Więcej błędów nie znalazłem ale jak się coś znajdzie to dam znać.
PS. Dzięki za fajną funkcję

Napisany przez: nospor 10.10.2007, 15:13:45

Cytat
Właśnie próbowałem użyć funkcji i niestety ma ona "błęda":
Faktycznie, kajko popelnil drobny blad.
Cytat
Wg php.net powinno być:
Twoja przeróbka też niestety nie jest poprawna. Nie uwzględnia ona, ze mozemy liczyc daty nie z tego roku.

Poprawna i zoptymalizowana wersja funkcji znajduje się tu:
http://nospor.pl/liczba-dni-roboczych-n23.html

Napisany przez: buul 7.01.2014, 17:49:21

Trochę czuję się jak archeolog odkopując stary temat, ale szukałem (pewnie słabo) rozwiązania i nie znalazłem a może takowe istnieje, jest proste i nie będę musiał wyważać otwartych drzwi.

Chodzi o stworzenie daty z posiadanego dnia roboczego (w formacie 3 znakowym), ewentualnie zamianie dnia roboczego na kolejny dzień roku.

Napisany przez: nospor 7.01.2014, 18:38:08

O to ci chodzi:
http://forum.nospor.pl/programowanie/php/dni-robocze-ft30.html
?

Napisany przez: buul 8.01.2014, 12:39:16

Patrzyłem na to i byłem przekonany, że to kolejna funkcja do obliczania ilości dni pomiędzy datami a tu... smile.gif

Dziękuję bardzo - przyda się.


A jednak za szybko się ucieszyłem. Ale spróbuję na bazie tego zrobić co mi potrzeba.
Dla mnie wprowadzony musi być 1 argument - dzień roboczy w formie 3 znakowej (ew. drugi - rok) i wynikiem powinna być data, którą dany dzień w danym roku reprezentuje.

Stworzyłem coś takiego na bazie tego co podawałeś:

  1. function data_z_dnia_roboczego($d, $y=""){
  2.  
  3. //rok
  4. $y = (!http://www.php.net/empty($y)) ? $y : http://www.php.net/date("Y");
  5.  
  6. //święta
  7. $hol=http://www.php.net/array('01-01','05-01','05-03','08-15','11-01','11-11','12-25','12-26');
  8.  
  9. //święta ruchome
  10. $easter = http://www.php.net/date('m-d', easter_date($y));
  11. $date = http://www.php.net/strtotime($y . '-' . $easter);
  12. $easterSec = http://www.php.net/date('m-d', http://www.php.net/strtotime('+1 day', $date));
  13. $cc = http://www.php.net/date('m-d', http://www.php.net/strtotime('+60 days', $date)); //Boże ciało
  14. $zs = http://www.php.net/date('m-d', http://www.php.net/strtotime('+50 days', $date)); //Zielone świątki
  15. $hol[8] = $easter;
  16. $hol[9] = $easterSec;
  17. $hol[10] = $cc;
  18. $hol[11] = $zs;
  19.  
  20. $robocze = http://www.php.net/array();
  21. $dzienR = 1;
  22.  
  23. for ($i=0; $i<=356; $i++){
  24.  
  25. //to może wyglądać lepiej
  26. $dz = ($i<=9) ? "00".$i : $dz;
  27. $dz = ($i<=99 && $i>=10) ? "0".$i : $dz;
  28. $dz = ($i>=100) ? $i : $dz;
  29.  
  30. $data = DateTime::createFromFormat('z Y', http://www.php.net/strval($dz) . ' ' . http://www.php.net/strval($y));
  31.  
  32. $weekDay = $data->format('w');
  33. $md = $data->format('m-d');
  34.  
  35. if (!($weekDay==0 || $weekDay==6 || http://www.php.net/in_array($md,$hol) || $y>2010 && $md=='01-06')) {
  36. $robocze[$dzienR] = $data->format('Y-m-d');
  37. $dzienR++;
  38. }
  39.  
  40. }
  41.  
  42. return $robocze[http://www.php.net/intval($d)];
  43. }


Dodałem Zielone Świątki do dni wolnych. Nie jestem jeszcze pewien tego, czy zwracany index nie powinien być o 1 większy (bo liczba dni w roku z "z" zaczyna się od 000), ale dla mojego zastosowania jest ok. Jeszcze jak usunie się "$weekDay==6" to soboty stają się również dniami roboczymi.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)