Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP][MYSQL]Porównanie daty+godziny aktualnej z wpisaną w bazie
Forum PHP.pl > Forum > Przedszkole
lilboi
Witam,

Szukałem, próbowałem i nic nie zdziałałem.

Potrzebuję pomocy w kwestii wyświetlenia liczby "przeskoczeń" godziny, najlepiej pokażę na przykładach:

W bazie 12:01 dzisiejszego dnia
Aktualnie 18:57
Wynik: 6 (13:00, 14:00, 15:00, 16:00, 17:00, 18:00) i wpisanie do bazy aktualnej daty i godziny (tak, aby o 19:30 zwrócony był wynik 1)

W bazie 22:50 wczorajszego dnia
Aktualnie 06:15
Wynik: 8 (23:00, 00:00, 01:00, 02:00, 03:00, 04:00, 05:00, 06:00) i wpisanie do bazy

W bazie 13:01 dzisiejszego dnia
Aktualnie 13:59
Wynik: 0 i bez wpisania do bazy

W bazie 18:58 dzisiejszego dnia
Aktualnie 19:03
Wynik: 1 (19:00) i wpisanie do bazy

W przypadku zerowej liczby minut zaokrąglenie w górę




Wszelka pomoc mile widziana, czy to będzie nakierowanie, czy gotowy skrypt smile.gif
melkorm
  1. SELECT IF('2007:01:01' < NOW(), HOUR(CURRENT_TIME) - HOUR('02:00:00'), '0') AS wynik;


Jeżeli wynik =/= 0 wtedy robisz update, chyba że koneicznie potzrebujesz ilość "przejść'' ?

Jeżeli chcesz gotowe zapytanie podaj zrzut tabeli tongue.gif
lilboi
tabela users, pole o nazwie regain i ilość przejść koniecznie potrzebna smile.gif
melkorm
  1. SELECT IF( regain < NOW() ,HOUR(TIMEDIFF(NOW(),regain) , '0') AS licznik FROM users;


Tutaj masz wynik z tabeli z licznikami smile.gif Czyli jeżeli data jest starsza oblicza różnice godzin między datami.

Następnie w php lecisz foreach'em po tej tablicy szukajac licznika i porownujesz go z tym ktory masz wbazie (bo chyba on po Tobie był ? smile.gif ) I w odopowiednich miejscach robisz update :]

Zapomniałbym przykład nie działa dla przykładu 18:59 - 19:01 =D Zaraz go poprawie i powinien śmigać ;]

poprawione:

  1. SELECT
  2. CASE WHEN regain < NOW() AND HOUR(TIMEDIFF(NOW(),regain)) > 0 THEN HOUR(TIMEDIFF(NOW(),regain))
  3. WHEN regain < NOW() AND HOUR(TIMEDIFF(NOW(),regain)) = 0 AND HOUR(NOW()) > HOUR(regain)
  4. THEN '1' END AS ile FROM users;


Powinno zadziałać przetestuj na przykładowe tablicy z najróżnijszymy datami / wyjątkami - jeżeli coś będzie źle podaj tablice danych i wyników .
lilboi
a jak jeszcze dodamy
  1. WHERE id='$userrow["id"]' LIMIT 1
? i poprosiłbym o jaśniejsze wyprowadzenie np $licznik, jeśli można smile.gif
melkorm
  1. SELECT
  2. CASE WHEN regain < NOW() AND HOUR(TIMEDIFF(NOW(),regain)) > 0 THEN HOUR(TIMEDIFF(NOW(),regain))
  3. WHEN regain < NOW() AND HOUR(TIMEDIFF(NOW(),regain)) = 0 AND HOUR(NOW()) > HOUR(regain)
  4. THEN '1' END AS ile FROM users WHERE id='.$userrow['id'].' LIMIT 1 ;


  1. <?php
  2. $wynik = mysql_fetch_array($zapytanie);
  3. $licznik = $wynik['ile'];
  4. ?>


Pisane z palca możliwa pomyłka biggrin.gif
lilboi
  1. Błąd
  2.  
  3. zapytanie SQL: Dokumentacja
  4.  
  5. SELECT *
  6. CASE WHEN `onlinetime` < NOW( ) AND HOUR( TIMEDIFF( NOW( ) , `onlinetime` ) ) >0
  7. THEN HOUR( TIMEDIFF( NOW( ) , `onlinetime` ) )
  8. WHEN `onlinetime` < NOW( ) AND HOUR( TIMEDIFF( NOW( ) , `onlinetime` ) ) =0 AND HOUR( NOW( ) ) > HOUR( `onlinetime` )
  9. THEN '1'
  10. END AS ile
  11. FROM users WHERE id <100
  12. LIMIT 100
  13.  
  14. MySQL zwrócił komunikat: Dokumentacja
  15. #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CASE WHEN `onlinetime` < NOW() AND HOUR(TIMEDIFF(NOW(),`onlinetime`)) > 0 THEN H' at line 1


tyle phpadmin, onlinetime to kolumna, do której wrzucany jest NOW(); więc powinno działać

Sam nie mam pojęcia o tego typu kodach, więc nawet jeśli błąd jest marginalny to nie wytropię, moja wiedza ogranicza się do pomysłu typu

  1. <?php
  2. $znacznik = time();
  3. $liczbadnia = date("z", $znacznik);
  4. if ($userrow["liczbadnia"]<$liczbadnia) {instrukcja}
  5. ?>


i gdyby time(); miała taki wodotrysk jak liczba godzin od początku roku, to tak bym kombinował biggrin.gif
melkorm
hehe za gwiazdką przecinek daj i powinno śmigać smile.gif
lilboi
przeszło, ale dla następujących wartości zwróciło:

2008-09-26 22:25:46 => NULL (ok)
2008-09-26 20:19:58 => 2 (ok)
2008-09-26 00:22:43 => 22 (ok)
2008-09-24 14:49:55 => 55 (ok)
2008-09-24 15:24:14 => 55 (nie ok)
2008-09-24 17:12:42 => 53 (ok)

fakt faktem błąd niewielki, acz obecny smile.gif jakby to pomogło to $userrow["regain"] może wskazywać na odpowiednią wartość, tony kodu wyżej mam select * z users smile.gif
melkorm
mhm, szkoda że nie wziąłeś wartości now sad.gif daj do zapytania:

  1. SELECT *, NOW() AS teraz, ....(od CASE)


i zrób ponownie test wtedy będe wiedział dokładnei gdzie jest błąd, sądze że zm inutami winksmiley.jpg ale do tego potzrebuej dane tongue.gif
lilboi
Kolejno: onlinetime | teraz | wartość
2008-09-25 16:24:17 2008-09-26 23:41:38 31
2008-09-26 19:54:17 2008-09-26 23:41:38 3
0000-00-00 00:00:00 2008-09-26 23:41:38 NULL
2008-09-24 14:49:55 2008-09-26 23:41:38 56
2008-09-24 15:24:14 2008-09-26 23:41:38 56
2008-09-23 22:29:01 2008-09-26 23:41:38 73
2008-09-24 15:37:18 2008-09-26 23:41:38 56
2008-09-24 17:12:42 2008-09-26 23:41:38 54
2008-09-26 15:27:49 2008-09-26 23:41:38 8
2008-09-25 19:06:21 2008-09-26 23:41:38 28

mam nadzieję, że w miarę czytelnie winksmiley.jpg felerne rekordy są pod NULLem
melkorm
  1. SELECT *,
  2. CASE WHEN `onlinetime` < NOW( ) AND HOUR( TIMEDIFF( NOW( ) , `onlinetime` ) ) > 0
  3. THEN IF(MINUTE(`onlinetime`) < MINUTE(NOW()), HOUR( TIMEDIFF( NOW( ) , `onlinetime` ), HOUR( TIMEDIFF( NOW( ) , `onlinetime` ))+'1'
  4. WHEN `onlinetime` < NOW( ) AND HOUR( TIMEDIFF( NOW( ) , `onlinetime` ) ) =0 AND HOUR( NOW( ) ) > HOUR( `onlinetime` )
  5. THEN '1'
  6. END AS ile
  7. FROM users WHERE id <100
  8. LIMIT 100


Im większe , im brzydsze to zapytanie tym coraz iweksze mam wrażenie że da się to inaczej rozwiązać :/
Powinno działać ;p
lilboi
Prawdę mówiąc myślałem nad rozwiązaniem w pełni PHP podanym przeze mnie wyżej, tak zrobiłem z numerkiem dnia w roku i działa znakomicie, a za każdym sprawdzeniem ma być zmieniany jeden rekord (tylko dla zalogowanego użyszkodnika), problem tkwił w tym, że nie poradziłbym sobie policzeniem różnicy w godzinach i miałbym problemy z formatem daty/godziny winksmiley.jpg Pewnie zakończyłoby się to osobną kolumną dla dnia i osobną dla godziny biggrin.gif

A oto wynik zapytania:
  1. Błąd
  2.  
  3. zapytanie SQL: Dokumentacja
  4.  
  5. SELECT onlinetime, NOW( ) AS teraz,
  6. CASE WHEN `onlinetime` < NOW( ) AND HOUR( TIMEDIFF( NOW( ) , `onlinetime` ) ) >0
  7. THEN IF( MINUTE( `onlinetime` ) < MINUTE( NOW( ) ) , HOUR( TIMEDIFF( NOW( ) , `onlinetime` ) , HOUR( TIMEDIFF( NOW( ) , `onlinetime` ) ) + '1'
  8. WHEN `onlinetime` < NOW( ) AND HOUR( TIMEDIFF( NOW( ) , `onlinetime` ) ) =0 AND HOUR( NOW( ) ) > HOUR( `onlinetime` )
  9. THEN '1'
  10. END AS ile
  11. FROM users WHERE id <100
  12. LIMIT 100
  13.  
  14. MySQL zwrócił komunikat: Dokumentacja
  15. #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' HOUR( TIMEDIFF( NOW( ) , `onlinetime` ))+'1'
  16. WHEN `onlinetime` < NOW( ) AND HO' at line 3
Kicok
Trzeba się pozbyć minut i sekund, bo to one wszystko psują. Gdy już mamy daty w postaci: YYYY-mm-dd HH:00:00, to można je odejmować:

  1. SELECT *, HOUR( TIMEDIFF( DATE_FORMAT( NOW(), '%Y-%m-%d %H:00:00' ), DATE_FORMAT( regain, '%Y-%m-%d %H:00:00' ) ) ) AS roznica
  2. FROM users


Warto też wyalić z zapytania DATE_FORMAT( NOW(), '%Y-%m-%d %H:00:00' ) i wstawić tam aktualną datę wygenerowaną przez PHP (date" title="Zobacz w manualu PHP" target="_manual) - również pozbawioną minut i sekund. Poprawi to wydajność zapytania jeśli masz sporo rekordów w tabeli users.
melkorm
heh no bez minut to banał .... chodzi własnie o to by smigało z minutami ;P

edit => chociaż masz racje, po wywaleniu minut mamy pełne godziny :] No wiedziałem że to jakoś łatwiej da się rozwiązać :/

brzydal.gif
lilboi
Super, działa świetnie smile.gif wielkie dzięki, ale mam jeszcze jedno pytanie; czy jakbym w przyszłości chciał liczbę odstępów trzydziesto i piętnastominutowych to dałoby się to jakoś łatwo przekształcić?
melkorm
wtedy zamiast godzin liczyło by się minuty biggrin.gif Łatwo to może nie ale trzebab y pomyśleć nadtym ;]
lilboi
Insza inszość jest taka, że tu mamy kolejne zapytanie, a chyba można go uniknąć, CHYBA biggrin.gif

  1. <?php
  2. $znacznik = time();
  3. $dzien = date("z", $znacznik);
  4. $godzina = date("G", $znacznik);
  5.  
  6. $rdzien = $userrow["dzien"];
  7. $rgodzina = $userrow["godzina"];
  8.  
  9. if ($dzien != $rdzien) {
  10. $roznica = 24-$rgodzina + ($dzien-$rdzien-1)*24 + $godzina;
  11. $updatequery = doquery("UPDATE {{table}} SET rgodzina='$godzina', rdzien='$dzien' WHERE id='".$userrow["id"]."' LIMIT 1", "users");
  12. }
  13. elseif ($rgodzina != $godzina) {
  14. $roznica = $godzina-$rgodzina;
  15. $updatequery = doquery("UPDATE {{table}} SET rgodzina='$godzina', rdzien='$dzien' WHERE id='".$userrow["id"]."' LIMIT 1", "users");
  16. }
  17. ?>


Co sądzicie? tym sposobem łatwo mogę dodać minuty, zajmie to jeszcze jeden elseif i unikniemy dodatkowego SELECTA
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.