Time Format Problem: Comparison is not working - mysql

MYSQL
Format of time in two tables:-
Jan 1 2018 10:42:06
table1.time greater than table2.time
Comparison is not working in these tables
table1.time > table2.time
No data is coming

You seem to be looking for :
STR_TO_DATE(a.time, '%b %d %Y %H:%i:%d')
The mysql STR_TO_DATE function lets you translate strings to date.
Once strings are converted to date, you can compare them using the < operator or the-like

Related

varchar date time comparison issue

I have a legacy table which has a varchar column represent date, format is MM/DD/YYYY (e.g. 01/08/2015). It is not convenient to perform data range selection since it is a varchar (when I use < or > kinds comparison, it goes to varchar/string comparison, which have different results from date comparision).
For example, I want to select only rows which dates are between 01/08/2015 and 01/10/2015. Any smart solution is appreciated, and I cannot change the data type of varchar to date in my existing table.
I am using MySQL Workbench/MySQL.
Varchar dates are evil and they are not real date, the best solution is to use mysql's native date data types.
Since you can't change the datatype you may use str_to_date() function and here how it works
mysql> select str_to_date('01/08/2015','%d/%m/%Y') as d ;
+------------+
| d |
+------------+
| 2015-08-01 |
+------------+
So the query for select would be
select * from table_name
where
str_to_date(date_column,'%d/%m/%Y')
between
str_to_date('01/08/2015','%d/%m/%Y')
and
str_to_date('01/10/2015','%d/%m/%Y')
There are many answers which addresses many different way of converting the string to date.
You may choose whichever is perfect for your need
SELECT * FROM `your_table` WHERE DATE_FORMAT(my_column_with_the_string_date, "%Y-%m-%d") <= '2011-09-30'
DATE_FORMAT can be used to convert your date string to any format: I will use the NOW() function instead of string to list different
formats that are supported
DATE_FORMAT(NOW(),'%b %d %Y %h:%i %p')
DATE_FORMAT(NOW(),'%m-%d-%Y')
DATE_FORMAT(NOW(),'%d %b %y')
DATE_FORMAT(NOW(),'%d %b %Y %T:%f')
The output of the above is:
Nov 04 2014 11:45 PM
11-04-2014
04 Nov 14
04 Nov 2014 11:45:34:243
You can modify your query accordingly
You can cast your dates as strings using STR_TO_DATE:
STR_TO_DATE(yourdatefield, '%m/%d/%Y')
SELECT STR_TO_DATE(got_fired_at, '%m/%d/%Y') BETWEEN ? AND ? FROM firings;
(field/table names guaranteed to have been chosen randomly)
Use MySQL's STR_TO_DATE function to parse the date strings to date objects then do the comparison.

MYSQL query: select between date with local format

my mysql database tb_date (varchar 20):
16 November 2014
06 December 2014
01 April 2014
12 April 2015
I want select between 01 January 2014 until 31 December 2014, how the query is with date conversion?
thanks..
This is an anti-pattern, storing date values in VARCHAR columns, rather than using datatypes specifically designed and implemented for storing date values... DATE, DATETIME or TIMESTAMP.
To answer your question, before it gets closed, you could use the STR_TO_DATE function to convert the strings into DATE datatype, and then do the comparison. MySQL won't be able to make use of an index range scan operation, it will need to evaluate that function on every flipping row in the table.
As an example:
SELECT t.mycol
FROM mytable t
WHERE STR_TO_DATE(t.mycol,'%d %M %Y') >= '2014-01-01'
AND STR_TO_DATE(t.mycol,'%d %M %Y') < '2015-01-01'
We'll need to check the MySQL Reference Manual to verify that '%M' is the right format specifier for the full month name...
http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-format
Yes, it looks like I guessed right. M is the month name.
As I already commented, you should store your date as Timestamp or Data format then you could simply compare.
However, there is still a solution.. You can convert the varchar to a date directly in your query :
select * from yourTable
where (str_to_date(tb_date, '%d %M %Y') between '2014-01-01' and '2014-12-31');
But please don't use this hack and change your date format...
Edit : If you are really willing to use varchar to store your date, change it to varchar(17) which is the max character possible using your string format.

Compare two unix time stamps to see if they are on the same date in MySql

I have read various questions here on Stackoverflow about the use of FROM_UNIXTIME but none directly deal with what I am trying to do. I have one timestamp in a variable coming from php (that has been reformatted - e.g. 25 March 2014) to a function which uses a database query to determine if there are other entries in the database that have the same date (not time). I've run across various methods for formatting and comparing timestamp entries using MySql and ended up with the following but I understand that it isn't very efficient. Does anyone know of a better way to accomplish this?
FROM_UNIXTIME(sd.timestart, "%e %M %Y") = ?'
where the variable in my array for comparison is the date format listed above. This accomplishes what I want but, again, I don't think it is the most efficient way to get this done. Any advice and/or ideas will be much appreciated.
*EDIT*
My timestamp is stored as an integer so I'm trying to use:
$thissessiondate = strtotime($date->timestart, strtotime('today'));
and
$tomorrowdate = strtotime($date->timestart, strtotime('tomorrow'));
to do trim to midnight but get an error (strtotime() expects parameter 2 to be long) and when I move 'today' to the first argument position, I get a conversion to 11 pm instead of 0:00...? I'm making some progress but my very incomplete knowledge of both PHP and MySQL are holding me back.
If you can avoid it, don't wrap columns used in predicates in expressions.
Have your predicates on bare columns to make index range scans possible. You want the datatype conversion to happen over on the literal side of the predicate, wherever possible.
The STR_TO_DATE function is the most convenient for this.
Assuming the timestart column is DATE, DATETIME or TIMESTAMP (which it really should be, if it represents a point in time.)
WHERE sd.timestart >= STR_TO_DATE( ? , "%e %M %Y")
AND sd.timestart < STR_TO_DATE( ? , "%e %M %Y") + INTERVAL 1 DAY
Effectively, what that's doing is taking the string passed in as the first argument to the STR_TO_DATE function, MySQL is going to convert that string to a DATETIME, based on the format specified as the second argument. And that effectively becomes a literal that MySQL can use to compare to the stored values in the column.
If there's an appropriate index available, MySQL will consider an index range scan operation to satisfy that predicate.
You'd need to pass in the same value twice, but that's not really a problem.
On the second line, we're just adding a day to the same value. So what MySQL is seeing is this:
WHERE sd.timestart >= STR_TO_DATE( '25 March 2014' , "%e %M %Y")
AND sd.timestart < STR_TO_DATE( '25 March 2014' , "%e %M %Y") + INTERVAL 1 DAY
In terms of performance, that's equivalent to:
WHERE sd.timestart >= '2014-03-15 00:00:00'
AND sd.timestart < '2014-03-16 00:00:00'
If you do it the other way around, and wrap timestart in a function, that's going to require MySQL to evaluate the function on every single row (or at least, on every row that isn't filtered out by another predicate first.)
IMPORANT NOTE
Be aware that MySQL interprets datetime values as being in the timezone of the MySQL connection, which defaults to the timezone setting of the MySQL server. MySQL is going to interpret datetime literals in the current setting of the timezone. For example, if MySQL timezone is set to +00:00, then datetime literals will be interpreted as UTC.
I assumed the format string matches the data being passed in, I don't use %e or %m. The %Y is a four digit year. (The list of format elements is in the MySQL documentation, under the DATE_FORMAT function.
Reference: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_str-to-date
If your timestart column is INTEGER or other numeric datatype, representing a number of seconds or some other unit of time since the beginning of an era, you can use the same approach for performance benefits.
In the predicate, reference bare columns from the table, and do any conversions required on the literal side.
If you aren't using MySQL functions to do the conversion to "seconds since Jan 1, 1970 UTC" when rows are inserted (which is really what the TIMESTAMP datatype is doing internally), then I wouldn't recommend using MySQL functions to do the conversion in the query either.
If you're doing the conversion from date and time to an integer type "timestamp" in PHP, then I'd do the inverse conversion in PHP as well, and do the trimming to midnight and the adding of a day in PHP.
In that case, your MySQL query would be of the simple form:
WHERE sd.timestart >= ?
AND sd.timestart < ?
Where you would pass in the appropriate integer values, to compare to the INTEGER timestamp column.
Note that MySQL does provide a function for converting to "seconds since Jan 1 1970 UTC", so if timestart is seconds since Jan 1 1970 UTC, then something like this is valid:
WHERE sd.timestart >= UNIX_TIMESTAMP(STR_TO_DATE( '25 March 2014' , "%e %M %Y"))
AND sd.timestart < UNIX_TIMESTAMP(STR_TO_DATE( '25 March 2014' , "%e %M %Y") + INTERVAL 1 DAY)
BUT... again, be aware of timezone conversion issues; if the MySQL database has a different timezone setting than the web server. If you are going to store "integer", then I wouldn't muck that up with the conversion that MySQL does, which may not be exactly the same as the conversion functions the web server does.
If you store your date as an int timestamp, you can do this
round(sd.timestart/86400)=round(UNIX_TIMESTAMP(NOW())/86400)
This will get everything in your database that is from the same day.
For example:
SELECT id FROM uploads WHERE (approved=0 OR approved is NULL) AND round(uploads.date/86400)<=round(UNIX_TIMESTAMP(NOW())/86400) order by uploads.date DESC LIMIT 20
Will display all the uploads for today and the days before, without showing the future uploads. 86400 is the number of seconds in one day.

Date Comparison Not Working (Dates are strings) - MySQL

I have a MySQL query that reads:
select sum(AmtPd) as HCSA from HC062017 where CostCenter = '8718' and ServiceDate > '08/31/2013'
Have been using it for several months with no problem. Today I encountered a problem with it not working. ServiceDate is a var(10) containing a date pulled from a report. The format is mm-dd-yyyy. What appears to be happening is if the ServiceDate is in 2013 (which some of them still are), then the statement works perfectly. However, when the ServiceDate is in 2014, no records are selected. If I leave off the ServiceDate parameter, I get the desired results (since all records this time are past the 08/31/2013 date). Maybe I lucked out with the months '09', '10', etc, falling after '08'. I've tried using str_to_date with no luck
select sum(AmtPd) as HCSA from HC062017 where CostCenter = '8718' and str_to_date(ServiceDate, '%m, %d, %Y') > '08-31-2013';.
Any suggestions on how to handle this?
You need to convert both to common format:
str_to_date(ServiceDate, '%m-%d-%Y') > str_to_date('08-31-2013', '%m-%d-%Y')
Comparing strings like you did is a bad idea. Strings are compared in alphabetic order, so '08-31-2013' is "smaller" than '09-30-2010' because 9 is compared to 8 before everything else. You can compare dates in ISO format YYYY-MM-DD.
STR_TO_DATE produces a date in a format of YYYY-MM-DD. So your date that you are comparing to must be in the same format:
str_to_date(ServiceDate, '%m, %d, %Y') > '2013-08-31';

mysql query - format date on output?

In my table, dates are stored like this: 2011-03-03T13:30:00
I'm trying to output dates like this: March 3, 2011 1:30 PM
I'd much rather work it into the query rather than use php to format it, but I'm having some difficulty doing that. Trying various iterations of DATE_FORMAT, but it's not giving me what I want, maybe because of the way it's being stored?
You basically have two different operations you may need to perform when handling dates: date to string and vice versa. The functions you can use are DATE_FORMAT() and STR_TO_DATE(). Full reference can be found in the manual.
Usage example:
SELECT
DATE_FORMAT(CURRENT_TIMESTAMP, '%d/%m/%Y %H:%i:%s'),
STR_TO_DATE('31/12/2001 23:55:00', '%d/%m/%Y %H:%i:%s')
If your dates are not real dates but strings, you'll need to convert twice: from string to date and again from date to string:
SELECT
STR_TO_DATE('2011-03-03T13:30:00', '%Y-%m-%dT%H:%i:%s'),
DATE_FORMAT(STR_TO_DATE('2011-03-03T13:30:00', '%Y-%m-%dT%H:%i:%s'), '%M %e, %Y %l:%i %p')
Use DATE_FORMAT:
DATE_FORMAT(date, "%M %e, %Y %h:%i %p")
The MySQL date storage format is actually YYYY-MM-DD, but using the str_to_date() and date_format() functions you can accept and generate any date format required.
select DATE_FORMAT(DateTable.MyDate,'%d %b %y')
from DateTable
would return
04 Nov 08
You should really use a DATETIME field for such things (and clean the input on the way in) rather than having to sort this out at the point of output.
Irrespective, you can simply use the DATE_FORMAT function to re-format your field into the format you require, although this might produce some un-expected results on a VARCHAR or CHAR field. (If so, you'll have to use STR_TO_DATE or failing that some various string functions to extract the date bits you require.)