MySQL String to Date converting with varying strings? - mysql

I need to convert dates of varying strings. They come in 3 different ways.
yyyy/mm/dd
mm/dd/yyyy
or blank (can fill in some default)
What is a good way to handle this situation for an INSERT statement?

Use STR_TO_DATE function in combination with COALESCE - something like:
set #strdate := '2014/05/10';
select COALESCE(STR_TO_DATE(#strdate,'%m/%d/%Y'),STR_TO_DATE(#strdate,"%Y/%m/%d"))

You can use MySQL str_to_date() function. It requires one format and will return NULL if the data doesnt match the format. UseCoalesce with str_to_date with str_to_date in descending order of likelihood of the format.
Example if yyyy/mm/dd is more common than mm/dd/yyyy then use
COALESCE(STR_TO_DATE(your_date_here,'%Y/%m/%d'),STR_TO_DATE(#strdate,"%m/%d/%Y"))
Edit: This is the same as Ondřej Šotek's answer but with a possible performance improvement

Related

MySQL date format to string

I have a dateformat but to display on front end I would like to display the data like so.
SELECT STR_TO_DATE('5,2013','%m,%Y');
The result I would like to generate is 'May 2013'.
Why are you storing dates as string values? Mysql has dedicated data types for date and time values: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-types.html
When using date, you can easily use DATE_FORMAT and set %m,%Y as formatting (second argument).
SELECT replace(date_format(str_to_date('5,2013','%m,%Y'),'%M-%Y'),'-',' ');
As to the format just read the docs: https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date-format. You need an uppercase M for the month name. And use DATE_FORMAT to get from a date to a string.
SELECT DATE_FORMAT(DATE '2013-05-01', '%M %Y');
Assuming that you have 5,2013 stored in your database, you need to use DATE_FORMAT after parsing the string:
SELECT DATE_FORMAT(STR_TO_DATE('5,2013','%m,%Y'), '%b %Y')
Why? Because it seems you don't have a date type stored in the database. So you parse it to date using STR_TO_DATE. This give you the default date format. DATE_FORMAT let you apply other formattings on it.
All avaliable formatting values are documented here: https://www.w3schools.com/sql/func_mysql_str_to_date.asp
In general, I would recommend to think about storing date objects instead of custom date strings like 5,2013. This avoids those castings, because you could directly use DATE_FORMAT. It also has benefits on filtering/ordering and performance. Using date types, you could easily sort by it or filter e.g. everything in month X.
I don't say its not possible with custom strings like 5,2013 but would be more complex and could result in bad performance if the db grows.
You can use the functions:
str_to_date() to convert the string (after concatenating the prefix '1' to your string) to a valid date and then
date_format() to reformat the date:
SELECT date_format(str_to_date(concat('1,', ?),'%d,%m,%Y'), '%b %Y');
Replace ? with your string.
See the demo.
Result:
May 2013

questions about the datetime type values

I have several things which I want to discuss with you guys.
Since, they were just simple questions, so no dataset here.
Suppose I have a datetime type column which called started_date, the value in it was like:
yyyy-mm-dd hh:mm:ss. So, if I want to select some IDs which were larger than one specified day (let's say June/01/2017), can I just using
select ID, started_date
from table1
where started_date>"2017-06-01";
Does this work?
I tried some samples, and it worked indeed in the mysql. However, someone told me that I cannot compare the datetime column with string values without converting their format. And it confused me. Because I thought the value "2017-06-01" here was date type value, so it does not need convert. Or am I thinking wrong?
Another thing was about the double quote and single quote, I understand that the single quote was used for string values. However, in this case, when I used double quote to quote "2017-06-01", it works. So, does it mean the double quote can quote date values?
I am just asking, so any response is welcome.
Thanks.
Your query is fine. You are using a safe date/time format for the string. In other words, if you have to store the value as a string, then use that format.
I would write the code as:
where started_date >= '2017-06-01'
I see no reason to exclude midnight on 2017-06-01 (although you might have a reason). Second, single quotes are the standard delimiter for strings.
That said, you can store the value as a string.
As a best practice, I stay away from comparing time-stamps to date-stamps. In this case you can be explicit and truncate the start date. And yes, use single quotes instead.
where SUBSTR(started_date, 1, 10) > '2017-06-01'
To make sure it works you could just convert the date time to a string first and compare the two strings:
to_char(started_date,'YYYY-MM-DD') >= '2017-06-01'
The Strings will compare just fine in that format.

MySQL timestamp format and datediff

Hi I'm writing queries for MySQL, and now my database has a column containing the timestamp in this format: 7/14/2015 7:57:49 AM, but I need to use the DATEDIFF function, so how can I convert the timestamp into the format like: 2015-7-14 (or 2015-07-14, I'm not sure which one is correct; just the date)?
This should convert your string to just the date in a date format, then you can use DATEDIFF on the date fields in question:
SELECT STR_TO_DATE(LEFT(t,LOCATE(' ',t) - 1), '%m/%d/%Y') FROM my_table;
The LEFT function will take the substring to the left of the space, which is just your date, then STR_TO_DATE will convert that substring to a date the system can use.
(Not knowing your field and table names, I used t and my_table.)
You don't need to. The way MySQL displays timestamps has nothing to do with the way they're stored internally; as long as it's TYPE TIMESTAMP or some compatible type, the DATEDIFF() function will know what to do with it.
TIMESTAMPs are actually stored as a really huge integer representing (I think) milliseconds from Midnight UTC, January 1st, 1970. The display format is determined by a system global variable, and has nothing to do with the actual value.
Converting from a string to a DATETIME or TIMESTAMP is actually also fairly straightforward using the STR_TO_DATE() function; in your case the format string would be something like
STR_TO_DATE('%c/%e/%Y %l:%i:%s %p', datecol)
although you might have to experiment a bit to make it work reliably.

Why i got null from this query

Following is my sql query kindly let me know why is it returning null
Select STR_TO_DATE ('11-APR-74','%e%b%Y')
OR
Select DATE_FORMAT ('11-APR-74','%e%b%Y')
From MySQL STR_TO_DATE function:
The server scans str attempting to match format to it. ... Scanning
starts at the beginning of str and fails if format is found not to
match.
This is why your first query fails: 11-APR-74 does not look like %e%b%Y, so date cannot be parsed. You should do instead
SELECT STR_TO_DATE ('11-APR-74','%e-%b-%Y')
From MySQL Date and Time types:
Although MySQL tries to interpret values in several formats, date
parts must always be given in year-month-day order (for example,
'98-09-04'), rather than in the month-day-year or day-month-year
orders commonly used elsewhere (for example, '09-04-98', '04-09-98').
This is why your second query fails: 74 is not a valid day of month, you should do instead
SELECT DATE_FORMAT ('74-APR-11','%e%b%Y')
Note, that DATE_FORMAT is usually used on DB values, not string literals as you do - to get an output different from the default one.
If you want to convert from string to date
Select STR_TO_DATE ('11-APR-74','%d-%b-%y')
use it like ::
Select STR_TO_DATE ('11-APR-74','%e-%b-%Y')
Because '%e%b%Y' format does not correspond to '11-APR-74' string value (as STR_TO_DATE function expects), and because '11-APR-74' value is of type CHAR, but not DATETIME (as DATE_FORMAT function expects).
If you want to reformat a date represented by a CHAR value, convert it from its original format to DATETIME first, and then convert it to a string of desired format:
SELECT DATE_FORMAT(STR_TO_DATE('11-APR-74','%e-%b-%Y'),'%e%b%Y');
By the way, you could strip dashes with a plain string sunction:
SELECT REPLACE('11-APR-74','-','');

Converting date format using str_to_date

In one of my Mysql database table the dates are stored in the format 31-Jan-05.
I'm trying to convert this format to 2005-01-31 before inserting them in other tables.
I've tried in this way str_to_date(exam_date, '%d%M%Y'), but i encounter the following error
Incorrect datetime value: '31-Jan-05' for function str_to_time
Can't i change the date format from 31-Jan-05 to 2005-01-31 using str_to_date?
Thanks in advance.
Yes. But you have two problems.
The second parameter is the current date format. (i.e. of the string)
You need to have the proper format (i.e. %b instead of %M).
Read the docs the for str_to_date().
str_to_date(exam_date, '%d-%b-%y')
Note: If you don't have a zero padded day, then you need to use %e instead of %d.