Avatar billede sevinding Juniormester
02. august 2016 - 18:39 Der er 26 kommentarer og
1 løsning

Standardformatet for tidsangivelser i MySQL

Jeg har hidtil brugt datatypen: time, når jeg skulle indsætte timer, minutter og sekunder i min database hos Surftown. Jeg har ikke indsat data siden august 2015.
Hvis jeg nu indsætter mere end 24 timer, virker min beregning af tidsforskelle ikke.
Surftown siger at  tidsangivelser skal laves om til formatet 99:55:44.000001
Er der en der kan fortælle mig hvad det går ud på?
Avatar billede arne_v Ekspert
02. august 2016 - 19:50 #1
Gemmer du ikke-dato-delen af et tidspunkt eller gemmer du laengden paa et interval?

Altsaa klokken 08:00 eller intervallet 8 timer og 0 minutter?
Avatar billede jakobdo Ekspert
02. august 2016 - 19:51 #2
Kommer vel netop lidt ud på hvad du ønsker.
Ville det f.eks. kunne give mening at gemme forskellen i sekunder?
Eller den præcise tid som Arne er inde på.
Hvad er det præcist du ønsker at opnå ?
Avatar billede sevinding Juniormester
03. august 2016 - 06:16 #3
Jeg har et felt der indeholder eksempelvis: 89 timer 04 minutter 48 sekunder som er en vindertid i Tour de France
Nr 2 har så tiden: 89 timer 08 minutter 53 sekunder.
Det er så forskellen på disse tider der ikke fungerer mere, da det viser -05:28:26   
Det kan ses her: http://www.tourfacts.dk/by_year/yearly/class1.php?aar=2016 som også er blevet ekstreeeemt langsom at indlæse.
Jeg bruger nedenstående, nok outdated, men funktionel kode:

$res = mysql_query("SELECT

alt.nummer AS nummer,
alt.ayear AS ayear,
alt.hold AS hold,
ryt.logo AS logo,
ryt.id AS rytterid,
ryt.name AS ryttername,
tea.id AS id,
tea.land AS land,
tea.name AS teamname,
lan.landid AS landid,
lan.fodeland AS fodeland,
lan.inter AS inter,
sta.afstand AS afstand,
yel.place AS place,
yel.tid AS tid,
yel.winnerspoint AS winnerspoint,
cyt.vinid AS vinid,
cyt.aar AS aar,
cyt.vintime AS vintime,

        SUM(sta.afstand) AS ialt,
        SEC_TO_TIME(SUM(TIME_TO_SEC(yel.tid))) AS sum,
        3600*SUM(sta.afstand)/SUM(TIME_TO_SEC(yel.tid)) AS gns,

        (TIMEDIFF(yel.tid,cyt.vintime)) AS forskel

        FROM alt AS alt
        INNER JOIN ryt AS ryt ON alt.navn = ryt.id
        INNER JOIN cl_yellow AS yel ON yel.name = ryt.id
        INNER JOIN teams AS tea ON alt.hold = tea.id
        INNER JOIN stages AS sta
          INNER JOIN class_yellow_winner AS cyt
        INNER JOIN lande AS lan ON ryt.land = lan.landid

        WHERE alt.ayear=$aar AND (alt.navn = ryt.id) AND yel.yelyear=$aar GROUP BY ryt.id ORDER BY yel.place ASC");

        while($r = mysql_fetch_array($res)) {

Indsætter jeg tider mindre end 24 timer, er der intet problem trods det at koden er den samme, og det hele fungerede i august 2015.
Som sagt siger Surftown at  tidsangivelser skal laves om til formatet 99:55:44.000001 da det er standardformatet for tidsangivelser i MySQL nu.
Og som det non-geni jeg er  vil jeg gerne vide hvordan jeg gør det.
Avatar billede arne_v Ekspert
03. august 2016 - 15:14 #4
Jeg ville helt klart gemme de intervaller som sekunder men docs siger:

12.3.2 The TIME Type

MySQL retrieves and displays TIME values in 'HH:MM:SS' format (or 'HHH:MM:SS' format for large hours values). TIME values may range from '-838:59:59' to '838:59:59'. The hours part may be so large because the TIME type can be used not only to represent a time of day (which must be less than 24 hours), but also elapsed time or a time interval between two events (which may be much greater than 24 hours, or even negative).

saa principielt burde det virke.

Er det den her:

(TIMEDIFF(yel.tid,cyt.vintime)) AS forskel

som driller?
Avatar billede arne_v Ekspert
03. august 2016 - 15:15 #5
Kunne du evt. flytte noget af bregningen fra SQL til PHP?

Det er noget mere fleksibelt.
Avatar billede sevinding Juniormester
03. august 2016 - 16:05 #6
Ja.det er lige nøjagtigt den forskel, der driller, samt den lange indlæsningstid.
Jeg troede at beregningen var PHP.
Som sagt er jeg en non-geni til det. Det meste af det jeg har, er mere eller mindre klippe-klistre.
Kunne du evt. give et eksempel på hvordan jeg kan flytte det?
Ved godt det lyder krævende, men håbet er jo lysegrønt.
Avatar billede arne_v Ekspert
03. august 2016 - 16:46 #7
Utestet!

SQL:

(TIMEDIFF(yel.tid,cyt.vintime)) AS forskel

->

TIME_TO_SEC(yel.tid) AS t, TIME_TO_SEC(cyt.vintime) AS vt

PHP kode:

$t = $row['t'];
$vt = $row['vt'];
$delta = $t - $vt;
$delta_sec = $delta % 60;
$delta = (int)($delta / 60);
$delta_min = $delta % 60;
$delta = (int)($delta / 60);
$delta_hrs = $delta;
$delta_str = sprintf('%d:%02d:%02d', $delta_hrs, $delta_min, $delta_sec);
Avatar billede sevinding Juniormester
03. august 2016 - 18:07 #8
Mange tak. Så er dere noget at lege med.
Hvordan aflønner man svar nu?
Avatar billede arne_v Ekspert
03. august 2016 - 18:20 #9
Du markerer et indlaeg som en loesning.
Avatar billede arne_v Ekspert
03. august 2016 - 18:20 #10
Men du kan jo godt vente til du har set det virke.
Avatar billede sevinding Juniormester
04. august 2016 - 10:14 #11
Hej Arne.
Jeg har insat sådan her:

        while($r = mysql_fetch_array($res)) {

        $t = $row['t'];
        $vt = $row['vt'];
        $delta = $t - $vt;
        $delta_sec = $delta % 60;
        $delta = (int)($delta / 60);
        $delta_min = $delta % 60;
        $delta = (int)($delta / 60);
        $delta_hrs = $delta;
        $delta_str = sprintf('%d:%02d:%02d', $delta_hrs, $delta_min, $delta_sec);

og udskriver sådan her:

echo "<td width='10%' align='right' valign='bottom'>".$delta_str."</td>";

Det giver en forskel på 0:00:00 hele vejen ned.
Udskriver jeg det rigtige? Kan ikke lige lure hvad det ellers kan være.
Avatar billede arne_v Ekspert
04. august 2016 - 15:00 #12
Indeholder $t og $vt hvad de skal?
Avatar billede sevinding Juniormester
04. august 2016 - 15:49 #13
De indeholder alle noget lignende det her 91:00:26 og op til 299:33:33
Jeg vil lige sige, at ved siden af datafeltet er der en boks der siger:
Choose Time
Tid
23:59:59
Time
Minut
Sekund
Millisecond
Microsecond
Time Zone

og 23:59:59 er det højeste den kan vise.
Indsætter jeg eksempelvis 91:00:26 bliver det lavet om til 23:00:26
Indsætter jeg derimod 910026 bliver det 91:00:26
Det var der ikke sidste år, hvor jeg opdaterede.
Avatar billede arne_v Ekspert
04. august 2016 - 16:00 #14
TIME_TO_SEC(yel.tid) AS t, TIME_TO_SEC(cyt.vintime) AS vt

skulle gerne goere at $t og $vt indeholder rene tal.
Avatar billede sevinding Juniormester
04. august 2016 - 16:40 #15
Hvis jeg udskriver:
echo "<td align='right' valign='bottom'>$r[t]&nbsp;$r[vt]</td>"; kommer der 2 gange mange sekunder.
Kan det være:
echo "<td width='8%' align='right' valign='bottom'>+&nbsp;".$delta_str."</td>"; der er forkert?
Avatar billede arne_v Ekspert
04. august 2016 - 16:50 #16
Kan du give mig et eksempel paa $r[t] $r[vt] $delta_str output saa jeg kan regne efter.
Avatar billede sevinding Juniormester
04. august 2016 - 17:00 #17
$r[t] = 83:36:02 : 300962     
$r[t] = 83:36:02 : 340394
".$delta_str." = 0:00:00   
Kan ses på: http://www.tourfacts.dk/by_year/yearly/class1.php?aar=2004

Duaner ikke hvor taknemlig jeg er over din tålmodighed. Men jeg er nødt til at forlade stolen for idag.
Avatar billede arne_v Ekspert
04. august 2016 - 20:53 #18
Jeg er ikke sikker paa at jeg forstaar dette output.

Hvad er 83:36:02 : 300962?

83:36:02.300962 ?

I saa fald er resultatet af udregningen jo korrekt, da forskellen kun er 0.04 sekund, men data er jo saa aabenlyst forkerte.
Avatar billede sevinding Juniormester
05. august 2016 - 05:35 #19
Det var uintelligent af mig at formulere det på den måde.
86:36:02 (86 timer 36 minutter 02 sekunder) er det der er indsat i tabellen.
300962 er et eksempel på $r[t]
300962 er et eksempel på $r[vt] (efter ny input af 'cyt.aar=$aar' i WHERE linien)
0:00:00 er et eksempel på ".$delta_str."
Avatar billede arne_v Ekspert
07. august 2016 - 17:24 #20
Der maa blive hevet noget forkert ud af databasen.

Tid 86:36:02 og vindertid det samme skal give en tidsdiffererence paa 0:00:00.

Men det er jo kun for vinderen at tid er lig vindertid.
Avatar billede sevinding Juniormester
08. august 2016 - 06:23 #21
Det er rigtigt.
Men kigger man på $t er det forskellige antal sekunder der bliver udskrevet ved hhv. 2, 3, osv. Mens $vt er konstant hele vejen ned:
http://www.tourfacts.dk/by_year/yearly/class1.php?aar=2016
Avatar billede arne_v Ekspert
08. august 2016 - 17:40 #22
<?php
        $t=320933;
        $vt=302688;
        $delta = $t - $vt;
        $delta_sec = $delta % 60;
        $delta = (int)($delta / 60);
        $delta_min = $delta % 60;
        $delta = (int)($delta / 60);
        $delta_hrs = $delta;
        $delta_str = sprintf('%d:%02d:%02d', $delta_hrs, $delta_min, $delta_sec);
        echo $delta_str;
?>

giver mig:

5:04:05

her.
Avatar billede sevinding Juniormester
08. august 2016 - 18:49 #23
Det skal det også. Og som sagt bliver sekundtallet skrevet rigtigt ud.
Det eneste sted der sådan set kan være en fejl, må være her:

echo "<td width='8%' align='right' valign='bottom'>".$delta_str."</td>";

Har også prøvet:

echo "<td width='8%' align='right' valign='bottom'>$delta_str</td>";

uden held.
Avatar billede arne_v Ekspert
09. august 2016 - 00:44 #24
For du beregnet $delta_str for hver raekke?
Avatar billede sevinding Juniormester
09. august 2016 - 05:04 #25
Det mener jeg da. Nu tager jeg mig den frihed at sende hele query'en:

$res = mysql_query("SELECT

alt.nummer AS nummer,
alt.ayear AS ayear,
alt.hold AS hold,
ryt.logo AS logo,
ryt.id AS rytterid,
ryt.name AS ryttername,
tea.id AS id,
tea.land AS land,
tea.name AS teamname,
lan.landid AS landid,
lan.fodeland AS fodeland,
lan.inter AS inter,
sta.afstand AS afstand,
yel.place AS place,
yel.tid AS tid,
yel.winnerspoint AS winnerspoint,
cyt.vinid AS vinid,
cyt.aar AS aar,
cyt.vintime AS vintime,

        SUM(sta.afstand) AS ialt,
        SEC_TO_TIME(SUM(TIME_TO_SEC(yel.tid))) AS sum,
        3600*SUM(sta.afstand)/SUM(TIME_TO_SEC(yel.tid)) AS gns,

        TIME_TO_SEC(yel.tid) AS t, TIME_TO_SEC(cyt.vintime) AS vt

       
        FROM alt AS alt
        INNER JOIN ryt AS ryt ON alt.navn = ryt.id
        INNER JOIN cl_yellow AS yel ON yel.name = ryt.id
        INNER JOIN teams AS tea ON alt.hold = tea.id
        INNER JOIN stages AS sta
          INNER JOIN class_yellow_winner AS cyt
        INNER JOIN lande AS lan ON ryt.land = lan.landid

        WHERE alt.ayear=$aar AND alt.navn = ryt.id AND yel.yelyear=$aar AND cyt.aar=$aar GROUP BY    ryt.id ORDER BY yel.place ASC");
        $i = 1;
        while($r = mysql_fetch_array($res)) {

        $t = $row['t'];
        $vt = $row['vt'];
        $delta = $t - $vt;
        $delta_sec = $delta % 60;
        $delta = (int)($delta / 60);
        $delta_min = $delta % 60;
        $delta = (int)($delta / 60);
        $delta_hrs = $delta;
        $delta_str = sprintf('%d:%02d:%02d', $delta_hrs, $delta_min, $delta_sec);

        $snit_afrundet = number_format( $r['gns'], 3, ",", "." );

        echo "<table width='100%' border='0' cellspacing='0' cellpadding='2'id='gul'><tr>";
        echo "<td width='5%' align='right' valign='bottom'>" . $i++ . "&nbsp;</td>";
        echo "<td width='5%' align='center' valign='bottom' class='land'>$r[inter]</td>";
        echo "<td width='25%' align='left' valign='bottom'><a href=http://www.tourfacts.dk/root/tour_de_france_riders.php?id=$r[rytterid] class='link2' target='_self'>$r[ryttername]</a></td>";
        echo "<td width='30%' align='left' valign='bottom'><a href='teamriders.php?aar=$aar&hold=$r[id]&name=$r[teamname]' class='link2'>$r[teamname]</a></td>";
        echo "<td width='10%' align='right' valign='bottom'>$r[tid]</td>";
        echo "<td width='8%' align='right' valign='bottom'>+&nbsp;$delta_str</td>";
        echo "<td align='right' valign='bottom'>t=$r[t]&nbsp;vt=$r[vt]</td>";
        echo "</tr></table>";
}
        $number = 0;
?>

Det er det, der popper op på class1.php
Avatar billede arne_v Ekspert
11. august 2016 - 04:48 #26
Proev og erstat:

$t = $row['t'];
$vt = $row['vt'];

med:

$t = $r['t'];
$vt = $r['vt'];
Avatar billede sevinding Juniormester
11. august 2016 - 05:12 #27
Og så man man sige; i bagklogskabens utrolig klare lys: "Selvfølgelig"
Men sådan er det nok, når man får løsningen serveret.
Jeg kan ikke sige mange tusind tak nok; men tusind tak for hjælpen.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester