Fouten in nieuwsscript
Pagina: « vorige 1 2 3 volgende »
Maar dan kan '.$row['date'].' op rij 30 beter weggelaten worden.
Ik ga nu alles bij langs om te corrigeren en op te schonen ;)
Beveiliging van het gastenboek moet nog aan gewerkt worden :)
Nu het volgende, ik wil de datumnotatie graag veranderen van 2015-10-01 naar b.v. 10 okt 2015.
Moet dat in mysql aangepast worden of kan ik dat in deze code aanpassen:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
echo '<table class="news">';
while($row = mysqli_fetch_array($result))
{
if($_SESSION['rechten'] == true)
{
echo "id:" ." ". $row['id']; echo "<br>";
}
echo '<tr>';
echo '<td>'.$row['datum'].' '.$row['date'].'</td>';
echo '<td>'.$row['Agendapunt'].' '.$row['message'].'</td>';
echo '</tr>';
}
echo '</table>';
if($_SESSION['rechten'] == true)
{
?>
while($row = mysqli_fetch_array($result))
{
if($_SESSION['rechten'] == true)
{
echo "id:" ." ". $row['id']; echo "<br>";
}
echo '<tr>';
echo '<td>'.$row['datum'].' '.$row['date'].'</td>';
echo '<td>'.$row['Agendapunt'].' '.$row['message'].'</td>';
echo '</tr>';
}
echo '</table>';
if($_SESSION['rechten'] == true)
{
?>
En wat is het verschil tussen de velden 'date' en 'datum'?
Formatteer je data (vlak) voordat je deze afdrukt.
Wanneer je je datums opslaat in het formaat waarmee je ze afdrukt ("10 okt 2015") dan heb je het jezelf haast onmogelijk gemaakt om hier op te sorteren. Dit is een vaak gemaakte (beginners)fout.
Sla data (en datums :)) altijd in hun rauwe, ongewijzigde formaat op. De formattering kan altijd nog (en stel dit moment zo lang mogelijk uit). Een omgekeerde bewerking (geformatteerde variant > rauwe variant) is vaak veel moeilijker of zelfs onmogelijk. Laat data in zijn (oorspronkelijke) waarde.
Het verschil tussen deze velden is slordigheid, ben vergeten dit aan te passen.
Het ziet er nu als volgt uit:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
echo '<table class="news">';
while($row = mysqli_fetch_array($result))
{
if($_SESSION['rechten'] == true)
{
echo "id:" ." ". $row['id']; echo "<br>";
}
echo '<tr>';
echo '<td>'.$row['date'].'</td>';
echo '<td>'.$row['message'].'</td>';
echo '</tr>';
}
echo '</table>';
while($row = mysqli_fetch_array($result))
{
if($_SESSION['rechten'] == true)
{
echo "id:" ." ". $row['id']; echo "<br>";
}
echo '<tr>';
echo '<td>'.$row['date'].'</td>';
echo '<td>'.$row['message'].'</td>';
echo '</tr>';
}
echo '</table>';
@Thomas van den Heuvel:
Ik begrijp niet wat je bedoeld, het gaat alleen maar om de weergave op de pagina.
Er hoeft niets afgedrukt te worden.
Met afdrukken bedoeld hij weergeven op de pagina ;)
Maar hoe is de datum in de database opgeslagen? Hoe ziet dat veld eruit, en welke type heeft deze volgens phpMyAdmin? Ik neem aan een DATETIME-type?
DateTime object opslaan.
Dit doe je door $row['date'] in een object te plaatsen:
Vervolgens kun je de datum weergeven zoals je wilt:
Ook kun je op deze manier beter met datums rekenen, vergelijken en sorteren.
Datums kun je het beste opslaan in een (mysql) DATETIME type. Bij het uitlezen kun je ze het beste in een (PHP) Dit doe je door $row['date'] in een object te plaatsen:
Vervolgens kun je de datum weergeven zoals je wilt:
Code (php)
Ook kun je op deze manier beter met datums rekenen, vergelijken en sorteren.
Omdat DATETIME geen UNIX-epoch timestamp is.
- Aar - op 11/10/2015 15:23:42:
Omdat DATETIME geen UNIX-epoch timestamp is.
En daar stip je meteen een (ander) interessant verschil aan: DATE(TIME) velden hebben geen indicatie van tijdszone (voor zover ik weet?). Je zult dus zelf een soort van uniformiteit moeten afdwingen en zelf voorzieningen aanbrengen om tijd(stipp)en om te rekenen van tijdszone A naar tijdszone B.
Als ik mijn datum uitlees zie ik 2015-10-11
date("d-m-Y", $row['']);
Geeft bij mij 11-10-2015
Toevoeging op 11/10/2015 15:40:58:
Ehh...
Kleine update:
date("d-m-Y", strtotime($row['date']));
Thomas van den Heuvel op 11/10/2015 15:35:38:
En daar stip je meteen een (ander) interessant verschil aan: DATE(TIME) velden hebben geen indicatie van tijdszone (voor zover ik weet?).
Ja en nee. Datums en tijden worden door MySQL intern opgeslagen in UTC, maar ook automatisch geconverteerd naar de huidige tijdzone (tz). Voor een leuke cheatsheet:
http://stackoverflow.com/questions/19023978/should-mysql-have-its-timezone-set-to-utc
Quote:
Changing the timezone will not change the stored datetime or timestamp, but it will select a different datetime from timestamp columns (maar niet van DATETIME kolommen dus)
Maar dat betekent dan toch dat kolommen van het DATETIME type niet timezone-aware zijn (die laatste "datetime" heeft betrekking op de geretourneerde "datum-en-tijd" van een TIMESTAMP kolom als ik het goed begrijp)?
Alleen TIMESTAMP kolommen worden dus automatisch omgezet, maar DATETIME kolommen niet. Deze geven dus ook niet een andere datum/tijd terug als je van tijdszone verandert, dit zul je handmatig moeten oplossen.
Het wordt ook min of meer gezegd in de eerste alinea "...know the timezone of the datetime columns that you store...", hieruit volgt al min of meer dat je deze apart zou moeten bijhouden of documenteert wat deze zou moeten zijn (en UTC is natuurlijk een handige / de beste? / de enige? default) omdat DATETIMEs zich zelf niet bewust zijn van een tijdszone.
Voorbeeld:
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
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
mysql> CREATE TABLE timetest (
-> id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> dt DATETIME NOT NULL,
-> ts TIMESTAMP NOT NULL
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.04 sec)
mysql> desc timetest;
+-------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| dt | datetime | NO | | NULL | |
| ts | timestamp | NO | | NULL | |
+-------+---------------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
mysql> SET @@session.time_zone = '+02:00';
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO timetest(dt, ts) VALUES (NOW(), NOW());
Query OK, 1 row affected (0.01 sec)
mysql> SELECT * FROM timetest;
+----+---------------------+---------------------+
| id | dt | ts |
+----+---------------------+---------------------+
| 1 | 2015-10-11 16:13:56 | 2015-10-11 16:13:56 |
+----+---------------------+---------------------+
1 row in set (0.00 sec)
mysql> SET @@session.time_zone = '+00:00';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * FROM timetest;
+----+---------------------+---------------------+
| id | dt | ts |
+----+---------------------+---------------------+
| 1 | 2015-10-11 16:13:56 | 2015-10-11 14:13:56 |
+----+---------------------+---------------------+
1 row in set (0.00 sec)
-> id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> dt DATETIME NOT NULL,
-> ts TIMESTAMP NOT NULL
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.04 sec)
mysql> desc timetest;
+-------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| dt | datetime | NO | | NULL | |
| ts | timestamp | NO | | NULL | |
+-------+---------------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
mysql> SET @@session.time_zone = '+02:00';
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO timetest(dt, ts) VALUES (NOW(), NOW());
Query OK, 1 row affected (0.01 sec)
mysql> SELECT * FROM timetest;
+----+---------------------+---------------------+
| id | dt | ts |
+----+---------------------+---------------------+
| 1 | 2015-10-11 16:13:56 | 2015-10-11 16:13:56 |
+----+---------------------+---------------------+
1 row in set (0.00 sec)
mysql> SET @@session.time_zone = '+00:00';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * FROM timetest;
+----+---------------------+---------------------+
| id | dt | ts |
+----+---------------------+---------------------+
| 1 | 2015-10-11 16:13:56 | 2015-10-11 14:13:56 |
+----+---------------------+---------------------+
1 row in set (0.00 sec)
Q.E.D.?
Long story short: datums-en-tijden in DATETIME kolommen zijn niet timezone-aware.
Gewijzigd op 11/10/2015 16:26:21 door Thomas van den Heuvel
Ja, correct. Het is een onderschat probleem, omdat data meestal worden hergebruikt in dezelfde tijdzone als ze zijn opgeslagen.
Wat je voor zuivere koffie eigenlijk zou moeten doen, is zowel PHP als MySQL voor de weergave instellen op de tijdzone van de gebruiker en achter de schermen alles in UTC opslaan. In plaats van NOW() gebruik ik bijvoorbeeld UTC_TIMESTAMP().
Wellicht bedoelen wij hetzelfde, maar verwoorden we het verschillend. Maar ik zou dus aan 1 kant alle tijdstip-functies volledig uitbannen. De andere kant geeft wel door hoe laat het is.
Gewijzigd op 11/10/2015 16:51:45 door Thomas van den Heuvel
Ja, maar dan moet de afhankelijke van de twee nog steeds snappen wat er met 16:59 wordt bedoeld. Ik vind het "dus" makkelijker om alles te standaardiseren op bijvoorbeeld UTC. Dan weet je namelijk: alles is UTC, tenzij je er bewust voor kiest daarvan af te wijken, bijvoorbeeld om een tijd in de locale van de gebruiker te tonen.
Jup en die varchar(12) zou ik veranderen in datetime.