Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: wykrycie odpowiedniej zmiany oraz różnica między czasem
Forum PHP.pl > Forum > PHP
john_doe
proszę o podpowiedź merytoryczną w dwóch tematach:

1. Mam tabele ze zmianami ( w sensie zmiany w zakładzie pracy), 3 zmiany

shifts
shift_id
shift_name
shift_start
shift_stop

uzupełniona jest tak

1 | shift_1 | 06:00:00 | 14:00:00
1 | shift_2 | 14:00:00 | 22:00:00
1 | shift_3 | 22:00:00 | 06:00:00

na podstawie aktualnego czasu chce wyznaczyć, która jest obecnie zmiana.
zapytanie w stylu
  1. SELECT * FROM shifts WHERE <aktualna godzina> BETWEEN HOUR(shift_start) AND HOUR(shift_end);

nie działa dla 3 zmiany. I w sumie musiałbym zmienić lekko te godziny aby przedziały na siebie nie nachodziły -> czyli lekko rozbudować ten helper o to by patrzył też na minuty ( zmiany musiała by się kończy np. o 13:59:00 )

załatwiam to helperem w CI
  1. function current_shift()
  2. {
  3. //ensure that there is something in the variable - in case of no match
  4. $shift_id = '';
  5.  
  6. $ci =& get_instance();
  7.  
  8. $current_hour = date("H") + 1;
  9.  
  10. $ci->db->select('shift_id');
  11. $ci->db->where($current_hour . ' BETWEEN shift_start AND shift_end', NULL, FALSE);
  12.  
  13. $query = $ci->db->get('shifts');
  14.  
  15. $result = $query->row(0);
  16.  
  17. $shift_id = $result->shift_id;
  18.  
  19.  
  20. return $shift_id;
  21. }


2. Różnica między czasami

załóżmy, że jest 1 zmiana ( czyli między 8 a 14), załóżmy dalej stan aplikacji na 10:30. Potrzebuję wyliczyć ile upłynęło czasu między 10:30 a 8 w sekundach. Ten przypadek jeszcze nie taki zły ale czy w ten sam sposób da się wliczyć czas między np. 23 a 2.30 w nocy? Tutaj też się zmienia data i nie wiem czy to ma znaczenie dla tej kalkulacji?


---
jak widać oba punkty są poniekąd zależne od siebie bo oba bazują na tabeli 'shifts'
sabat24
1. Osobiście w dynamicznym przykładzie dodałbym 2 dodatkowe kolumny (użyję typu TIME dla lepszej czytelności, ale mógłby to być jakiś int) i znormalizował je do północy i na nich wykonywał operacje szukania oraz pobierania różnicy w czasach. W przypadku dodawania / edycji zmiany, należałoby sprawdzić, czy ma najmniejszą wartość. Jeśli tak, pobrać różnicę między nią i północą i wpisać do dodatkowych kolumn odpowiednie wartości dla danej zmiany pomniejszone o tę różnicę. W przypadku pola TIME daty nie mogłyby zachodzić na siebie, żeby ostatnia zmiana kończyła się o 23:59:59, a nie o 00:00:00. Oczywiście wcześniejsza różnica musiałyby być znana, aby odpowiednio skorygować czas przekazywany do zapytania. Jeśli zmiany Ci się nie zmieniają w szalonym tempie i możesz w pliku konfiguracyjnym przyjąć, że pierwsza zaczyna się o 06:00:00, to uprości sprawę.

W tym wypadku miałbyś więc 2 dodatkowe kolumny: shift_start_normalized, shift_stop_normalized i dane
1 | shift_1 | 06:00:00 | 14:00:00 | 00:00:00 | 07:59:59
2 | shift_2 | 14:00:00 | 22:00:00 | 08:00:00 | 13:59:59
3 | shift_3 | 22:00:00 | 06:00:00 | 14:00:00 | 23:59:59

Do zapytania wrzucasz AKTUALNY_CZAS - RÓŻNICA, czyli Twoje zapytanie wyglądałoby tak:
SELECT * FROM shifts WHERE <aktualna godzina - 6> BETWEEN shift_start_normalized AND shift_stop_normalized

Zakładając, że masz tylko 3 zmiany i raczej się nie zmienia to za często, to można wykorzystać drugi sposób.

2. Pola shift_start i shift_stop są oczywiście typu TIME

  1. SELECT * FROM shifts WHERE
  2. (shift_start < shift_stop AND
  3. shift_start <= '06:00:00' AND
  4. shift_stop > '06:00:00')
  5. OR
  6. (shift_start > shift_stop AND
  7. ('06:00:00' < shift_stop OR
  8. '06:00:00' >= shift_start))


  1. SELECT * FROM shifts WHERE
  2. (shift_start < shift_stop AND
  3. shift_start <= '04:00:00' AND
  4. shift_stop > '04:00:00')
  5. OR
  6. (shift_start > shift_stop AND
  7. ('04:00:00' < shift_stop OR
  8. '04:00:00' >= shift_start))


Oba wyniki zwrócą pierwszą zmianę.
  1. SELECT * FROM shift WHERE
  2.  
  3. (shift_start < shift_stop AND
  4. shift_start <= '14:00:00' AND
  5. shift_stop > '14:00:00')
  6. OR
  7. (shift_start > shift_stop AND
  8. ('14:00:00' < shift_stop OR
  9. '14:00:00' >= shift_start))

Wynik zwróci drugą zmianę.

Przykładowe wartości '06:00:00' i '14:00:00' to aktualna godzina.

Jak już sobie pobierzesz shift_start dla odpowiedniej zmiany, to później niech helper obliczy Ci różnicę czasu między aktualną porą i pobranym początkiem zmiany. Nie ma sensu zaprzęgać do tego MySQL (jeśli koniecznie chcesz, potrzebna będzie instrukcja warunkowa). W przypadku nr 1 wynik dostaniesz jako TIMEDIFF ('aktualna_godzina', shift_start)

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.