Du kørte denne tidsdiagnostiske forespørgsel på din MySQL-server.
select @@time_zone, now(), utc_timestamp()
Det fremgår tydeligt af din lokale tid og UTC-tid, at din servermaskines systemtidszoneindstilling er 'Canada/Mountain', og MySQL-serversoftwaren har ikke sin egen tidszoneindstilling.
Hvis du samler dine borde op og flytter dem uændret til en server i en nærliggende tidszone, kan du altid opdatere din software for at udstede kommandoen
set time_zone = 'Canada/Mountain';
lige efter du har oprettet forbindelse fra din software. Dette vil få din nye MySQL-forbindelse til at opføre sig, som din nuværende gør tidszonemæssigt. Hvis du ejer MySQL-serveren, kan du indstille dens standardtidszone i henhold til anvisningerne på denne side. http://dev.mysql.com/doc /refman/5.5/da/time-zone-support.html
Her er historien om tidsdatatyper. DATE
, TIME
og DATETIME
er alle tidszone-uvidende . Når du har gemt en dato/tidsværdi, får du den samme værdi tilbage, selvom du ændrer dine tidszoneindstillinger.
TIMESTAMP
datatypen er tidszonefølsom . Disse dataelementer gemmes altid i UTC, også kendt som Z, tid
, tidligere kendt som Greenwich Mean Time. De konverteres altid til UTC, når de er gemt, og konverteres altid tilbage, når de hentes.
De indbyggede funktioner
for at få aktuel dato og tid (NOW()
og venner) er tidszonefølsomme . De vil give værdier i lokal tid. Undtagelserne er de tre funktioner, der starter med UTC_
som giver værdier i UTC-tid.
Mange MySQL multi-time-zone applikationer bruger følgende operationelle disciplin:
- Spørg hver bruger om en brugerpræferencetidszone, eller find ud af det ud fra en anden smule personlige data om brugeren. (Telefoner har disse oplysninger leveret fra netværket.) Gem det som en zoneinfo-venlig tidszonebeskrivelse ('America/New_York', 'Canada/Mountain', 'Europe/Wien' osv.) på brugerens vegne.
- Når du etablerer en MySQL-session på vegne af brugeren, skal du indstille brugerens tidszone med en
set time_zone
forespørgsel som den, der er vist ovenfor. Du bør gøre dette lige efter dinconnect
operation. - Gem datoer og klokkeslæt for brugere i
TIMESTAMP
datatyper. De bliver konverteret til UTC, efterhånden som de gemmes. - Hent dem efter behov. De bliver konverteret tilbage til lokal tid.
Tanken er, at din brugers tidszone er en del af hendes kontekst. Dette fungerer godt, for hvis bruger A er i Vancouver og bruger B i Halifax, og bruger B af en eller anden grund ser bruger A's tidsdata, vil det mere eller mindre automatisk blive vist til B i atlantisk tid.
Det er også godt, fordi det på en gennemsigtig måde håndterer de globale luner af dagslys til standardtid, der skifter. Et tidsstempel fra sidste sommer vil blive vist i sidste sommers lokale tid.
Mange ledere af servere til global brug indstiller deres systemservertid eller deres MySQL-standardtidszone til UTC. (Det gør din ikke.)
En anden måde at håndtere alt dette på er måden, hvorpå du er startet. Vælg en tidszone og gem dine tidsstempler i forhold til den tidszone. Det er bedst, hvis du vælger en tidszone, der i så fald ikke veksler mellem dagslys og standardtid. Derefter, når du gemmer tider i databasen, skal du konvertere eksplicitet. Du ville gemme tider fra brugere i Ottawa ved at gøre sådan noget.
INSERT INTO tbl (appt) VALUES ( 'whatever-time' - INTERVAL 120 MINUTE)
og du ville få værdierne ud på samme måde. Dette er udsat for fejl, men du kan få det til at fungere.
Endelig kan du selv foretage dine konverteringer. Hvis du vil vide, hvor mange minutters offset der er mellem en vilkårlig tidszone og UTC, kan du prøve disse to forespørgsler.
set time_zone = 'Canada/Atlantic';
select timestampdiff(minute, utc_timestamp(), now());
På denne tid af året giver det -240 tilbage, hvilket er -4:00. Du skal bruge minutter i stedet for timer på grund af tidszoneforskydninger på en halv time eller et kvarter i nogle lande.
Pas endelig på. TIMESTAMP
datatyper repræsenterer ikke tider før 1970. Og på mit MariaDB 10.0-forekomst ser det ud til at gå ad helvede til lige efter 2038-01-19T03:14:07 UTC, når tiden ruller over ud af 32 bit.