Tijd en mysql
Ik heb een topic systeem dat werkt met tijd nu wil ik niet gewoon de tijd er in hebben maar bv: 14 uur geleden, 2 seconden geleden, een dag geleden, een week geleden.
Hoe kan ik dit het beste maken?
datum-/tijdfuncties in MySQL de gewenste gegevens in je query bepalen...
In je database sla je de timestamp op in een DATETIME veld in het formaat yyyy-mm-dd hh:mm:ss. Vervolgens kun je met de Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
$some_time_stamp = "2011-12-31 00:00:00";
$time_remaining = strtotime($some_time_stamp) - time();
print age($time_remaining) . " remaining till new years evening!";
function age($seconds, $stop_at_days = false, $return_on_zero = "0") {
if($seconds <= 60) {
if($seconds < 0) {
return $return_on_zero;
} else {
return $seconds . ' second' . (($seconds == 1) ? '':'s');
}
} elseif($seconds <= 3600) {
return round($seconds / 60) . ' minute' . ((round($seconds / 60) == 1) ? '':'s');
} elseif($seconds <= 86400) {
return round($seconds / 3600) . ' hour' . ((round($seconds / 3600) == 1) ? '':'s');
} elseif($seconds <= 604800 || $stop_at_days) {
return round($seconds / 86400) . ' day' . ((round($seconds / 86400) == 1) ? '':'s');
} elseif($seconds <= 2419200) {
return round($seconds / 604800) . ' week' . ((round($seconds / 604800) == 1) ? '':'s');
} elseif($seconds <= 29030400) {
return round($seconds / 2419200) . ' month' . ((round($seconds / 2419200) == 1) ? '':'s');
} else {
return round($seconds / 29030400) . ' year' . ((round($seconds / 29030400) == 1) ? '':'s');
}
}
?>
$some_time_stamp = "2011-12-31 00:00:00";
$time_remaining = strtotime($some_time_stamp) - time();
print age($time_remaining) . " remaining till new years evening!";
function age($seconds, $stop_at_days = false, $return_on_zero = "0") {
if($seconds <= 60) {
if($seconds < 0) {
return $return_on_zero;
} else {
return $seconds . ' second' . (($seconds == 1) ? '':'s');
}
} elseif($seconds <= 3600) {
return round($seconds / 60) . ' minute' . ((round($seconds / 60) == 1) ? '':'s');
} elseif($seconds <= 86400) {
return round($seconds / 3600) . ' hour' . ((round($seconds / 3600) == 1) ? '':'s');
} elseif($seconds <= 604800 || $stop_at_days) {
return round($seconds / 86400) . ' day' . ((round($seconds / 86400) == 1) ? '':'s');
} elseif($seconds <= 2419200) {
return round($seconds / 604800) . ' week' . ((round($seconds / 604800) == 1) ? '':'s');
} elseif($seconds <= 29030400) {
return round($seconds / 2419200) . ' month' . ((round($seconds / 2419200) == 1) ? '':'s');
} else {
return round($seconds / 29030400) . ' year' . ((round($seconds / 29030400) == 1) ? '':'s');
}
}
?>
Bedankt allebei we gaan er eens wat dingen mee proberen.
Als ik zo'n dingen maak, probeer ik steeds zoveel mogelijk de Unix seconden te vermijden.
Je houdt hier geen enkele rekening met zomer-/ wintertijd, met schrikkeljaren, schrikkelseconden.
Nu ja, zoals je zegt, het gaat om code uit duistere tijden
Kris Peeters op 09/03/2011 11:00:18:
Je houdt hier geen enkele rekening met zomer-/ wintertijd, met schrikkeljaren, schrikkelseconden.
En het belangrijkste noem je nog niet eens: het feit of een maand 28, 30 of 31 dagen heeft.
Kortom, het gegeven voorbeeld is op z'n minst onnauwkeurig. Rekenen met data en tijden kun je daarom ook beter over laten aan de database. Deze is daar over het algemeen beter in en hoef je niet meer in PHP te gaan rotzooien :-)
Oei, ja, die had ik niet eens gezien :)
Maar kan iemand een klein voor beeldje kunnen geven hoe zo iets er uit zou gaan zien zo dat ik het zelf verder kan maken?
Je wil dus als resultaat slechts 1 eenheid.
Als het 56 minuten geleden is, wil je het uitgedrukt ( enkel ) in minuten; als het 65 minuten geleden is, wil je het in aantal uren ...
Minuutje, ik zal eens iets schrijven.
Nu, ik veronderstel dat je in de database een veld hebt met data Type DATETIME. Juist?
-----------------------------
Een lastig gevoel in mijn dikke teen vertelt me dat dit waarschijnlijk efficiënter kan, maar ja, volgens mij doet het wat je verlangt.
created is mijn datetime veld
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?php
$db = mysql_connect('localhost', 'root', 'mijn_paswoord');
mysql_select_db('phphulp', $db);
// Vervang * door de velden die je nodig hebt
$sql = "
SELECT *
, YEAR(NOW()) - YEAR(created) AS jaren
, MONTH(NOW()) - MONTH(created) AS maanden
, DAY(NOW()) - DAY(created) AS dagen
, HOUR(NOW()) - HOUR(created) AS uren
, MINUTE( TIMEDIFF(NOW(), created) ) AS minuten
, SECOND( TIMEDIFF(NOW(), created) ) AS seconden
FROM mijn_berichten
";
$res = mysql_query($sql);
while($row = mysql_fetch_assoc($res)) {
$tijd_geleden = one_timeunit_diff($row);
echo $row['id'] .' - '. $tijd_geleden . ' geleden <br/>' ;
}
function one_timeunit_diff($row) {
if ($row['jaren'] > 0) {
return $row['jaren'] . ($row['jaren'] == 1 ? ' jaar' : ' jaar');
}
if ($row['maanden'] > 0) {
return $row['maanden'] . ($row['maanden'] == 1 ? ' maand' : ' maanden');
}
if ($row['dagen'] > 0) {
return $row['dagen'] . ($row['dagen'] == 1 ? ' dag' : ' dagen');
}
if ($row['uren'] > 0) {
return $row['uren'] . ($row['uren'] == 1 ? ' uur' : ' uur');
}
if ($row['minuten'] > 0) {
return $row['minuten'] . ($row['minuten'] == 1 ? ' minuut' : ' minuten');
}
else {
$row['seconden'] = (int) $row['seconden'];
return $row['seconden'] . ($row['seconden'] == 1 ? ' seconde' : ' seconden');
}
}
?>
$db = mysql_connect('localhost', 'root', 'mijn_paswoord');
mysql_select_db('phphulp', $db);
// Vervang * door de velden die je nodig hebt
$sql = "
SELECT *
, YEAR(NOW()) - YEAR(created) AS jaren
, MONTH(NOW()) - MONTH(created) AS maanden
, DAY(NOW()) - DAY(created) AS dagen
, HOUR(NOW()) - HOUR(created) AS uren
, MINUTE( TIMEDIFF(NOW(), created) ) AS minuten
, SECOND( TIMEDIFF(NOW(), created) ) AS seconden
FROM mijn_berichten
";
$res = mysql_query($sql);
while($row = mysql_fetch_assoc($res)) {
$tijd_geleden = one_timeunit_diff($row);
echo $row['id'] .' - '. $tijd_geleden . ' geleden <br/>' ;
}
function one_timeunit_diff($row) {
if ($row['jaren'] > 0) {
return $row['jaren'] . ($row['jaren'] == 1 ? ' jaar' : ' jaar');
}
if ($row['maanden'] > 0) {
return $row['maanden'] . ($row['maanden'] == 1 ? ' maand' : ' maanden');
}
if ($row['dagen'] > 0) {
return $row['dagen'] . ($row['dagen'] == 1 ? ' dag' : ' dagen');
}
if ($row['uren'] > 0) {
return $row['uren'] . ($row['uren'] == 1 ? ' uur' : ' uur');
}
if ($row['minuten'] > 0) {
return $row['minuten'] . ($row['minuten'] == 1 ? ' minuut' : ' minuten');
}
else {
$row['seconden'] = (int) $row['seconden'];
return $row['seconden'] . ($row['seconden'] == 1 ? ' seconde' : ' seconden');
}
}
?>
Gewijzigd op 10/03/2011 14:52:09 door Kris Peeters
helemaal super hier kan ik zeker wat mee ga er zo even lekker mee hobby.
Ditzelfde zou je ook in puur SQL voor elkaar kunnen krijgen. Kijk dan naar het gebruik van een/meerdere CASE statements...
Het was het eerste (qua algemeen principe) dat in me opkwam
Blanche / Kris Peeters zou het beter zijn met mysql.
En zo ja ik kan er niets over vinden om eerlijk te zijn heeft iemand daar misschien ook een klein voorbeeld van?
http://dev.mysql.com/doc/refman/5.0/en/control-flow-functions.html
Nu, meestal laat ik dit soort dingen liever door php doen.
Dit zal dan ook netjes 1 terug geven...
Je zult eerst het tijdsinterval moeten berekenen en daar vervolgens mee gaan rekenen. Helaas is MySQL van alle database daar ook weer niet de sterkste in, maar met functies als DATEDIFF() en TIMEDIFF() moet je een aardig eind kunnen komen.