I have a MySQL database, which I cannot alter, where I read date from. The issue is that I have a varchar column that stores a date. The date is stored in the atomtime format eg. 2014-06-01T00:00:00+02:00.
I cannot figure how to specify the format in the STR_TO_DATE function. I tried STR_TO_DATE(Endtime, '%Y-%m-%dT%H:%i:%s+02:00'), but that doesn't work.
Do anyone have a solution for this?
I am trying to run the following query (which is not working properly):
SELECT *, COUNT(*) as antal
FROM ivocall_calls
WHERE Agentname LIKE 'Vinh Nguyen'
AND Status1 = 'SALG'
AND STR_TO_DATE(Endtime, '%Y-%m-%dT%H:%i:%s+02:00')
BETWEEN STR_TO_DATE('2014-06-01T00:00:00+02:00', '%Y-%m-%dT%H:%i:%s+02:00')
AND STR_TO_DATE('2014-06-30T00:00:00+02:00', '%Y-%m-%dT%H:%i:%s+02:00')
Thanks in advance.
This is probably best-addressed using a stored function to parse and convert the timestamps from the stored format into MySQL's native format, using the built-in date time math functions to do the time zone conversions.
The function below will correctly handle two formats, YYYY-MM-DDTHH:MM:SSZ and YYYY-MM-DDTHH:MM:SS+/-HH:MM as well as correctly formed MySQL datetime literals, which will be passed through unmodified.
DELIMITER $$
DROP FUNCTION IF EXISTS `from_iso8601_subset` $$
CREATE FUNCTION `from_iso8601_subset`(in_ts TINYTEXT) RETURNS DATETIME
DETERMINISTIC
NO SQL
BEGIN
-- this function takes an input timestamp value in a suppported subset of iso8601 values, and
-- and converts it to the equivalent MySQL datetime value, expressed in the current session's
-- time zone. Since this is also the timezone that columns in the TIMESTAMP data type expect,
-- this causes the input value to be stored correctly in the native TIMESTAMP format, which is.
-- UTC under the hood.
-- if you are taking the value here and stuffing it into a DATETIME column, you need to have your
-- session ##time_zone set to the same zone in which that column should be stored, or use
-- CONVERT(from_iso('input value'),'UTC','Your Desired Time Zone');
-- 2014-02-01T23:59:59Z --
IF (in_ts REGEXP '^[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}[T ][[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2}(Z|[+-][[:digit:]]{2}:[[:digit:]]{2})$') THEN
SET in_ts = REPLACE(REPLACE(in_ts, 'T', ' '), 'Z', '+00:00');
RETURN CONVERT_TZ(SUBSTRING(in_ts FROM 1 FOR 19), SUBSTRING(in_ts FROM 20 FOR 24), ##time_zone);
-- unexpected format -- let MySQL's built-in functions do the best they can; this will throw warnings
-- if the input is not a yyyy-mm-dd hh:mm:ss datetime literal; alternately this could return NULL.
ELSE
RETURN CAST(in_ts AS DATETIME);
END IF;
END $$
DELIMITER ;
Example output:
mysql> SET ##time_zone = 'America/New_York';
Query OK, 0 rows affected (0.08 sec)
mysql> SELECT from_iso8601_subset('2014-06-01T00:00:00+02:00');
+--------------------------------------------------+
| from_iso8601_subset('2014-06-01T00:00:00+02:00') |
+--------------------------------------------------+
| 2014-05-31 18:00:00 |
+--------------------------------------------------+
1 row in set (0.08 sec)
mysql> set ##time_zone = 'UTC';
Query OK, 0 rows affected (0.08 sec)
mysql> SELECT from_iso8601_subset('2014-06-01T00:00:00+02:00');
+--------------------------------------------------+
| from_iso8601_subset('2014-06-01T00:00:00+02:00') |
+--------------------------------------------------+
| 2014-05-31 22:00:00 |
+--------------------------------------------------+
1 row in set (0.08 sec)
We assume that if the input data matches one of the patterns, then the contents of the value passed in are also going to be sane; if you give nonsense input values, you'll get some nonsense output, such as if you are using a time zone of '+99:00' but it won't fail. This function does not have any SQL injection vulnerabilities.
The code could be further-optimized, but as written, this function is efficient enough that it can evaluate several thousand expressions per second on a moderately-powered machine.
Use unix_timestamp() instead:
SELECT something, COUNT() as antal FROM ivocall_calls
WHERE Agentname LIKE 'Vinh Nguyen'
AND Status1 = 'SALG'
AND unix_timestamp(Endtime) BETWEEN
unix_timestamp('2014-06-01T00:00:00+02:00' and unix_timestamp('2014-06-30T00:00:00+02:00');
Related
SELECT STR_TO_DATE('07:15:00','%H:%i:%s') as time
SELECT STR_TO_DATE('07:15:00','%T') as time
Both results in NULL. But why? I don't think the format is incorrect here, but why is my time nor parsed?
+------+
| time |
+------+
| NULL |
+------+
1 row in set, 1 warning (0.01 sec)
Moreover, I only care for the hours and minutes. But this also fails:
SELECT STR_TO_DATE('07:15:00','%H:%i') as time
My final goal is to create a view, selecting strings from another table and converting them to TIME columns:
CREATE VIEW
myview AS SELECT
SELECT STR_TO_DATE('07:15:00','%H:%i') as time
FROM `othertable`
I suppose you're using version 5.7.
Look at SELECT ##GLOBAL.sql_mode if NO_ZERO_DATE value returns within the string. [ Btw, NO_ZERO_IN_DATE and NO_ZERO_DATE parameters are deprecated ]
If you're using Database at NO_ZERO_DATE, then SELECT STR_TO_DATE('07:15:00','%H:%i:%s') or SELECT STR_TO_DATE('07:15:00','%T') returns null.
Try to disable that mode by SET GLOBAL sql_mode = 'NO_ENGINE_SUBSTITUTION'; if you have privilege, or you can edit mysql.cnf file and restart mysql.
Cast the time strings to time:
SELECT cast('07:15:00' as time) as time
If you cannot disable NO_ZERO_DATE, then here is a workaround you may use which still goes through STR_TO_DATE to generate time values. You may concatenate to the time a random date, and then call TIME() to extract only the time portion, e.g.
SELECT TIME(STR_TO_DATE(CONCAT('2019-01-01 ', '07:15:00'), '%Y-%m-%d %H:%i:%s'))
-- ^^ random date ^^ your time literal
SELECT DATE_FORMAT('2019-11-05','%Y%m%d') as time
try this function
I want to convert a timestamp in MySQL to a date.
I would like to format the user.registration field into the text file as a yyyy-mm-dd.
Here is my SQL:
$sql = requestSQL("SELECT user.email,
info.name,
FROM_UNIXTIME(user.registration),
info.news
FROM user, info
WHERE user.id = info.id ", "export members");
I also tried the date conversion with:
DATE_FORMAT(user.registration, '%d/%m/%Y')
DATE(user.registration)
I echo the result before to write the text file and I get :
email1;name1;DATE_FORMAT(user.registration, '%d/%m/%Y');news1
email2;name2;news2
How can I convert that field to date?
DATE_FORMAT(FROM_UNIXTIME(`user.registration`), '%e %b %Y') AS 'date_formatted'
To just get a date you can cast it
cast(user.registration as date)
and to get a specific format use date_format
date_format(registration, '%Y-%m-%d')
SQLFiddle demo
Convert timestamp to date in MYSQL
Make the table with an integer timestamp:
mysql> create table foo(id INT, mytimestamp INT(11));
Query OK, 0 rows affected (0.02 sec)
Insert some values
mysql> insert into foo values(1, 1381262848);
Query OK, 1 row affected (0.01 sec)
Take a look
mysql> select * from foo;
+------+-------------+
| id | mytimestamp |
+------+-------------+
| 1 | 1381262848 |
+------+-------------+
1 row in set (0.00 sec)
Convert the number to a timestamp:
mysql> select id, from_unixtime(mytimestamp) from foo;
+------+----------------------------+
| id | from_unixtime(mytimestamp) |
+------+----------------------------+
| 1 | 2013-10-08 16:07:28 |
+------+----------------------------+
1 row in set (0.00 sec)
Convert it into a readable format:
mysql> select id, from_unixtime(mytimestamp, '%Y %D %M %H:%i:%s') from foo;
+------+-------------------------------------------------+
| id | from_unixtime(mytimestamp, '%Y %D %M %H:%i:%s') |
+------+-------------------------------------------------+
| 1 | 2013 8th October 04:07:28 |
+------+-------------------------------------------------+
1 row in set (0.00 sec)
If the registration field is indeed of type TIMESTAMP you should be able to just do:
$sql = "SELECT user.email,
info.name,
DATE(user.registration),
info.news
FROM user,
info
WHERE user.id = info.id ";
and the registration should be showing as yyyy-mm-dd
FROM_UNIXTIME(unix_timestamp, [format]) is all you need
FROM_UNIXTIME(user.registration, '%Y-%m-%d') AS 'date_formatted'
FROM_UNIXTIME gets a number value and transforms it to a DATE object,
or if given a format string, it returns it as a string.
The older solution was to get the initial date object and format it with a second function DATE_FORMAT... but this is no longer necessary
Just use mysql's DATE function:
mysql> select DATE(mytimestamp) from foo;
You should convert timestamp to date.
select FROM_UNIXTIME(user.registration, '%Y-%m-%d %H:%i:%s') AS 'date_formatted'
FROM_UNIXTIME
If you are getting the query in your output you need to show us the code that actually echos the result. Can you post the code that calls requeteSQL?
For example, if you have used single quotes in php, it will print the variable name, not the value
echo 'foo is $foo'; // foo is $foo
This sounds exactly like your problem and I am positive this is the cause.
Also, try removing the # symbol to see if that helps by giving you more infromation.
so that
$SQL_result = #mysql_query($SQL_requete); // run the query
becomes
$SQL_result = mysql_query($SQL_requete); // run the query
This will stop any error suppression if the query is throwing an error.
I did it with the 'date' function as described in here :
(SELECT count(*) as the-counts,(date(timestamp)) as the-timestamps FROM `user_data` WHERE 1 group BY the-timestamps)
If you want to change the datatype of the column, you can simply convert first from TIMESTAMP to INT:
ALTER TABLE table_name MODIFY column_name INT;
And then INT to DATE:
ALTER TABLE table_name MODIFY column_name DATE;
But, if you didn't mean to change a column, but wanted SELECT only, then you can use date() function:
SELECT date(your_timestamp_column) FROM your_table;
I want to convert a record 1580707260
Usually, I am using online timestamp converter
Want to showcase it in the query result
Please try this
DATE_FORMAT(FROM_UNIXTIME(field name from table), '%e %b %Y')
AS 'display name for result'
Try:
SELECT strftime("%Y-%d-%m", col_name, 'unixepoch') AS col_name
It will format timestamp in milliseconds to yyyy-mm-dd string.
You can use this command FROM_UNIXTIME(unix_timestamp, [format]); but sometimes timestamp is in a long value that you have to remove 3 last values to 0.
for instance you use this command from_unixtime(e.EVENT_TIME/1000);
this way solve my problem.
I need to convert some TIMESTAMP fields to INT in our MySQL (InnoDB) DB. I realize that converting a TIMESTAMP to INT is unusual, but we still need to do it :)
It seems straight-forward enough to do, but there are some timezone and daylight saving errors.
I have a script that generates my SQL code per column. For example, it generates:
ALTER TABLE alarmLog ADD COLUMN started_tmp INT UNSIGNED;
UPDATE alarmLog SET started_tmp = UNIX_TIMESTAMP(started);
ALTER TABLE alarmLog DROP started;
alter TABLE alarmLog CHANGE started_tmp started INT UNSIGNED NULL DEFAULT 0;
If I compare the before and after data using select FROM_UNIXTIME(1291788036);, the result looks good.
The idea is then to change all the client-side software to convert to UTC and use that INT when storing it. When retrieving, that INT is converted to the current time zone.
But then the docs warn me about this scenario (daylight savings in CET):
mysql> SELECT UNIX_TIMESTAMP('2005-03-27 02:00:00');
+---------------------------------------+
| UNIX_TIMESTAMP('2005-03-27 02:00:00') |
+---------------------------------------+
| 1111885200 |
+---------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT UNIX_TIMESTAMP('2005-03-27 03:00:00');
+---------------------------------------+
| UNIX_TIMESTAMP('2005-03-27 03:00:00') |
+---------------------------------------+
| 1111885200 |
+---------------------------------------+
1 row in set (0.00 sec)
How do API and OS's normally deal with daylight savings? I know my PC has its clock in UTC and in summer time, the OS adds two hours to it, and in winter time one. I assume it uses the UTC time to determine whether it's DST or not.
So, how do I deal with this? Is the only solution to add a field to the database to specify DST offset?
You don't need to store the time in INT's. MySQL's TIMESTAMP type does that anyway (it uses standard Unix timestamps to store the time) and they are always in UTC timezone.
You only need to set the session timezone and all TIMESTAMP columns will be converted from/to your zone when you update/select them.
You can set the zone at connect/initialization time once:
SET time_zone = '+10:00';
And then you can select/update the time in your zone directly
SELECT timestamp_column FROM table ...
I'm not very familiar with datetime libs but I guess they use the timezone you provided and the time in question to determine timezone and daylight savings offsets.
In the example you provided I think one of the values is actually invalid, because the clock is supposed to jump from 01:59:59 to 03:00:00 and 02:00:00 never actually happened. The UNIX_TIMESTAMP function probably returns the nearest second in that case.
I want to convert a timestamp in MySQL to a date.
I would like to format the user.registration field into the text file as a yyyy-mm-dd.
Here is my SQL:
$sql = requestSQL("SELECT user.email,
info.name,
FROM_UNIXTIME(user.registration),
info.news
FROM user, info
WHERE user.id = info.id ", "export members");
I also tried the date conversion with:
DATE_FORMAT(user.registration, '%d/%m/%Y')
DATE(user.registration)
I echo the result before to write the text file and I get :
email1;name1;DATE_FORMAT(user.registration, '%d/%m/%Y');news1
email2;name2;news2
How can I convert that field to date?
DATE_FORMAT(FROM_UNIXTIME(`user.registration`), '%e %b %Y') AS 'date_formatted'
To just get a date you can cast it
cast(user.registration as date)
and to get a specific format use date_format
date_format(registration, '%Y-%m-%d')
SQLFiddle demo
Convert timestamp to date in MYSQL
Make the table with an integer timestamp:
mysql> create table foo(id INT, mytimestamp INT(11));
Query OK, 0 rows affected (0.02 sec)
Insert some values
mysql> insert into foo values(1, 1381262848);
Query OK, 1 row affected (0.01 sec)
Take a look
mysql> select * from foo;
+------+-------------+
| id | mytimestamp |
+------+-------------+
| 1 | 1381262848 |
+------+-------------+
1 row in set (0.00 sec)
Convert the number to a timestamp:
mysql> select id, from_unixtime(mytimestamp) from foo;
+------+----------------------------+
| id | from_unixtime(mytimestamp) |
+------+----------------------------+
| 1 | 2013-10-08 16:07:28 |
+------+----------------------------+
1 row in set (0.00 sec)
Convert it into a readable format:
mysql> select id, from_unixtime(mytimestamp, '%Y %D %M %H:%i:%s') from foo;
+------+-------------------------------------------------+
| id | from_unixtime(mytimestamp, '%Y %D %M %H:%i:%s') |
+------+-------------------------------------------------+
| 1 | 2013 8th October 04:07:28 |
+------+-------------------------------------------------+
1 row in set (0.00 sec)
If the registration field is indeed of type TIMESTAMP you should be able to just do:
$sql = "SELECT user.email,
info.name,
DATE(user.registration),
info.news
FROM user,
info
WHERE user.id = info.id ";
and the registration should be showing as yyyy-mm-dd
FROM_UNIXTIME(unix_timestamp, [format]) is all you need
FROM_UNIXTIME(user.registration, '%Y-%m-%d') AS 'date_formatted'
FROM_UNIXTIME gets a number value and transforms it to a DATE object,
or if given a format string, it returns it as a string.
The older solution was to get the initial date object and format it with a second function DATE_FORMAT... but this is no longer necessary
Just use mysql's DATE function:
mysql> select DATE(mytimestamp) from foo;
You should convert timestamp to date.
select FROM_UNIXTIME(user.registration, '%Y-%m-%d %H:%i:%s') AS 'date_formatted'
FROM_UNIXTIME
If you are getting the query in your output you need to show us the code that actually echos the result. Can you post the code that calls requeteSQL?
For example, if you have used single quotes in php, it will print the variable name, not the value
echo 'foo is $foo'; // foo is $foo
This sounds exactly like your problem and I am positive this is the cause.
Also, try removing the # symbol to see if that helps by giving you more infromation.
so that
$SQL_result = #mysql_query($SQL_requete); // run the query
becomes
$SQL_result = mysql_query($SQL_requete); // run the query
This will stop any error suppression if the query is throwing an error.
I did it with the 'date' function as described in here :
(SELECT count(*) as the-counts,(date(timestamp)) as the-timestamps FROM `user_data` WHERE 1 group BY the-timestamps)
If you want to change the datatype of the column, you can simply convert first from TIMESTAMP to INT:
ALTER TABLE table_name MODIFY column_name INT;
And then INT to DATE:
ALTER TABLE table_name MODIFY column_name DATE;
But, if you didn't mean to change a column, but wanted SELECT only, then you can use date() function:
SELECT date(your_timestamp_column) FROM your_table;
I want to convert a record 1580707260
Usually, I am using online timestamp converter
Want to showcase it in the query result
Please try this
DATE_FORMAT(FROM_UNIXTIME(field name from table), '%e %b %Y')
AS 'display name for result'
Try:
SELECT strftime("%Y-%d-%m", col_name, 'unixepoch') AS col_name
It will format timestamp in milliseconds to yyyy-mm-dd string.
You can use this command FROM_UNIXTIME(unix_timestamp, [format]); but sometimes timestamp is in a long value that you have to remove 3 last values to 0.
for instance you use this command from_unixtime(e.EVENT_TIME/1000);
this way solve my problem.
I need to update 2 datetime columns, and I need them to be exactly the same, using mysql version 4.1.20. I'm using this query:
mysql> update table set last_update=now(), last_monitor=now() where id=1;
It is safe or there is a chance that the columns are update with different time, because of the 2 visible calls to now()?
I don't think that it can be update with different values (I think internally mysql calls now() just once per row or something similar), but I'm not an expert, what do you think?
Update:
Second question was extracted here.
Found a solution:
mysql> UPDATE table SET last_update=now(), last_monitor=last_update WHERE id=1;
I found this in MySQL Docs and after a few tests it works:
the following statement sets col2 to the current (updated) col1 value, not the original col1 value. The result is that col1 and col2
have the same value. This behavior differs from standard SQL.
UPDATE t1 SET col1 = col1 + 1, col2 = col1;
Mysql isn't very clever. When you want to use the same timestamp in multiple update or insert queries, you need to declare a variable.
When you use the now() function, the system will call the current timestamp every time you call it in another query.
MySQL evaluates now() once per statement when the statement commences execution. So it is safe to have multiple visible now() calls per statement.
select now(); select now(), sleep(10), now(); select now();
+---------------------+
| now() |
+---------------------+
| 2018-11-05 16:54:00 |
+---------------------+
1 row in set (0.00 sec)
+---------------------+-----------+---------------------+
| now() | sleep(10) | now() |
+---------------------+-----------+---------------------+
| 2018-11-05 16:54:00 | 0 | 2018-11-05 16:54:00 |
+---------------------+-----------+---------------------+
1 row in set (10.00 sec)
+---------------------+
| now() |
+---------------------+
| 2018-11-05 16:54:10 |
+---------------------+
1 row in set (0.00 sec)
You can store the value of a now() in a variable before running the update query and then use that variable to update both the fields last_update and last_monitor.
This will ensure the now() is executed only once and same value is updated on both columns you need.
You can put the following code on the default value of the timestamp column:
CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, so on update the two columns take the same value.
If you really need to be sure that now() has the same value you can run two queries (that will answer to your second question too, in that case you are asking to update last_monitor = to last_update but last_update hasn't been updated yet)
you could do something like:
mysql> update table set last_update=now() where id=1;
mysql> update table set last_monitor = last_update where id=1;
anyway I think that mysql is clever enough to ask for now() only once per query.
There are 2 ways to this;
First, I would advice you declare now() as a variable before injecting it into the sql statement. Lets say;
var x = now();
mysql> UPDATE table SET last_update=$x, last_monitor=$x WHERE id=1;
Logically if you want a different input for last_monitor then you will add another variable like;
var y = time();
mysql> UPDATE table SET last_update=$x, last_monitor=$y WHERE id=1;
This way you can use the variables as many times as you can, not only in mysql statements but also in the server-side scripting-language(like PHP) you are using in your project.
Remember these same variables can be inserted as inputs in a form on the front-end of the application. That makes the project dynamic and not static.
Secondly if now() indicates time of update then using mysql you can decalre the property of the row as a timestamp. Every time a row is inserted or updated time is updated too.