sql >> Databasteknik >  >> RDS >> Mysql

Hur man hanterar MySQL-tidszon i skript

Du körde den här tidsdiagnostiska frågan på din MySQL-server.

select @@time_zone, now(), utc_timestamp()

Det framgår tydligt av din lokala tid och UTC-tid att din servermaskins systemtidszonsinställning är 'Kanada/Mountain' och att MySQL-serverprogramvaran inte har någon egen tidszonsinställning.

Om du plockar upp dina tabeller och flyttar dem oförändrade till en server i någon närliggande tidszon, kan du alltid uppdatera din programvara för att utfärda kommandot

set time_zone = 'Canada/Mountain';

direkt efter att du anslutit från din programvara. Detta kommer att få din nya MySQL-anslutning att bete sig som din nuvarande gör tidszonsmässigt. Om du äger MySQL-servern kan du ställa in dess standardtidszon enligt anvisningarna på den här sidan. http://dev.mysql.com/doc /refman/5.5/en/time-zone-support.html

Nu, här är historien om tidsdatatyper. DATE , TIME och DATETIME är alla ovitande om tidzon . När du har lagrat ett datum/tidsvärde får du tillbaka samma värde även om du ändrar dina tidszoninställningar.

TIMESTAMP datatypen är tidszonskänslig . Dessa dataposter lagras alltid i UTC, även känd som Z, tid , tidigare känd som Greenwich Mean Time. De konverteras alltid till UTC när de lagras och konverteras alltid tillbaka när de hämtas.

De inbyggda funktioner för att få aktuellt datum och tid (NOW() och vänner) är tidszonskänsliga . De kommer att ge värden i lokal tid. Undantagen är de tre funktionerna som börjar med UTC_ som ger värden i UTC-tid.

Många MySQL multi-time-zone-applikationer använder följande operativa disciplin:

  1. Fråga varje användare om en tidszon som användaren föredrar, eller ta reda på det utifrån någon annan del av personlig information om användaren. (Telefoner har den här informationen tillhandahållen från nätverket.) Lagra den som en zoninfovänlig tidszonsbeskrivning ('America/New_York', 'Kanada/Mountain', 'Europe/Wien', etc) för användarens räkning.
  2. När du har upprättat en MySQL-session på uppdrag av användaren, ställ in användarens tidszon med en set time_zone fråga som den som visas ovan. Du bör göra detta direkt efter din connect operation.
  3. Lagra datum och tider för användare i TIMESTAMP datatyper. De kommer att konverteras till UTC allt eftersom de lagras.
  4. Hämta dem vid behov. De konverteras tillbaka till lokal tid.

Tanken är att din användares tidszon är en del av hennes sammanhang. Detta fungerar bra, för om användare A är i Vancouver och användare B i Halifax, och användare B av någon anledning ser användare A:s tidsdata, kommer det att visas för B i Atlanttid mer eller mindre automatiskt.

Det är också bra eftersom det på ett transparent sätt hanterar de globala nycklarna av dagsljus till standardtid som förändras. En tidsstämpel från förra sommaren kommer att visas i förra sommarens lokala tid.

Många chefer för servrar för global användning ställer in sin systemservertid, eller deras MySQL-standardtidszon, till UTC. (Det gör inte din.)

Ett annat sätt att hantera allt detta är sättet du har börjat. Välj en tidszon och lagra dina tidsstämplar i förhållande till den tidszonen. Det är bäst om du väljer en tidszon som inte växlar mellan dagsljus och standardtid i så fall. Sedan, när du lagrar tider i databasen, konvertera explicitet. Du skulle spara tider från användare i Ottawa genom att göra något liknande.

INSERT INTO tbl (appt) VALUES ( 'whatever-time' - INTERVAL 120 MINUTE)

och du skulle få ut värdena på samma sätt. Detta är felbenäget men du kan få det att fungera.

Slutligen kan du göra dina omvandlingar själv. Om du vill veta hur många minuters offset det finns mellan en godtycklig tidszon och UTC, prova dessa två frågor.

set time_zone = 'Canada/Atlantic';
select timestampdiff(minute, utc_timestamp(), now());

Vid den här tiden på året ger det tillbaka -240, vilket är -4:00. Du måste använda minuter istället för timmar på grund av tidszonförskjutningar på halvtimme eller kvart i vissa länder.

Till sist, se upp. TIMESTAMP datatyper representerar inte tider före 1970. Och på min MariaDB 10.0-instans verkar det gå åt helvete i en hink direkt efter 2038-01-19T03:14:07 UTC när tiden rullar över 32 bitar.




  1. Skriv session start på 1 sida eller alla sidor?

  2. Hämta bild från databasen i asp.net

  3. hur man skapar mysql-schema i nodejs

  4. MySQL paginering utan dubbelfråga?