Mijn vraag gaat over het correct werken met datums en tijden. Ik denk dat ik nu namelijk (waarschijnlijk) een probleem heb met tijdzones. Dit is een verwarrende vraag! Dus ik hoop dat ik het goed uitleg. Anders hoor ik het graag.
Ik ben een applicatie aan het ontwikkelen waarbij o.a. afspraken kunnen worden opgeslagen in een agenda van de gebruiker. Deze mogelijkheid lijkt een beetje op de agenda die veel mensen kennen van bijvoorbeeld Outlook.
De interactie met de server is in de vorm van een API.
Het clientside gedeelte van de app is een desktop programma (dus geen omgeving in webbrowser). Alle output van de server is in JSON format. Alle input van de client is een simpele formdata POST request, GET request, of POST request met de input in JSON format.
Hier is een relevant stukje van de JSON die de client naar de server stuurt als de gebruiker een afspraak in zijn agenda zet:
{
"agenda_id":"2",
"user_id":"1",
"title":"Vergadering",
"description":"Vergadering over laatste kwartaal 2021...",
"start_date":"2022-02-06T09:00:00+01:00",
"end_date":"2022-02-06T11:30:00+01:00",
"location":"Kantoor, ruimte ...",
}
Let op de start_date en end_date in de JSON. Dit is uiteraard de start en eind datum en tijd van de afspraak. (Het is overigens dus ook mogelijk dat een afspraak meerdere dagen duurt).
In de client code (desktop app geschreven in C#) gebruik ik altijd voor elke datum een DateTime object (vrijwel volledig vergelijkbaar met PHP's ingebouwde DateTime class).
Als ik een datum en tijd heb: 2022-02-06 09:00, en hiervan maak ik een DateTime object op de client, dan wordt dit: 2022-02-06T09:00:00+01:00. Je zier hier dat er vanzelf een offset van +01:00 aan de tijd is toegevoegd door de client. Dat komt omdat de tijdzone in Nederland UTC+01:00 is.
Ik heb dit zo gelaten, want het lijkt me correct, en wordt door het systeem vanzelf zo toegevoegd. (Logica van DateTime class).
Dus de server ontvangt datums zoals: 2022-02-06T09:00:00+01:00 waaruit ook de tijdzone is af te leiden.
De datums sla ik op in een MySQL database, in een DATETIME kolom.
Als ik dan in PhpMyAdmin kijk, bevat de kolom de volgende waarde: 2022-02-06 09:00:00. Hierbij is de tijdzone (die +01:00) weer weg.
Als ik vervolgens een API request doe naar de server om de afspraak te laden, dan ontvang ik van de server de volgende datum: 2022-02-06T09:00:00+00:00. Hierin zit wél weer een tijdzone component, (echter nu +00:00). Dat komt doordat:
- In de database kolom, zoals bleek, de datum zonder tijdzone wordt opgeslagen.
- PHP dus de string uit de database kolom ontvangt in de vorm: 2022-02-06 09:00:00
- Ik hiervan een PHP DateTime object maak, en dat deze DateTime automatisch +00:00 krijgt als ik deze in JSON output. De PHP DateTime plakt er een tijdzone aan, en deze is hier +00:00 omdat de tijdzone van de server UTC is.
De client ontvangt de JSON dan met de datum string 2022-02-06T09:00:00+00:00.
De client verwerkt de datum string in een C# DateTime. Hij ziet "+00:00" en denkt: dit is UTC-0 tijd. De client weet dat hij in Nederland is, en dat NL een UTC +01:00 offset heeft, dus maakt de client er doodleuk 2022-02-06T10:00:00+01:00 van.
Ik begrijp het bijna zelf niet meer, dus wil ik weten hoe je correct omgaat met datums en tijd op een consistente wijze.
Ik wil de datums graag opslaan als UTC tijd, wat betekent dat ze soort van 'tijdzone onafhankelijk zijn', maar ik begrijp dit niet goed.
Ook ben ik erachter gekomen dat het kolomtype DATETIME in MySQL geen tijdzone informatie in de waarde opslaat, wat ik ook weer raar vind.
Als je daarentegen bijvoorbeeld naar kolomtype TIMESTAMP kijkt, blijkt dat hierbij de datums impliciet gewoon als een unix timestamp worden opgeslagen (het aantal seconden sinds 01-01-1970), en dat dit UTC-0 tijd is.
Ik ben bereid om dingen volledig om te gooien, maar begrijp gewoon niet hoe ik moet werken met datum-tijden, hoe ik ze correct opsla, en hoe ik verwarring met tijdzones voorkom.
Wat ik ook niet zou weten, is of het nou wel/niet goed is dat de client automatisch de datums omzet op basis van tijdzone.
Iemand een idee of hetzelfde probleem gehad? Laat me weten als ik ergens niet duidelijk ben.