Het lijkt erop dat het niet uitmaakt welke tijdzone zich op de server bevindt, zolang je de tijd goed hebt ingesteld voor de huidige tijdzone, de tijdzone kent van de datetime-kolommen die je opslaat en je bewust bent van de problemen met zomertijd.
Aan de andere kant, als u controle heeft over de tijdzones van de servers waarmee u werkt, kunt u alles intern op UTC instellen en hoeft u zich geen zorgen te maken over tijdzones en DST.
Hier zijn enkele opmerkingen die ik heb verzameld over het werken met tijdzones als een soort cheatsheet voor mezelf en anderen, die van invloed kunnen zijn op de tijdzone die de persoon kiest voor zijn/haar server en hoe hij/zij de datum en tijd opslaat.
MySQL-tijdzone-cheatsheet
Opmerkingen:
-
Het wijzigen van de tijdzone zal de opgeslagen datum/tijdstempel niet wijzigen , maar het zal een andere datum/tijd selecteren uit de kolommen met tijdstempel
-
Waarschuwing! UTC heeft schrikkelseconden, deze zien eruit als '2012-06-30 23:59:60' en kunnen willekeurig worden toegevoegd, met een opzegtermijn van 6 maanden, vanwege de vertraging van de rotatie van de aarde
-
GMT verwart seconden, daarom is UTC uitgevonden.
-
Waarschuwing! verschillende regionale tijdzones kunnen vanwege de zomertijd dezelfde datum/tijd-waarde opleveren
-
De tijdstempelkolom ondersteunt alleen datums 1970-01-01 00:00:01 tot 2038-01-19 03:14:07 UTC, vanwege een beperking .
-
Intern een MySQL-tijdstempelkolom wordt opgeslagen als UTC maar bij het selecteren van een datum zal MySQL deze automatisch converteren naar de tijdzone van de huidige sessie.
Bij het opslaan van een datum in een tijdstempel, gaat MySQL ervan uit dat de datum zich in de tijdzone van de huidige sessie bevindt en converteert deze naar UTC voor opslag.
-
MySQL kan gedeeltelijke datums opslaan in datetime-kolommen, deze zien eruit als "2013-00-00 04:00:00"
-
MySQL slaat "0000-00-00 00:00:00" op als u een datetime-kolom instelt als NULL, tenzij u de kolom specifiek instelt om null toe te staan wanneer u deze aanmaakt.
Een tijdstempelkolom in UTC-indeling selecteren
ongeacht in welke tijdzone de huidige MySQL-sessie zich bevindt:
SELECT
CONVERT_TZ(`timestamp_field`, @@session.time_zone, '+00:00') AS `utc_datetime`
FROM `table_name`
U kunt ook de tijdzone van de server of de globale of huidige sessie instellen op UTC en vervolgens het tijdstempel als volgt selecteren:
SELECT `timestamp_field` FROM `table_name`
Om de huidige datum/tijd in UTC te selecteren:
SELECT UTC_TIMESTAMP();
SELECT UTC_TIMESTAMP;
SELECT CONVERT_TZ(NOW(), @@session.time_zone, '+00:00');
Voorbeeld resultaat:2015-03-24 17:02:41
Om de huidige datetime in de sessietijdzone te selecteren
SELECT NOW();
SELECT CURRENT_TIMESTAMP;
SELECT CURRENT_TIMESTAMP();
Om de tijdzone te selecteren die was ingesteld toen de server werd gelanceerd
SELECT @@system_time_zone;
Retourneert "MSK" of "+04:00" voor Moskou-tijd, bijvoorbeeld, er is (of was) een MySQL-bug waarbij, indien ingesteld op een numerieke offset, de zomertijd niet zou worden aangepast
Om de huidige tijdzone te krijgen
SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);
Het zal 02:00:00 terugkeren als uw tijdzone +2:00 is.
Om de huidige UNIX-tijdstempel te krijgen (in seconden):
SELECT UNIX_TIMESTAMP(NOW());
SELECT UNIX_TIMESTAMP();
Om de tijdstempelkolom als UNIX-tijdstempel te krijgen
SELECT UNIX_TIMESTAMP(`timestamp`) FROM `table_name`
Om een UTC datetime-kolom als UNIX-tijdstempel te krijgen
SELECT UNIX_TIMESTAMP(CONVERT_TZ(`utc_datetime`, '+00:00', @@session.time_zone)) FROM `table_name`
Verkrijg een huidige tijdzone datetime van een positief UNIX-tijdstempel integer
SELECT FROM_UNIXTIME(`unix_timestamp_int`) FROM `table_name`
Krijg een UTC datetime van een UNIX-tijdstempel
SELECT CONVERT_TZ(FROM_UNIXTIME(`unix_timestamp_int`), @@session.time_zone, '+00:00')
FROM `table_name`
Krijg een huidige tijdzone datetime van een negatief UNIX-tijdstempel integer
SELECT DATE_ADD('1970-01-01 00:00:00',INTERVAL -957632400 SECOND)
Er zijn 3 plaatsen waar de tijdzone kan worden ingesteld in MySQL:
Let op:Een tijdzone kan in 2 formaten worden ingesteld:
- een offset van UTC:'+00:00', '+10:00' of '-6:00'
- als een benoemde tijdzone:'Europe/Helsinki', 'US/Eastern' of 'MET'
Benoemde tijdzones kunnen alleen worden gebruikt als de tabellen met tijdzone-informatie in de mysql-database zijn gemaakt en ingevuld.
in het bestand "my.cnf"
default_time_zone='+00:00'
of
timezone='UTC'
@@global.time_zone variabele
Om te zien op welke waarde ze zijn ingesteld
SELECT @@global.time_zone;
Gebruik een van beide om er een waarde voor in te stellen:
SET GLOBAL time_zone = '+8:00';
SET GLOBAL time_zone = 'Europe/Helsinki';
SET @@global.time_zone='+00:00';
@@session.time_zone variabele
SELECT @@session.time_zone;
Gebruik een van beide om het in te stellen:
SET time_zone = 'Europe/Helsinki';
SET time_zone = "+00:00";
SET @@session.time_zone = "+00:00";
zowel "@@global.time_zone variabele" als "@@session.time_zone variabele" kunnen "SYSTEM" retourneren, wat betekent dat ze de tijdzone gebruiken die is ingesteld in "my.cnf".
Om tijdzonenamen te laten werken (zelfs voor standaardtijdzone), moet u uw tijdzone-informatietabellen instellen die moeten worden ingevuld: http://dev.mysql.com/doc /refman/5.1/en/time-zone-support.html
Opmerking:u kunt dit niet doen omdat het NULL teruggeeft:
SELECT
CONVERT_TZ(`timestamp_field`, TIMEDIFF(NOW(), UTC_TIMESTAMP), '+00:00') AS `utc_datetime`
FROM `table_name`
Mysql-tijdzonetabellen instellen
Voor CONVERT_TZ
om te werken, moeten de tijdzonetabellen worden ingevuld
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` ;
Als ze leeg zijn, vul ze dan op door deze opdracht uit te voeren
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
als deze opdracht je de foutmelding "gegevens te lang geeft voor kolom 'afkorting' op rij 1 ", dan kan dit worden veroorzaakt doordat er een NULL-teken wordt toegevoegd aan het einde van de tijdzone-afkorting
de oplossing is om dit uit te voeren
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
(zorg ervoor dat de dst-regels van uw servers up-to-date zijn zdump -v Europe/Moscow | grep 2011
https://chrisjean.com/updating-daylight-saving-time- on-linux/
)
Bekijk de volledige DST-overgangsgeschiedenis (zomertijd) voor elke tijdzone
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
past ook eventuele noodzakelijke zomertijdwijzigingen toe op basis van de regels in de bovenstaande tabellen en de datum die u gebruikt.
Opmerking:
Volgens de docs , verandert de waarde die u instelt voor time_zone niet, als u deze bijvoorbeeld instelt als "+01:00", dan wordt de time_zone ingesteld als een offset van UTC, die niet volgt op DST, dus het blijft allemaal hetzelfde het hele jaar door.
Alleen de genoemde tijdzones verandert de tijd tijdens de zomertijd.
Afkortingen zoals CET
zal altijd een wintertijd zijn en CEST
zal zomertijd zijn terwijl +01:00 altijd UTC
zal zijn tijd + 1 uur en beide veranderen niet met DST.
Het system
timezone is de tijdzone van de hostcomputer waarop mysql is geïnstalleerd (tenzij mysql deze niet kan bepalen)
U kunt hier meer lezen over het werken met DST.
Wanneer u UTC van de legendarische Jon Skeet niet moet gebruiken:https://codeblog.jonskeet.uk/2019/03/27/storing-utc-is-not-a-silver-bullet/ (Bijvoorbeeld een geplande gebeurtenis in de toekomst die een tijd vertegenwoordigt, niet een moment in de tijd)
gerelateerde vragen:
- Hoe stel ik de tijdzone van MySQL in?
- MySql - SELECT TimeStamp Column in UTC-formaat
- Hoe Unix-tijdstempel in MySQL krijgen van UTC-tijd?
- Server MySQL TimeStamp converteren naar UTC
- https://dba. stackexchange.com/questions/20217/mysql-set-utc-time-as-default-timestamp
- Hoe Ik krijg de huidige tijdzone van MySQL?
- MySQL datum/tijd-velden en zomertijd -- hoe verwijs ik naar het "extra" uur?
- Negatieve waarden converteren van FROM_UNIXTIME
Bronnen:
- 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/en/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