DevProTalk

DevProTalk (http://www.devprotalk.com/index.php)
-   PHP (http://www.devprotalk.com/forumdisplay.php?f=9)
-   -   DateTime and PHP (http://www.devprotalk.com/showthread.php?t=10940)

webarto 12. 04. 2012. 21:49

DateTime and PHP
 
Pozdrav,

Nisam puno radio sa DateTime, pa da čujem vaša iskustva oko slijedećeg...

Radnik ima radno vrijeme od 18:00 do 03:00 (9 sati razlike).

Pošto ovo zahvata 2 dana (nije bitno koja), potrebno je vratiti...

[ 0 => '6', 1 => '3' ]


Znači radi 6 sati u prvom danu, i 3 sata u drugom danu.

Kako biste vi ovo riješili? Language agnostic ako neko ima code :)

bluesman 12. 04. 2012. 23:04

Imaš puno funkcija koje rade matematičke operacije sa datumima, bitno je i koja ti je rezolucija potrebna, možda ti je najlakše sa timestamp-ovima

webarto 12. 04. 2012. 23:11

Ima puno, nažalost ja nisam pronašao u manualu, niti na prvoj stranici na Googleu :)

Ovo time_diff sam siguran da ima neko riješenje, ali ono što me zanimalo je ovaj shift_span... tnx Mister ;)
PHP kôd:

array(2) {
  [
0]=>
  
int(6)
  [
1]=>
  
int(3)


http://ideone.com/FR3x3

PHP kôd:

<?php
 
function shift_span($start$end)
{    
    
$time_diff time_diff($start$end);
    
$time_diff $time_diff['hours'];
 
    
# ignore minutes, safe after we calculated difference
    
$start = (int) $start;
    
$end = (int) $end;
            
    if(
$start $time_diff <= 24)
        return array(
$time_diff);
 
    return array(
        
abs($end $time_diff),
        
abs(($start $time_diff) % 24)
    );
}
 
function 
time_diff($start$end)
{
    
# do not ignore minutes
    
$start strtotime($start);
    
$end strtotime($end);
 
    
$diff abs($start $end);
    
$hours floor($diff 3600);
    
$minutes = ($diff - ($hours 3600)) / 60;
 
    
$hours $start $end24 $hours$hours;
    
    return 
compact('hours''minutes');
}
 
$start '18:00:00';
$end '03:00:00';
 
var_dump(shift_span($start$end));


ivanhoe 13. 04. 2012. 03:45

minute mozes da racunas i kao:
PHP kôd:

$minutes = ($diff 3600) / 60

nije da je neka bitna razlika, nego cisto eto kao zanimljivost :)

jablan 13. 04. 2012. 08:51

Obrati pažnju samo da dani kad se prebacuje vreme sa letnjeg na zimsko i obratno nemaju po 24 časa. :)

japan 13. 04. 2012. 09:15

Off Topic: ^ a ništa "primera radi"? :D

jablan 13. 04. 2012. 17:23

Off Topic: ^ :D Napisao sam nešto ali nisam hteo da kačim (autocenzura na delu). Mislim da problem nije dobro definisan. ;)

webarto 13. 04. 2012. 18:02

čekaj, kako nije definisan problem :D
slobodno zakači, može i ruby ;)

Kôd:

+----+----------+----------+----------+
| id | staff_id | start    | end      |
+----+----------+----------+----------+
|  1 |      66 | 21:00:00 | 03:00:00 |
+----+----------+----------+----------+

Kôd:

+----+-------------+------+----------+----------+
| id | schedule_id | day  | start    | end      |
+----+-------------+------+----------+----------+
| 16 |          1 |    1 | 21:00:00 | 00:00:00 |
| 17 |          1 |    2 | 00:00:00 | 03:00:00 |
+----+-------------+------+----------+----------+

day 1 je ponedeljak, day 2 je utorak...

jablan 13. 04. 2012. 18:46

Heh, pa sad mi je još manje jasno kad vidim da u drugoj tabeli opet nemaš broj sati nego početno i krajnje vreme.

Npr. http://ideone.com/UrB1k

webarto 13. 04. 2012. 19:28

Nije ni meni jasno, ali takav je zahtjev. Hvala na code, mnogo logičnije u Ruby :)
http://pokit.org/get/img/e7b901bdd27...8876bddec1.png

dee 13. 04. 2012. 19:45

Zasto to ne napravis na bazi? (pod pretpostavkom da $staff & $shift podatke cuvas u bazi)

webarto 13. 04. 2012. 20:06

Da, sve je bazi. Nemam ideju kako to da izvedem u MySQL. Postoje samo sati i dani (0,1,2...), ali ne i datumi. Da li je radnik zauzet u datom (ili trenutnom) vremenu, to bi moglo.

dee 13. 04. 2012. 20:22

Nisam dugo radio s MySQLom, ali ovo bi moralo voditi rjesenju:
http://dev.mysql.com/doc/refman/4.1/...ction_timediff

ako je $start<$end, onda samo timediff.
ako je $start>$end onda 24 - timediff($start, $end)

webarto 13. 04. 2012. 20:34

Da, da, radio sam tako, u PHP AFAIK postoji samo date_diff a ne time_diff... ali problem je što ja te podatke dobijam preko POST, a kada izračunam i sačuvam u bazu, neće mi trebati ponovno računanje. Hvala na predlogu.

jablan 14. 04. 2012. 07:39

http://sqlfiddle.com/#!2/304f9/24

webarto 14. 04. 2012. 13:18

my cup runneth over :D to je ti je kad "barataš" statistikama, hvala ;)

jablan 14. 04. 2012. 13:36

Može i bolje, napraviš view:

http://sqlfiddle.com/#!2/83534/2

webarto 14. 04. 2012. 15:09

Odlično. Izvini što smaram... Problem je što nije normalizovano, neko pametan je odlučio da napravi polja sa imenima dana (a polja u HTML formi sadrže iste nazive).

schedules
Kôd:

+----+----------+----------+----------+--------+--------+---------+-----------+----------+--------+----------+
| id | staff_id | start    | end      | sunday | monday | tuesday | wednesday | thursday | friday | saturday |
+----+----------+----------+----------+--------+--------+---------+-----------+----------+--------+----------+
|  1 |      66 | 21:00:00 | 03:00:00 |      0 |      0 |      0 |        0 |        0 |      0 |        1 |
+----+----------+----------+----------+--------+--------+---------+-----------+----------+--------+----------+

shifts
Kôd:

+----+-------------+------+----------+----------+
| id | schedule_id | day  | start    | end      |
+----+-------------+------+----------+----------+
| 3 |          1 |    6 | 21:00:00 | 00:00:00 |
| 4 |          1 |    0 | 00:00:00 | 03:00:00 |
+----+-------------+------+----------+----------+

day označava dan u sedmici (0(sun)..6(sat)), ali sad vidim da čitava struktura f***ed up, i da pored ovoga ima i fail cases. Ovo dole sam koristio prije SQL...

PHP kôd:

    private function _shifts($schedule_id)
    {
        if (!
$schedule_id)
            die(
'No schedule selected');
        
        
$shift_span       WA_DT::shift_span($_POST['start'], $_POST['end']);
        
$shift_span_count count($shift_span);
        
        
$_days = array(
            
'sunday',
            
'monday',
            
'tuesday',
            
'wednesday',
            
'thursday',
            
'friday',
            
'saturday'
        
);
        
        
# loop through weekdays
        
foreach ($_days as $k => $v)
        {
            
# if day is checked
            
if ($_POST[$v] != false)
            {
                
$today $k;
                
                
$tomorrow $today 1;
                if (
$tomorrow 6)
                    
$tomorrow = --$tomorrow 6;
                
                
# if shift is one day or two days
                
if ($shift_span_count == 1)
                {
                    
$shifts = new Shifts;
                    
$shifts->fromArray(array(
                        
'schedule_id' => $schedule_id,
                        
'day' => $today,
                        
'start' => $_POST['start'],
                        
'end' => $_POST['end']
                    ));
                    
$shifts->save();
                }
                else
                {
                    
$shifts = new Shifts;
                    
$shifts->fromArray(array(
                        
'schedule_id' => $schedule_id,
                        
'day' => $today,
                        
'start' => sprintf('%02s:00:00'24 $shift_span[0]),
                        
'end' => '00:00:00'
                    
));
                    
$shifts->save();
                    
$shifts = new Shifts;
                    
$shifts->fromArray(array(
                        
'schedule_id' => $schedule_id,
                        
'day' => $tomorrow,
                        
'start' => '00:00:00',
                        
'end' => sprintf('%02s:00:00'$shift_span[1])
                    ));
                    
$shifts->save();
                }
                
            }
        }
        
    } 

Usput, mrzim Doctrine.

jablan 14. 04. 2012. 15:53

Jebešga, ovo je baš ružno sa danima kao poljima. Ja bih tu napravio onda još jedan view koji bi normalizovao tu tabelu prvo, pa onda nad njom ovaj drugi view (s tim što ne bi bilo fiksno 1 i 2 kao dani, već day i day+1 iz ovog prethodnog viewa). Tako nešto.

Mada ja umem malo da preteram sa viewovima. ;)

webarto 14. 04. 2012. 16:41

Tačno tako, jebešga :)
Pazi ovo... 2012-4-29 24:00 je u stvari 2012-4-30, a u rezultatima se ne pojavljuje, to je 4 dana, valjda :D

DATEDIFF ne može da parsira 24:00, kada pomjerim na 30., vraća da je 3, ali je u stvari 4 puna, [27, 28, 29, 30].

Da li je lakše getShifts uraditi sa SQL?

PHP kôd:

getShifts('2012-4-27 00:00''2012-4-29 24:00');

array(
  
=> array(
    
'start' => '2012-4-27 07:00',
    
'end'   => '2012-4-27 12:00'
  
),
  
=> array(
    
'start' => '2012-4-28 12:00',
    
'end'   => '2012-4-28 17:00'
  
),
  
=> array(
    
'start' => '2012-4-29 12:00',
    
'end'   => '2012-4-29 17:00'
  



dee 14. 04. 2012. 17:06

24 niti ne postoji. range za time je 00:00:0000 - 23:59:9999

sve sto ti trebas napraviti jest imati tabelu za $schedules koja bi izgledala otprilike:

id | staffId | start | end

start i end bi bili datetime. iz toga mozes dobiti sve: dan u tjednu, razlike u cemu hoces (dani, sati...), smjene pojedinog zaposlenika, koliko je sati koji dan radio, itd itd...

tabela shifts ti tada ne treba vec je za dobivanje shiftova dovoljan query (ili view) kako ti je jablan napisao.

webarto 15. 04. 2012. 03:48



PHP kôd:

SELECT idstartend,
 CASE 
WHEN start end AND end AND CAST('01:38:14' AS time) < end THEN 1 ELSE 0 END AS yesterday,
 CASE 
WHEN CAST('01:38:14' AS timeBETWEEN start AND end THEN 1 ELSE 0 END AS today
 FROM schedules
 WHERE
 
(
     
/* this will handle eg 09-17 situations or one day shifts */
     
CAST('01:38:14' AS timeBETWEEN start AND end
 
OR
     
/* this will handle eg 18-03 situations or two day shifts */
     
NOT (CAST('01:38:14' AS timeBETWEEN end AND start) AND start end
 
)
 AND 
staff_id 93
 HAVING today 
OR yesterday 1
 LIMIT 1 



Vreme je GMT +2. Trenutno vreme je 17:29.

Powered by vBulletin® Verzija 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Copyright © DevProTalk. All Rights Reserved.

Mišljenja, saveti, izjave, ponude ili druge informacije ili sadržaji nastali na Sajtu su vlasništvo onoga ko ih je kreirao, a ne DevProTalk.com, tako da ne morate da se oslanjate na njih.
Autori poruka su jedini odgovorni za ovakve sadržaje. DevProTalk.com ne garantuje tačnost, kompletnost ili upotrebnu vrednost informacija, stavova, saveta ili datih izjava. Ne postoje uslovi pod kojima bi mi bili odgovorni za štetu ili gubitak koji je posledica bilo čijeg oslanjanja na nepouzdane informacije, ili bilo kakve informacije nastale kroz komunikaciju između registrovanih članova.
Web sajt može sadržavati linkove na druge web sajtove na Internetu ili neke druge sadržaje. Ne kontrolišemo niti podržavamo te druge web sajtove, niti smo pregledali bilo kakve sadržaje na takvim sajtovima. Mi nećemo biti odgovorni za legalnost, tačnost ili prikladnost bilo kog sadržaja, oglasa, proizvoda, usluga ili informacije lociranim na ili distribuiranih kroz druge web sajtove, niti za bilo kakvu štetu nastalu kao posledica takvih informacija. DevProTalk.com drži i čuva druga prava vlasništva na web sajtu. Web sajt sadrže materijale zaštićene copyright-om, zaštitne znakove i druge informacije o pravu vlasništva ili softver. Članovi mogu poslatu informacije zaštićene pravima vlasništva njihovih nosilaca i ona ostaju zaštićena bez obzira da li su oni koji prenose te informacije to naveli ili ne. Osim informacija koje su u javnom vlasništvu ili za koje dobijete dozvolu, nemate pravo da kopirate, modifikujete ili na bilo koji način menjate, objavljujete, prenosite, distribuirate, izvršavate, prikazujete ili prodajte bilo koju informaciju zaštićenu pravima vlasništva. Slanjem informacija ili sadržaja na bilo koji deo DevProTalk.com, Vi automatski dozvoljavate i predstavljate garanciju da imate pravo da dozvolite DevProTalk.com ili članovima DevProTalk.com bespovratnu, kontinualnu, neograničenu, globalnu dozvolu da koriste, kopiraju, izvršavaju, prikazuju i distribuiraju takve informacije i sadržaje i da iz takvih sadžaja koriste bilo koji deo u bilo koje svrhe, kao i pravo i dozvolu da koriste gore navedene sadržaje. Svi zaštitni znakovi (trademarks), logotipi, oznake usluga, firme ili imena proizvoda koji se pominju na ovom web sajtu su vlasništvo kojim raspolažu njihovi vlasnici.