sql >> Database >  >> RDS >> Mysql

Hoe om te gaan met MySQL-tijdzone in script

Je hebt deze tijddiagnostische query uitgevoerd op je MySQL-server.

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

Uit uw lokale tijd en utc-tijd blijkt duidelijk dat de systeemtijdzone-instelling van uw servermachine 'Canada/Mountain' is en dat de MySQL-serversoftware geen eigen tijdzone-instelling heeft.

Als u uw tafels oppakt en ze ongewijzigd naar een server in een nabijgelegen tijdzone verplaatst, kunt u uw software altijd bijwerken om de opdracht

te geven
set time_zone = 'Canada/Mountain';

direct nadat u verbinding hebt gemaakt vanuit uw software. Hierdoor zal uw nieuwe MySQL-verbinding zich qua tijdzone gedragen zoals uw huidige. Als u de MySQL-server bezit, kunt u de standaardtijdzone instellen volgens de aanwijzingen op deze pagina. http://dev.mysql.com/doc /refman/5.5/en/time-zone-support.html

Dit is het verhaal over tijdgegevenstypen. DATE , TIME , en DATETIME zijn allemaal tijdzone-onwetend . Zodra je een datum/tijd-waarde hebt opgeslagen, krijg je dezelfde waarde terug, zelfs als je je tijdzone-instellingen wijzigt.

De TIMESTAMP gegevenstype is tijdzonegevoelig . Die gegevensitems worden altijd opgeslagen in UTC, ook wel bekend als Z, time , voorheen bekend als Greenwich Mean Time. Ze worden altijd geconverteerd naar UTC wanneer ze worden opgeslagen, en altijd terug geconverteerd wanneer ze worden opgehaald.

De ingebouwde functies voor het verkrijgen van de huidige datum en tijd (NOW() en vrienden) zijn tijdzonegevoelig . Ze leveren waarden op in lokale tijd. De uitzonderingen zijn de drie functies die beginnen met UTC_ die waarden opleveren in UTC-tijd.

Veel MySQL-toepassingen met meerdere tijdzones gebruiken de volgende operationele discipline:

  1. Vraag elke gebruiker om een ​​tijdzone met gebruikersvoorkeur, of bereken deze uit andere persoonlijke gegevens over de gebruiker. (Telefoons hebben deze informatie van het netwerk voorzien.) Bewaar dat als een zoneinfo-vriendelijk tijdzonedescriptor ('America/New_York', 'Canada/Mountain', 'Europe/Wenen', etc) namens de gebruiker.
  2. Bij het opzetten van een MySQL-sessie namens de gebruiker, stelt u de tijdzone van de gebruiker in met een set time_zone query zoals hierboven weergegeven. Doe dit direct na uw connect operatie.
  3. Sla datums en tijden voor gebruikers op in TIMESTAMP gegevens typen. Ze worden geconverteerd naar UTC terwijl ze worden opgeslagen.
  4. Haal ze indien nodig op. Ze worden teruggezet naar de lokale tijd.

Het idee is dat de tijdzone van uw gebruiker deel uitmaakt van haar context. Dit werkt goed, want als gebruiker A in Vancouver is en gebruiker B in Halifax, en om de een of andere reden gebruiker B de tijdgegevens van gebruiker A bekijkt, wordt deze min of meer automatisch aan B in Atlantische tijd getoond.

Het is ook goed omdat het transparant omgaat met de wereldwijde grillen van het veranderen van daglicht naar standaardtijd. Een tijdstempel van afgelopen zomer wordt weergegeven in de lokale tijd van afgelopen zomer.

Veel beheerders van servers voor wereldwijd gebruik stellen hun systeemservertijd of hun MySQL-standaardtijdzone in op UTC. (De jouwe niet.)

Een andere manier om dit allemaal aan te pakken is de manier waarop je bent begonnen. Kies een tijdzone en sla uw tijdstempels op met betrekking tot die tijdzone. Kies dan het beste voor een tijdzone die niet afwisselt tussen daglicht en standaardtijd. Converteer vervolgens expliciet wanneer u tijden in de database opslaat. Je zou tijden van gebruikers in Ottawa opslaan door zoiets te doen.

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

en je zou de waarden op dezelfde manier krijgen. Dit is foutgevoelig, maar u kunt het laten werken.

Ten slotte kunt u uw conversies zelf uitvoeren. Als u wilt weten hoeveel minuten verschuiving er zijn tussen een willekeurige tijdzone en UTC, kunt u deze twee zoekopdrachten proberen.

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

In deze tijd van het jaar geeft dat -240 terug, wat -4:00 is. In sommige landen moet u minuten gebruiken in plaats van uren vanwege tijdzoneverschuivingen van een half uur of een kwartier.

Tot slot, kijk uit. TIMESTAMP gegevenstypen vertegenwoordigen geen tijden vóór 1970. En op mijn MariaDB 10.0-instantie lijkt het naar de hel te gaan na 2038-01-19T03:14:07 UTC wanneer de tijd voorbijgaat uit 32 bits.




  1. MySQL:selecteer alle datums tussen datumbereik en ontvang tabelgegevens die overeenkomen met datums

  2. Database implementeren vanuit bronbeheer

  3. Fix 'ERROR:kolom "colname" bestaat niet' in PostgreSQL bij gebruik van UNION, BEHALVE of INTERSECT

  4. Hoe html op te slaan in een mysql-database