MySQL compare two dateTime fields specifying precision - mysql

With MySQL what is the method of doing a datetime comparison with precision? Like I want to compare two dateTime fields to see if their equal ignorming minutes and seconds, saying:
[compare with precision down to hours]
Is 2011-05-05 14:32:49 equal to 2011-05-05 14:46:22 ?
=> TRUE
I'm not sure there is anything, and google isn't helping (precision just brings up a bunch of results about milli and micro second junk). Maybe this type of compare is dervied from another function and there isn't a date compare w/ precision in MySQL?
Thanks!

You could try:
DATE(dt1) = DATE(dt2) AND HOUR(dt1) = HOUR(dt2)
Take a look at MySql Date-Time functions

Related

how to make sure milliseconds of the date are stored in database?

I am using grails 2.2 with mysql.
I get the time as unix timestamp.
def raceStartTime = params.raceStart //milliseconds epoch time
I then convert the time to date as shown below
Date startDateTime = new Date(raceStartTime.toLong())
and persist it in database
Race r = new Race()
r.start = startDateTime
r.save()
It turns out when saving the date in mysql database the precision is lost i.e the exact value of milliseconds is not recorded. It seems to record time as hh mm ss. I need to preserve the fractional part of the second. Is there a way to make it so that when the timestamp converted date is saved, the fractional second part is not lost? Thanks for help!
UPDATE:
I used the following mapping block to change the datatype.
static mapping = {
debug type: 'text'
raceStart sqlType: 'DATETIME(6)'
raceEnd sqlType: 'DATETIME(6)'
}
After this i run dbm-gorm-diff but it doesnt generate change log. i appreciate any guide.thanks!
This has to do with how you defined your start column in MySQL.
From the documentation:
MySQL has fractional seconds support for TIME, DATETIME, and TIMESTAMP values, with up to microseconds (6 digits) precision.
To define a column that includes a fractional seconds part, use the syntax type_name(fsp), where type_name is TIME, DATETIME, or TIMESTAMP, and fsp is the fractional seconds precision. For example:
CREATE TABLE t1 (t TIME(3), dt DATETIME(6));
The fsp value, if given, must be in the range 0 to 6. A value of 0 signifies that there is no fractional part. If omitted, the default precision is 0. (This differs from the standard SQL default of 6, for compatibility with previous MySQL versions.)
Hence, ensure that you create your table with:
CREATE TABLE race (... start DATETIME(6) ...)
edit: I am no grails expert, but I think you can configure this mapping by defining the following on your Race class:
static mapping = {
start sqlType: "DATETIME", precision: 6
}

MySQL 5.6 calculation with datatype time within function returns wrong value - but outside is ok

I use mySQL 5.6 on Windows 7 Pro x64 and have the following problem.
SELECT fee(100, '12:00:00');
returns 500,000 which is obviously not correct.
But
SELECT 100 * '12:00:00'/24;
returns the correct result which is 50.
DROP FUNCTION IF EXISTS fee;
DELIMITER //
CREATE FUNCTION fee(price INT, duration TIME)
RETURNS DECIMAL(15,2)
BEGIN
RETURN price * duration/24;
END //
DELIMITER ;
Have you ever encountered this problem? What is the reason behind it?
Thanks for any hints for solving this.
My guess is that in 100 * '12:00:00'/24 expression '12:00:00' is evaluated as string, not as a time expression, and in '12:00:00'/24 operation the string is converted to a number, so it is executed as 12/24, which gives the expected result.
However, when the fee() function is called, '12:00:00' is passed to a parameter with TIME data type. In the duration/24 operation duration is converted to integer first, then the division is executed. However, select cast(cast('12:00:00' as time) as integer) conversion yields 120000, not 12. 120000/24*100=500000 - this is the output received from the original function. According to mysql documentation on TIME:
Be careful about assigning abbreviated values to a TIME column. MySQL
interprets abbreviated TIME values with colons as time of the day.
That is, '11:12' means '11:12:00', not '00:11:12'. MySQL interprets
abbreviated values without colons using the assumption that the two
rightmost digits represent seconds (that is, as elapsed time rather
than as time of day). For example, you might think of '1112' and 1112
as meaning '11:12:00' (12 minutes after 11 o'clock), but MySQL
interprets them as '00:11:12' (11 minutes, 12 seconds). Similarly,
'12' and 12 are interpreted as '00:00:12'.
Although the documentation describes integer to time conversion, it is safe to assume that time to integer conversion works the same way. I would use price * time_to_sec(duration)/86400 to get the right result.
Thank you all for your helps and comments.
#Shadow, #B98 – you are right. The problem has to do with converting '12:00:00' to its corresponding numeric value.
I searched a lot about how MySQL performs converting time to number in general, however I didn't find anything.
So I started a little bit experimenting on it and this is what I found out about it yet:
The default datatype in MySQL is VARCHAR, so every value/"variable" which has no explicit datatype its datatype is VARCHAR(length of value/variable) as you've correctly guessed, Shadow.
Converting VARCHAR to a numeric datatype works generally like this: take all digits from the left of the string up to the point you find a character except 0-9. If immediately after the digits there is a dot “.”, take the dot as the decimal point and continue searching for decimal digits till the string ends or you find a character except 0-9.
So in short: take from the left of the string what matches the pattern [0-9][.[0-9]] and throw the rest of it away – as you mentioned it, B98. Examples: '12:30:59' = 12; '12whatever30whatever59' = 12; '12.30.59' = 12.30; '12.30whatever' = 12.30
However, converting TIME to a numeric datatype works a little bit different: First remove the colons then convert it to an integer. Exempels: '12:00:00' = 120000; '12:30:59' = 123059
Converting DATETIME to a numeric datatype works the same way as converting TIME to numeric, except here get the dashes in the date part, the space between date and time and the colons in the time part removed and then gets the whole string converted to an integer. Exempels: '2015-12-24 12:59:59' = '20151224125959'
Below you find a query which shows this behavior of MySQL.
DROP VIEW IF EXISTS datetimeTypes;
CREATE VIEW datetimeTypes AS
SELECT
'12:59:00.50' AS timeImplicit,
CAST('12:59:00.50' AS TIME) AS timeExplicit,
'12:59:00.50' / 1 AS timeImplicitDiv,
CAST('12:59:00.50' AS TIME) / 1 AS timeExplicitDiv,
'2015-12-24 12:59:59' AS datetimeImplicit,
CAST('2015-12-24 12:59:59' AS DATETIME) AS datetimeExplicit,
'2015-12-24 12:59:59' / 1 AS datetimeImplicitDiv,
CAST('2015-12-24 12:59:59' AS DATETIME)/1 AS datetimeExplicitDiv;
SHOW FIELDS FROM datetimeTypes;
SELECT * FROM datetimeTypes;

phpMyAdmin - Storing time in mm:ss:ms format

In phpMyAdmin I'm wanting to record a lap time for a race. The format needs to be in mm:ss:ms format.
How can I store this value in the database? Is there a data type that will allow it? I've tried time, timestamp and datetime but none of them store the value with milliseconds.
If this is not possible can I store it as an int or a varchar and then convert it in a select query to mm:ss:ms format for output display purposes?
Example Output:
1:35.547
So that's:
1 minute, 35 secs, 547 milliseconds
Any ideas?
MySQL 5.6.4 and up expands fractional seconds support for TIME, DATETIME, and TIMESTAMPvalues, with up to microseconds (6 digits) precision.
http://dev.mysql.com/doc/refman/5.6/en/fractional-seconds.html
In earlier versions you have to implement the feature manually. The simplest option I can think of would be storing the milliseconds in a separate SMALLINT column, then:
SELECT CONCAT(
TIME_FORMAT(time_col, '%i minutes, %s seconds, '),
milliseconds_col,
' milliseconds'
) FROM ...
Alternatively, you could store your times as DECIMAL(10, 3). Unfortunately both approaches require cumbersome, manual conversions.

MySQL SEC_TO_TIME gives hh:mm:ss.000000

As said in the caption I am wondering why the SEC_TO_TIME-Function of MySQL gives me that Zeros at the end.
Refering to the docu (http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_sec-to-time) that shouldn't happen (I am using MySQL 5.0.11).
Any Idea why this Zeros appears and how to get rid of them? To much zeros for displaying miliseconds.
Sine the zeros doens't break MySQLs Date-funcions, it's more a "I don't like that"-Question rather than a real Problem (at least till now^^)
// EDIT: I just figured out that the zeros aren't coming from the SEC_TO_TIME but from the FROM_UNIXTIME()-Function. Thx to #Abhik Chakraborty to ask for the input!
// EDIT2: I used FROM_UNIXTIME(last_try, '%Y-%m-%d %H:%i:%s') to get rid of the zeros. But When I do TIME(FROM_UNIXTIME(last_try, '%Y-%m-%d %H:%i:%s')) the zeros are back. Why??
Seems like every function adds the zeros back. Using SEC_TO_TIME on a simple integer-value also gives zeros...
Here is the whole query iam using:
SELECT
SEC_TO_TIME(FLOOR(TIME_TO_SEC((TIME(FROM_UNIXTIME(`last_try`))))/1800)*1800)
FROM `last48h`
The query reads the timestamp, gets only the time, converts it to seconds, breaks the seconds into half-hours (/1800 gives 0 < x < 48) rounds down and converts back to time
SEC_TO_TIME produces a TIME data type for its result. You can format that as you wish with DATE_FORMAT.
If you actually need subsecond time resolution you'll need to move to version 5.6.4 or beyond.
When you directly SELECT any sort of TIME data type to display, you get a default TIME-to-string conversion operation. The default TIME-to-string conversion in some generations of MySQL yields a string ending in hh:mm:ss+zz00. +zz00 is a timezone indicator, and often displays as +0000. Any chance that's what you're seeing?
It doesn't make sense to try to handle a UNIX_TIMESTAMP() style number of seconds using SEC_TO_TIME(). As of mid-2014 the current unix timestamp value is above 1.39 gigaseconds. TIME data types are used for stuff like elapsed times, and have a limit of just under 839 hours (3 megaseconds, precisely 3020399 seconds), and silently truncate their values.
For example, this is a good use of SEC_TO_TIME:
SELECT SEC_TO_TIME(end_timestamp - start_timestamp) AS duration
edit
Strangely enough, this query
SELECT
SEC_TO_TIME(FLOOR(TIME_TO_SEC((TIME(FROM_UNIXTIME(UNIX_TIMESTAMP()))))/1800)*1800) AS a,
FLOOR(TIME_TO_SEC((TIME(FROM_UNIXTIME(UNIX_TIMESTAMP()))))/1800)*1800 AS b,
TIME_TO_SEC((TIME(FROM_UNIXTIME(UNIX_TIMESTAMP()))))/1800 AS c,
FROM_UNIXTIME(UNIX_TIMESTAMP()) AS d,
FROM_UNIXTIME(UNIX_TIMESTAMP() - UNIX_TIMESTAMP() % 1800) as e
doesn't show any of the 0000 stuff through the phpmyadmin instance I use.
By the way, most people who round time to the nearest interval (a half-hour in your case) prefer to use a modulo and a subtraction; it's less dependent on implicit numerical type conversion than your method.
SELECT TIME(FROM_UNIXTIME(last_try - last_try%1800))
does what the query in your question does.
I had the same problem with the 'SEC_TO_TIME' function.
I had overlooked the fact that I was storing timestamps as a VARCHAR.
I changed my datatypes from VARCHAR to BIGINT and it is formatting the output values as expected (hh:mm:ss).
Try to use TIME_FORMAT with %k specifier it should help.

MySql - Bad format for Time 'hhh:mm:ss' in column x

In MySQL, I am trying to get difference between two timestamp value and storing the result in time column. But sometimes the result comes in 'hhh:mm:ss' format. While trying to access that column in Java using Result.getTime(), it is throwing error saying 'Bad format for time in column x'.
To get better idea, store the result of following query in time column and try to access this value in Java.
SELECT SEC_TO_TIME(ABS(TIMESTAMPDIFF(SECOND,'2013-01-26 19:03:48','2013-02-15 06:59:36'))) as 'RESULT';
What should I do to get result even if it has 'hhh:mm:ss' format (without any error)?
Thanks in advance.
I assume you run query and result set contain the result
String hourMinSec=resultset.getString("RESULT");
String[]result=hourMinSec.split(":");
int hour=Integer.parseInt(result[0]);
int min=Integer.parseInt(result[1]);
int second=Integer.parseInt(result[2]);
Expressing difference between two dates as date is meaningless i think. Just to answer your question if you want to create time you can use following
Time time =new Time(hour, min, second);
But i feel its meaningless.
You can't express the difference between two dates as another date. For example if you will got 31 days difference you can't say if it is 1 month or 1 month and 1 day.
You should create your own object to storage this data.