How do I set a timestamp column whose default value is the current UTC time?
MySQL uses UTC_TIMESTAMP()
function for UTC timestamp:
mysql> SELECT UTC_TIMESTAMP();
+---------------------+
| UTC_TIMESTAMP() |
+---------------------+
| 2012年07月01日 11:36:35 |
+---------------------+
1 row in set (0.00 sec)
So I've tried:
CREATE TABLE `blah` (
`creation_time` TIMESTAMP DEFAULT UTC_TIMESTAMP,
...
And other variations, like UTC_TIMESTAMP()
, but without success.
6 Answers 6
To go along with @ypercube's comment that CURRENT_TIMESTAMP
is stored as UTC but retrieved as the current timezone, you can affect your server's timezone setting with the --default_time_zone option for retrieval. This allows your retrieval to always be in UTC.
By default, the option is 'SYSTEM' which is how your system time zone is set (which may or may not be UTC!):
mysql> SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| SYSTEM | SYSTEM |
+--------------------+---------------------+
1 row in set (0.00 sec)
mysql> SELECT CURRENT_TIMESTAMP();
+---------------------+
| CURRENT_TIMESTAMP() |
+---------------------+
| 2012年09月25日 16:28:45 |
+---------------------+
1 row in set (0.00 sec)
You can set this dynamically:
mysql> SET @@session.time_zone='+00:00';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| SYSTEM | +00:00 |
+--------------------+---------------------+
1 row in set (0.00 sec)
Or permanently in your my.cnf:
[mysqld]
**other variables**
default_time_zone='+00:00'
Restart your server, and you will see the change:
mysql> SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| +00:00 | +00:00 |
+--------------------+---------------------+
1 row in set (0.00 sec)
mysql> SELECT CURRENT_TIMESTAMP();
+---------------------+
| CURRENT_TIMESTAMP() |
+---------------------+
| 2012年09月25日 20:27:50 |
+---------------------+
1 row in set (0.01 sec)
-
3
-
Is it possible to specify
default_time_zone
for a specific table or database? Thanks.W.M.– W.M.2016年08月11日 15:20:29 +00:00Commented Aug 11, 2016 at 15:20 -
2Is it possible to specify default_time_zone for a specific query?mcmillab– mcmillab2016年08月22日 05:06:33 +00:00Commented Aug 22, 2016 at 5:06
-
@mcmillab you can set the session timezone prior to running the query, then reset to the global timezone before running further queries (or re-connect).Derek Downey– Derek Downey2016年08月22日 13:39:40 +00:00Commented Aug 22, 2016 at 13:39
-
Following on mcmillab -- or to query the column with an operator that shows the underlying UTC value (since conversion isn't 1-to1)?Marc L.– Marc L.2017年06月30日 15:03:26 +00:00Commented Jun 30, 2017 at 15:03
With MySQL 8.0.13, you can use UTC_TIMESTAMP
as the default value if you surround it with parentheses like so:
CREATE TABLE `blah` (
id int NOT NULL AUTO_INCREMENT,
creation_time TIMESTAMP NOT NULL DEFAULT (UTC_TIMESTAMP)
)
-
1Yes but it will not work if you add ON UPDATE like this:
creation_time TIMESTAMP NOT NULL DEFAULT (UTC_TIMESTAMP) ON UPDATE (UTC_TIMESTAMP)
here bugs.mysql.com/bug.php?id=103228 someone raised an issue for it. Lets hope they will solve itgshock– gshock2021年09月12日 14:46:05 +00:00Commented Sep 12, 2021 at 14:46 -
1@GeorgiStaykov that's my issue report I raised ;-)John C– John C2021年09月13日 03:36:01 +00:00Commented Sep 13, 2021 at 3:36
You cannot specify UTC_TIMESTAMP
as default to specify automatic properties. You should use only the DEFAULT CURRENT_TIMESTAMP
and ON UPDATE CURRENT_TIMESTAMP
clauses.
Also, you can insert UTC_TIMESTAMP
values like this though for a table:
CREATE TABLE `test` (
`ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
The INSERT
query would be like this to insert UTC_TIMESTAMP
:
INSERT INTO `test` (`ts`)
VALUES
(UTC_TIMESTAMP());
-
1Thanks for "You can not specify UTC_TIMESTAMP as default to specify automatic properties"Barbaros Alp– Barbaros Alp2016年02月01日 13:44:50 +00:00Commented Feb 1, 2016 at 13:44
My solution is with a trigger:
DELIMITER //
CREATE TRIGGER `update_to_utc` BEFORE INSERT ON `my_table` FOR EACH ROW BEGIN
set new.my_field=utc_timestamp();
END//
DELIMITER ;
Then every new inserted row will have the timestamp in UTC.
-
I'd recommend using
SET new.my_field = COALESCE(new.created_at, UTC_TIMESTAMP()
instead, so you can still have other values in case of restore data for example, this will only set the UTC_TIMESTAMP if the inserted value is NULL. (This still works if the column is NOT NULL)Romuald Brunet– Romuald Brunet2024年01月09日 10:09:58 +00:00Commented Jan 9, 2024 at 10:09
John C's solution worked for me with
`Created` datetime NOT NULL DEFAULT (UTC_TIMESTAMP)
but I also had to change the sql modes because when I tried to add an index to this table I would get the error "ERROR 1067 (42000): Invalid default value"
removing the modes NO_ZERO_IN_DATE,NO_ZERO_DATE
resolved the issue with setting up the indexes.
set global sql_mode = "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"
-
1They fixed that error in 8.0.24, I reported it in 8.022. bugs.mysql.com/bug.php?id=101486John C– John C2021年09月13日 03:38:11 +00:00Commented Sep 13, 2021 at 3:38
for mariadb only the global my.cnf solutions did work
for mariadb 10.2, the permanent solution of @Derek Downey in this post.
[mysqld]
**other variables**
default_time_zone='+00:00'
for mariadb 10.0 (i had 10.0.32), see https://stackoverflow.com/questions/947299/how-do-i-make-mysqls-now-and-curdate-functions-use-utc
[mysqld_safe]
**other variables**
timezone = UTC
both definitions may coexist in my.cnf of mariadb 10.2, but i don't have mariadb 10.0 anymore.
hope this will help you.
CURRENT_TIMESTAMP
?MySQL converts TIMESTAMP values from the current time zone to UTC for storage, and back from UTC to the current time zone for retrieval.
CURRENT_TIMESTAMP
). From the same documentation page:(This does not occur for other types such as DATETIME.)
.