Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Obliczanie ilości dni
Forum PHP.pl > Forum > Bazy danych > MySQL
Kamilo
Witam

Są jakieś gotowe funkcje za pomocą których mogłabym obliczyć ilość dni pomiędzy dwoma datami ?
np. "2006-01-06" i "2006-12-15" interesuje mnie ilość dni pomiędzy tymi dwoma datami.

Pozdrawiam
nospor
No ale czy tak ciezko zajrzec do manuala?
http://dev.mysql.com/doc/refman/5.0/en/dat...-functions.html
Do wyboru do koloru
Kamilo
Dzieki za pomoc.
Polecenie którego szukałem to:
  1. mysql> SELECT DATEDIFF( 'data1' , 'data2' );
cytrysek
Witam,
a w jaki sposób obliczyć liczbę dni bez sobót i niedziel questionmark.gif

pzdr.
PW
dymsza
są 2 wyjścia jedno łatwe i brzydkie 2 trudniejsze dla początkujących i możesz nie podołać.

opcja łatwa dla noobów : jeśli znasz przedział czasowy w jakim będzie działać aplikacja możesz utworzyć table z datami o strukturze id|data|numer_dnia
wypełniasz tą table wstępnie na pare lat rok ma 365dni wiec jak zrobisz nawet na 10 lat to będzie działało ok.

i tera piszesz tak.

  1. SELECT count(*) FROM tabela_z_datami WHERE numer_dnia NOT IN(6,7) AND DATA >= 'data1' AND DATA <= 'data2'


a druga metoda to funkcja wbudowana którą obliczasz to w pętli nie pisze przykładu bo sma bym musiał nad tym trochę po mędrkować .

jeśli jest inna opcja proszę o nie miłosierne skarcenia exclamation.gif!
nospor
jesli nie koniecznie musi to byc na mysql to:
http://nospor.pl/liczba-dni-roboczych-n23.html
fernet
A czy nie bylo by lepiej pracowac na znaczkach czasu i przechowywac w bazie znaczki czasu. Wydaje mi sie ze to troche wydajniejsze niz pokretne zapytanie mysql
cytrysek
Wolałbym jednak zapytanie mysql.

http://nospor.pl/liczba-dni-roboczych-n23.html
tak widziałem, ale zapytanie mysql w moim przypadku byłoby wygodniejsze.

Ja to widze tak (czysta teoria):

mam 2 daty data_start i data_end
1. obliczam liczbe dni z tego przedzialu (np za pomocą DATEDIFF)

2. a od wyniku odejmuję liczbę dni, które w tym przedziale czasowym mają numer dnia 6 i 7.


ad. 1 wiem jak zrobic,
a jak ugryźć ad 2 bez tworzenia dodatkowych znaczkow w bazie?

dzieki za pomoc.
PW
dymsza
Ja osobiście nie wiem ale mam trochę upraszczający sprawę z dodatkową tabelą temat:

otóż tworzymy tabela : |id| i wypełniamy ją od 1 do liczby która przyjmujesz za maksymalną rozpiętość daty.

  1. SELECT count(*) FROM tabela_z_datami WHERE DAYOFWEEK( ADDDATE(data1,tabela_z_datami.id ) ) NOT IN(1,6) AND ADDDATE(data1,tabela_z_datami.id ) >= 'data1' AND ADDDATE(data1,tabela_z_datami.id ) <= 'data2' AND tabela_z_datami.id < datediff('data2','data1')


jak widać zapytanie nie wygląda szczególniej grożenie i wydaje mi się ze będzie działać dobrze. Jedynym ograniczeniem jest konieczność założenia maksymalnej rospiętości data czyli data2 - data1 oczywiście możesz ze spokojem zrobić tabel o maxymlnym id np. rónym maxymalnej liczbie dla integer 12 jeśli to to id będzie kluczem nie będzie miało to wpływu na wydajność zapytania.
cytrysek
No to znalazłem !

http://www.artfulsoftware.com/infotree/que...&bw=1280#91
użyłem procedurki:
  1. DROP FUNCTION IF EXISTS BizDateTimeDiff;
  2. //DELIMITER
  3. CREATE FUNCTION BizDateTimeDiff( d1 DATETIME, d2 DATETIME )
  4. RETURNS CHAR(30)
  5. DETERMINISTIC
  6. BEGIN DECLARE dow1, dow2, days, wknddays INT;
  7. DECLARE tdiff CHAR(10);
  8. SET dow1 = DAYOFWEEK(d1);
  9. SET dow2 = DAYOFWEEK(d2);
  10. SET tdiff = TIMEDIFF( TIME(d2), TIME(d1) );
  11. SET days = DATEDIFF(d2,d1);
  12. SET wknddays = 2 * FLOOR( days / 7 ) +
  13. IF( dow1 = 1 AND dow2 > 1, 1,
  14. IF( dow1 = 7 AND dow2 = 1, 1,
  15. IF( dow1 > 1 AND dow1 > dow2, 2,
  16. IF( dow1 < 7 AND dow2 = 7, 1, 0 )
  17. )
  18. )
  19. );
  20. SET days = FLOOR(days - wkndDays) - IF( ASCII(tdiff) = 45, 1, 0 );
  21. SET tdiff = IF( ASCII(tdiff) = 45, TIMEDIFF( '24:00:00', SUBSTRING(tdiff,2)), TIMEDIFF( tdiff, '00:00:00' ));
  22. RETURN CONCAT( days, ' days ', tdiff );
  23. END;
  24.  
  25. DELIMITER ;

a potem juz tylko proste zapytanie :
  1. SELECT BizDateTimeDiff( '2007-1-1 00:00:00', '2007-3-31 00:00:00' ) AS dtdiff;


i działa super.
nawet nie wiedziałem, że takie cuda można w mysql.
Mam pytanie, czy taka procedura będzie juz ustawiona na stałe (wrzuciłemją spod konsoli), czy np po restarcie bazy już nie zadziała?

Czy ma ktos pomysł jak ją rozszerzyć, by dodac jeszcze święta ?


pzdr.
PW
sylbryka
Witam, tak czytam ten post - dużo skorzystałam, jestem historyczką i stwierdziłam że na odległych datach te funkcje się nie nadają
W (naszym) kalendarzu gregoriańskim
obowiązuje system:
- rok jest zwykły, jeśli nie dzieli się przez 4
- rok jest przestępny, jeżeli dzieli się przez 4,
wyjątek:
- jeżeli dzieli się przez 100 a nie jest
podzielny przez 400 to jest zwykły.
A gregoriański istnieje dopiero od 15 października 1582, wcześniej stosowali inny kalendarz Juliański (i inny system roku przestępnego) różniący się 10 dni, i zaraz po 5 października nastał 15 października - a tego niestety w funkcjach nie uwzględniają, do długich dat się nie nadaje.

Najlepiej właśnie przeliczyć te daty na system liczb w zapisie dni juliańskich i odciąć je od siebie.
algorytm liczenia dni juliańskich:
http://cybermoon.w.interia.pl/wiedza/algor...julian_day.html
i jak obliczyć:
http://cybermoon.w.interia.pl/wiedza/algor...legle_daty.html
Mchl
Kilka słów o kolendarzu MySQLa

http://dev.mysql.com/doc/refman/5.0/en/mysql-calendar.html
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.