Dato og tid
Regn med tidspunkter, og unngå de tre fellene som tar de fleste: lokal tid, kalenderdager i millisekunder, og måling med veggklokka.
Tid ser enkelt ut helt til det ikke er det. Denne oppskriften viser det grunnleggende, og de tre fellene som tar de fleste.
funksjon start() -> heltall {
la naa = builtin.now_ms()
skriv("Millisekunder siden 1970: " + tekst(naa))
la ett_dogn = 24 * 60 * 60 * 1000
la i_morgen = naa + ett_dogn
skriv("Om et døgn: " + tekst(i_morgen))
returner 0
}Hva som skjer her
builtin.now_ms gir antall millisekunder siden midnatt 1. januar 1970 i UTC. Det er ett enkelt tall, uten tidssone, uten sommertid, uten format. Nettopp derfor er det et godt lagringsformat: to slike tall kan alltid sammenlignes og trekkes fra hverandre, uansett hvor i verden de ble laget.
Felle 1: å lagre lokal tid
Den vanligste feilen er å lagre tidspunkter som lokal tekst, for eksempel klokkeslett og dato slik en nordmann skriver dem.
Da får du to problemer hvert år. Om høsten stilles klokka tilbake, og timen mellom to og tre opptrer to ganger — du kan ikke vite hvilken av dem en lagret verdi mener. Om våren hopper klokka fram, og den timen finnes ikke i det hele tatt. Har du lagret et tidspunkt der, er det ugyldig.
Legger du til brukere i flere land, blir det verre: to hendelser lagret som lokal tid kan ikke sammenlignes uten å vite hvilken sone hver av dem kom fra.
Regelen: lagre alltid i UTC som millisekunder. Gjør om til lokal tid først i det øyeblikket et menneske skal lese det.
Felle 2: å regne kalenderdager i millisekunder
Koden over legger til 86 400 000 millisekunder og kaller det et døgn. Det stemmer som regel — men ikke alltid.
De to dagene i året der klokka stilles, er ett døgn henholdsvis 23 og 25 timer i lokal tid. Legger du til 86 400 000 millisekunder på en dato rett før overgangen, havner du på feil klokkeslett. For en påminnelse som skal komme klokka ni hver morgen, betyr det at den plutselig kommer klokka åtte eller ti.
Skal du legge til en kalenderdag — altså samme klokkeslett neste dag — bruk kalenderfunksjonene i std.kalender. Skal du legge til nøyaktig 24 timer, er millisekunder riktig. Det er to forskjellige ting, og forskjellen merkes bare to dager i året. De to dagene er nok til å ødelegge tilliten til systemet ditt.
Felle 3: å måle tid med veggklokka
Skal du måle hvor lang tid noe tok, er now_ms ikke ideelt. Systemklokka kan justeres mens du måler — av tidssynkronisering, eller av en administrator — og da kan differansen bli negativ eller absurd stor.
Til varighetsmåling og ytelsestesting har standardbiblioteket std.timeit, som bruker en klokke som bare går framover.
Kort oppsummert
- Lagre i UTC-millisekunder. Alltid.
- Vis lokal tid, så sent som mulig, bare for mennesker.
- Regn i kalenderfunksjoner når du mener kalenderdager, i millisekunder når du mener eksakt tid.
- Mål varighet med
std.timeit, ikke med veggklokka.
Les også
- En webtjeneste med flere ruterEt komplett program som svarer på flere adresser, leser spørrestrengen og returnerer både HTML og ren tekst.
- Lagre og hente dataOpprett en tabell, skriv rader og les dem ut igjen — med de innebygde databasefunksjonene, og uten ett spørsmål per rad.
- Hashe et passord trygtArgon2id fra standardbiblioteket — riktig verktøy for passord, uten en eneste ekstern avhengighet.