Det lader til, at det er ligegyldigt, hvilken tidszone der er på serveren, så længe du har den rigtige tid indstillet til den aktuelle tidszone, kender tidszonen for de datetime-kolonner, du gemmer, og er opmærksom på problemerne med sommertid.
På den anden side, hvis du har kontrol over tidszonerne på de servere, du arbejder med, kan du få alt sat til UTC internt og aldrig bekymre dig om tidszoner og sommertid.
Her er nogle noter, jeg har samlet om, hvordan man arbejder med tidszoner som en form for cheatsheet for mig selv og andre, som kan have indflydelse på, hvilken tidszone personen vil vælge til sin server, og hvordan han/hun gemmer dato og klokkeslæt.
MySQL Timezone Cheatsheet
Bemærkninger:
-
Ændring af tidszonen vil ikke ændre det gemte dato og klokkeslæt eller tidsstemplet , men det vil vælge en anden dato og klokkeslæt fra tidsstempelkolonner
-
Advarsel! UTC har skudsekunder, disse ser ud som '2012-06-30 23:59:60' og kan tilføjes tilfældigt med 6 måneders varsel på grund af afmatningen af jordens rotation
-
GMT forvirrer sekunder, og derfor blev UTC opfundet.
-
Advarsel! Forskellige regionale tidszoner producerer muligvis den samme dato og klokkeslæt på grund af sommertid
-
Tidsstempelkolonnen understøtter kun datoer 1970-01-01 00:00:01 til 2038-01-19 03:14:07 UTC, på grund af en begrænsning .
-
Internt en MySQL-tidsstempelkolonne er gemt som UTC men når du vælger en dato, vil MySQL automatisk konvertere den til den aktuelle sessions tidszone.
Når du gemmer en dato i et tidsstempel, vil MySQL antage, at datoen er i den aktuelle sessions tidszone og konvertere den til UTC for lagring.
-
MySQL kan gemme delvise datoer i datetime-kolonner, disse ser ud som"2013-00-00 04:00:00"
-
MySQL gemmer "0000-00-00 00:00:00", hvis du indstiller en datetime-kolonne som NULL, medmindre du specifikt indstiller kolonnen til at tillade null, når du opretter den.
For at vælge en tidsstempelkolonne i UTC-format
uanset hvilken tidszone den aktuelle MySQL-session er i:
SELECT
CONVERT_TZ(`timestamp_field`, @@session.time_zone, '+00:00') AS `utc_datetime`
FROM `table_name`
Du kan også indstille serveren eller den globale eller aktuelle sessions tidszone til UTC og derefter vælge tidsstemplet sådan:
SELECT `timestamp_field` FROM `table_name`
Sådan vælger du den aktuelle dato og klokkeslæt i UTC:
SELECT UTC_TIMESTAMP();
SELECT UTC_TIMESTAMP;
SELECT CONVERT_TZ(NOW(), @@session.time_zone, '+00:00');
Eksempelresultat:2015-03-24 17:02:41
For at vælge den aktuelle dato og klokkeslæt i sessionens tidszone
SELECT NOW();
SELECT CURRENT_TIMESTAMP;
SELECT CURRENT_TIMESTAMP();
For at vælge den tidszone, der blev indstillet, da serveren startede
SELECT @@system_time_zone;
Returnerer "MSK" eller "+04:00" for Moskva-tid for eksempel, der er (eller var) en MySQL-fejl, hvor den, hvis den er indstillet til en numerisk offset, ikke ville justere sommertiden
For at få den aktuelle tidszone
SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);
Den vender tilbage 02:00:00, hvis din tidszone er +2:00.
For at få det aktuelle UNIX-tidsstempel (i sekunder):
SELECT UNIX_TIMESTAMP(NOW());
SELECT UNIX_TIMESTAMP();
For at få tidsstempelkolonnen som et UNIX-tidsstempel
SELECT UNIX_TIMESTAMP(`timestamp`) FROM `table_name`
For at få en UTC-dato-tidskolonne som et UNIX-tidsstempel
SELECT UNIX_TIMESTAMP(CONVERT_TZ(`utc_datetime`, '+00:00', @@session.time_zone)) FROM `table_name`
Få en aktuel tidszone dato/klokkeslæt fra et positivt UNIX-tidsstempel-heltal
SELECT FROM_UNIXTIME(`unix_timestamp_int`) FROM `table_name`
Få en UTC-datotid fra et UNIX-tidsstempel
SELECT CONVERT_TZ(FROM_UNIXTIME(`unix_timestamp_int`), @@session.time_zone, '+00:00')
FROM `table_name`
Få en aktuel tidszone dato/klokkeslæt fra et negativt UNIX-tidsstempel-heltal
SELECT DATE_ADD('1970-01-01 00:00:00',INTERVAL -957632400 SECOND)
Der er 3 steder, hvor tidszonen kan indstilles i MySQL:
Bemærk:En tidszone kan indstilles i 2 formater:
- en offset fra UTC:'+00:00', '+10:00' eller '-6:00'
- som en navngivet tidszone:'Europe/Helsinki', 'US/Eastern' eller 'MET'
Navngivne tidszoner kan kun bruges, hvis tidszoneinformationstabellerne i mysql-databasen er blevet oprettet og udfyldt.
i filen "my.cnf"
default_time_zone='+00:00'
eller
timezone='UTC'
@@global.time_zone variabel
For at se, hvilken værdi de er sat til
SELECT @@global.time_zone;
For at indstille en værdi for det, brug enten en:
SET GLOBAL time_zone = '+8:00';
SET GLOBAL time_zone = 'Europe/Helsinki';
SET @@global.time_zone='+00:00';
@@session.time_zone variabel
SELECT @@session.time_zone;
For at indstille det, brug enten en:
SET time_zone = 'Europe/Helsinki';
SET time_zone = "+00:00";
SET @@session.time_zone = "+00:00";
både "@@global.time_zone variable" og "@@session.time_zone variable" returnerer muligvis "SYSTEM", hvilket betyder, at de bruger tidszonen indstillet i "my.cnf".
For at tidszonenavne skal fungere (selv for standardtidszone), skal du konfigurere dine tidszoneoplysninger, der skal udfyldes: http://dev.mysql.com/doc /refman/5.1/da/time-zone-support.html
Bemærk:du kan ikke gøre dette, da det vil returnere NULL:
SELECT
CONVERT_TZ(`timestamp_field`, TIMEDIFF(NOW(), UTC_TIMESTAMP), '+00:00') AS `utc_datetime`
FROM `table_name`
Opsæt mysql-tidszonetabeller
For CONVERT_TZ
for at fungere, skal tidszonetabellerne udfyldes
SELECT * FROM mysql.`time_zone` ;
SELECT * FROM mysql.`time_zone_leap_second` ;
SELECT * FROM mysql.`time_zone_name` ;
SELECT * FROM mysql.`time_zone_transition` ;
SELECT * FROM mysql.`time_zone_transition_type` ;
Hvis de er tomme, så fyld dem op ved at køre denne kommando
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
hvis denne kommando giver dig fejlen "data for lange til kolonne 'forkortelse' i række 1 ", så kan det være forårsaget af et NULL-tegn, der er tilføjet i slutningen af tidszoneforkortelsen
rettelsen er at køre dette
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
(if the above gives error "data too long for column 'abbreviation' at row 1")
mysql_tzinfo_to_sql /usr/share/zoneinfo > /tmp/zut.sql
echo "SET SESSION SQL_MODE = '';" > /tmp/mysql_tzinfo_to.sql
cat /tmp/zut.sql >> /tmp/mysql_tzinfo_to.sql
mysql --defaults-file=/etc/mysql/my.cnf --user=verifiedscratch -p mysql < /tmp/mysql_tzinfo_to.sql
(sørg for, at dine servers dst-regler er opdaterede zdump -v Europe/Moscow | grep 2011
https://chrisjean.com/updating-daylight-saving-time- on-linux/
)
Se hele DST (sommertid) overgangshistorik for hver tidszone
SELECT
tzn.Name AS tz_name,
tztt.Abbreviation AS tz_abbr,
tztt.Is_DST AS is_dst,
tztt.`Offset` AS `offset`,
DATE_ADD('1970-01-01 00:00:00',INTERVAL tzt.Transition_time SECOND) AS transition_date
FROM mysql.`time_zone_transition` tzt
INNER JOIN mysql.`time_zone_transition_type` tztt USING(Time_zone_id, Transition_type_id)
INNER JOIN mysql.`time_zone_name` tzn USING(Time_zone_id)
-- WHERE tzn.Name LIKE 'Europe/Moscow' -- Moscow has weird DST changes
ORDER BY tzt.Transition_time ASC
CONVERT_TZ
anvender også alle nødvendige sommertidsændringer baseret på reglerne i ovenstående tabeller og den dato, du bruger.
Bemærk:
Ifølge dokumenterne , den værdi du indstiller for time_zone ændres ikke, hvis du indstiller den som "+01:00" for eksempel, så vil tidszonen blive sat som en offset fra UTC, som ikke følger sommertid, så den forbliver den samme alle året rundt.
Kun de navngivne tidszoner vil ændre tid i sommertid.
Forkortelser som CET
vil altid være en vintertid og CEST
vil være sommertid, mens +01:00 altid vil være UTC
tid + 1 time, og begge vil ikke ændre sig med sommertid.
system
tidszone vil være tidszonen på værtsmaskinen, hvor mysql er installeret (medmindre mysql ikke kan bestemme det)
Du kan læse mere om at arbejde med sommertid her
Hvornår skal man ikke bruge UTC af den legendariske Jon Skeet:https://codeblog.jonskeet.uk/2019/03/27/storing-utc-is-not-a-silver-bullet/ (For eksempel en planlagt begivenhed i fremtiden, der repræsenterer et tidspunkt, ikke et øjeblik i tid)
relaterede spørgsmål:
- Hvordan indstiller jeg tidszonen for MySQL?
- MySql - VÆLG TimeStamp Column i UTC-format
- Sådan få Unix-tidsstempel i MySQL fra UTC-tid?
- Konvertering af Server MySQL TimeStamp til UTC
- https://dba. stackexchange.com/questions/20217/mysql-set-utc-time-as-default-timestamp
- Hvordan gør Jeg får den aktuelle tidszone for MySQL?
- MySQL datotidsfelter og sommertid -- hvordan refererer jeg til den "ekstra" time?
- Konvertering af negative værdier fra FROM_UNIXTIME
Kilder:
- https://bugs.mysql.com/bug.php?id=68861
- http://dev. mysql.com/doc/refman/5.0/en/date-and-time-functions.html
- http://dev.mysql.com/doc/ refman/5.1/da/datetime.html
- http://en.wikipedia.org/wiki/Coordinated_Universal_Time
- http://shafiqissani.wordpress.com/2010/09/30/how-to-get-the-current-epoch-time-unix-timestamp/
- https://web.ivy.net/~carton/ rant/MySQL-timezones.txt