Assume the following table:
CREATE TABLE IF NOT EXISTS `test` (
`stamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
When I run the following SQL:
SET time_zone = '+00:00';
INSERT INTO `test` (`stamp`) VALUES (CURRENT_TIMESTAMP);
The value in test is my machine's local time instead of UTC.
According to MySQL site
Values for TIMESTAMP columns are converted from the current time zone
to UTC for storage, and from UTC to the current time zone for
retrieval.
What am I doing wrong? I want to store my records with UTC date/time stamp and retrieve them in the user's local time zone.
According to the MySQL 5.5 documentation using the TIMESTAMP data type will default to using the server's time zone unless you change the variable from the client side.
From: http://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html
Per-connection time zones. Each client that connects has its own time
zone setting, given by the session time_zone variable. Initially, the
session variable takes its value from the global time_zone variable,
but the client can change its own time zone with this statement:
mysql> SET time_zone = timezone;
Related
I have a MYSQL database that is on a remote shared server.
One of my columns in a table requires to populate automatically with the CURRENT_TIMESTAMP when the record is being populated with other data.
The database uses the SYSTEM time which is "UTC +00:00", but I need this to be "UTC +01:00"
I cannot use "SET GLOBAL time_zone = '+01:00';" as I don't have the priveliges (understandably), and understand there's no way to set a time_zone just at database level (beyond a session instance, this solution needs stick).
Is there a way that I can have my column populate with "CURRENT_TIMESTAMP + ADD ONE HOUR", like a calculation? As I'm looking for a solution at DB level to this.
I'm not db profficient, but appreciate any advice.
you can create a trigger that launched each time you insert in that column
DELIMITER $$
CREATE TRIGGER update_count
AFTER UPDATE ON table_name (time)
UPDATE table_name
SET HOUR(column_name) = SEC_TO_TIME((UNIX_TIMESTAMP(HOUR(column_name))+1)*60)
WHERE time= NEW.time;
END;
$$DELIMITER ;
Look for the function CONVERT_TZ
mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','GMT','MET');
-> '2004-01-01 13:00:00'
mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00');
-> '2004-01-01 22:00:00'
It might be of help to what you need, here's the docs:
https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_convert-tz
You will only change time zone,
Example:
CREATE TABLE IF NOT EXISTS test_timestamp (
t1 TIMESTAMP
);
SET time_zone='+00:00';
INSERT INTO test_timestamp
VALUES('2008-01-01 00:00:01');
SELECT
t1
FROM
test_timestamp;
t1='2008-01-01 00:00:01'
SET time_zone ='+03:00';
SELECT t1
FROM test_timestamp;
t1='2008-01-01 03:00:01'
Have a shared server and running a mysql trigger in which time is being inserted into a column as follows -
Insert INTO mytable SET time=now();
The table and the column time then gets a GMT time.
I want that local time is inserted into that table and column.
Tried this code but still giving GMT time on insertion -
set #localtime = CONVERT_TZ('now()','GMT','+5:30');
Insert INTO mytable SET time=#localtime;
The column time has settings of TIMESTAMP as default and if I change the settings to Varchar, it gives error - "#1048 - Column 'time' cannot be null"
Please help.
I found answer to this question -
set #localtime = (SELECT CONVERT_TZ('now()','##session.time_zone','+5:30'));
Insert INTO mytable SET time=#localtime;
I have a table containing datetime field. I want to select records with a condition that only those records that has datetime value above current IST time.
Example
select * from mytable where dt > current_ist_datetime
current_ist_datetime is what i do not know how to use. CONVERT_TZ() with NOW() can give it. But i do not know what timezone mysql uses. that is, i do not know second parameter that i should pass to CONVERT_TZ()
You can retrieve the timezone setting for the current MySQL session with a SQL statement:
mysql> SELECT ##session.time_zone;
If the DBA has not set the timezone on MySQL, it will default to a value of SYSTEM, which represents the timezone on the operating system.
http://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html
FOLLOWUP:
In a predicate as in your example SQL statement:
select * from mytable where dt > current_ist_datetime
(given dt and current_ist_datetime of datatype DATETIME)
the comparison of the values will be independent of any timezone conversion, since there is no no timezone information associated with a DATETIME value.
That is, the value returned from a column of datatype DATETIME is not affected by the time_zone setting of the MySQL server (SELECT ##global.time_zone) or of the MySQL session (SELECT ##session.time_zone).
The value returned by the NOW() function, however, will be impacted by the time_zone setting of the session.
To get that returned in IST, ensure the time_zone for the session is specified correctly, e.g.
SET VARIABLES time_zone = "+05:30"
(N.B. If the session is retrieved from and returned from a connection pool, the other users of the pool may not be expecting a different time_zone;...)
(NOTE: the above entirely ignores the confusion introduced by the JDBC driver, caused by the "impedance mismatch" (differences) between MySQL's implementation of DATETIME datatype, and Java implementation of Date object. If you are passing DATETIME values across a JDBC connection, that's whole 'nother ball of confusion.)
MySQL uses timezone in two formats; i.e. you can either use 'Asia/Calcutta' or '+05:30' (for IST). But I would suggest you use the latter one.
Timezone for UTC is '+00:00'. So you can use following query provided that dt is in UTC & current_ist_datetime is in IST
select * from mytable where dt > CONVERT_TZ(current_ist_datetime,'+05:30','+00:00')
I am using this query in my project where I paas current_ist_datetime & +05:30 from client(in IST) to my server(in UTC) & it works like a charm.
If you use NOW() mysql will select current date time of your system's timezone
select * from mytable where dt > CONVERT_TZ(NOW(),'+05:30','+00:00')
You can modify these queries according to your need.
I have a MySQL table which hen created automatically puts a ISO 8601 timestamp into one of the fields. It does this because I have set the default value thought phpMyAdmin to TIMESTAMP.
When I update the field I want to add another timestamp to another field. Obviously I cant do that using the default option. Is there an SQL command to add a current timestamp to a field? I have had a quick read through the MySQL website but I couldnt find a way to do it...
I also had a look to see if there was a way of generating an ISO8601 timestamp through PHP but I couldnt figure out a way to convert from a PHP/unix timestamp to ISO8601.
Cheers!
MySQL can automatically initialise and/or update a single TIMESTAMP type column within every table to the current time on INSERT and UPDATE. As explained in Automatic Initialization and Updating for TIMESTAMP:
One TIMESTAMP column in a table can have the current timestamp as the default value for initializing the column, as the auto-update value, or both. It is not possible to have the current timestamp be the default value for one column and the auto-update value for another column.
In your case, because you want separate columns to hold the record's initialisation and update times, you will need to set one (or both) of those columns explicitly; one can explicitly set a date/time column to the current date/time in SQL using the NOW() function:
INSERT INTO my_table (created) VALUES (NOW());
UPDATE my_table SET updated = NOW();
One can even use triggers to achieve the automatic behaviour that is not natively provided by MySQL:
CREATE TRIGGER set_init_time AFTER INSERT ON my_table FOR EACH ROW
SET NEW.created = NOW();
CREATE TRIGGER set_updt_time AFTER UPDATE ON my_table FOR EACH ROW
SET NEW.updated = NOW();
I need to keep track of the time a row was inserted into the database, and the time it was last modified.
I tried to create two separate columns, and use CURRENT_TIMESTAMP:
create table def (
id int,
creation timestamp
default CURRENT_TIMESTAMP,
modification timestamp
on update CURRENT_TIMESTAMP
);
However, this produced an error:
ERROR 1293 (HY000): Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
What is the best way to do this?
I'm thinking stored procedure, but looking for a standard solution. I'm also concerned with access privileges -- as few programs/things should be able to touch the timestamps as possible.
Although I would prefer MySQL answers, solutions for other RDBMS's are also appreciated!
Ya this is a lame limitation on MySQL. If you are going through an application you can add a time() call for the created_at column, and let the updated_at column use the CURRENT_TIMESTAMP.
$sql = "INSERT INTO my_table SET name = 'Mike', created_at = " . time();
I'd opt to do this on the created_at column as it probably won't be touched as often as the updated_at column.
-- Edit --
Better yet, use MySQL's built in now() function. This way you only need to be concerned with the timezone of the mysql server, and not the timezones of the app server AND the mysql server.
$sql = "INSERT INTO my_table SET name = 'Mike', created_at = NOW()";
You can use a trigger. The application can also set the value, but if do, it will be overwritten by the database.
delimiter //
CREATE TRIGGER def_bef_update BEFORE UPDATE ON def FOR EACH ROW BEGIN
SET NEW.modification = CURRENT_TIMESTAMP;
END//
delimiter ;
You can also use it to check the data and update your modification date only if has important changes.