SQL Server Compare Month-Day portion of date - sql

I'm trying to compare 2 people and see whose birthday falls earlier in the year. I'm trying to hack together a solution where I take the mm-dd from a datetime field using RIGHT(DOB, 5) and concatenating it with '1900' to create a new date field and use that for comparison.
CONVERT(DATE,'1900-' + RIGHT(DOB,5),126) DOB
However I'm getting the following error:
Conversion failed when converting date and/or time from character string.
Any suggestions for how to fix this?

Try this
right(convert (char(10), dob, 120), 5)
the 120 format is yyyy-mm-dd

You can use
format(date,'MMdd')

Related

Convert a Custom (String) Date Format to datetime in SQL

I need to get all rows from a table that have a date of the last 7 days or greater. My issue is that when the DB was originally setup, someone set it up as VARCHAR. So now I need to CONVERT the String to a DateTime.
The issue is, the format of the Date/Time isn't recognized by SQL. The format is:
2023-01-01T00:00:00.000+0000
If I can trim off the last 8 characters from the string, SQL will recognize it. But I've had no luck thus far. The statement I was attempting was:
SELECT CONVERT(datetime, TRIM('.000+0000' FROM date_col), 127) FROM table_name;
But that resulted in the error:
Conversion failed when converting date and/or time from character string.
Try this
SELECT CAST(LEFT(REPLACE('2023-01-01T00:00:00.000+0000', 'T', ' '), 19) AS DATETIME)
No need for the replace with datetime2(n)
Select WithMS = try_convert(datetime2(3),left('2023-01-01T00:00:00.100+0000',23))
,SansMS = try_convert(datetime2(0),left('2023-01-01T00:00:00.100+0000',23))
Results
WithMS SansMS
2023-01-01 00:00:00.100 2023-01-01 00:00:00

Converting date 24-NOV-49 to yyyy-mm-dd format

I am trying to convert the date 24-NOV-49 to 1949-11-24.
This is the code I am currently using:
TRY_CONVERT(DATE, NULLIF(GEB_DATUM,''), 103)
Unfortunately this is giving me wrong conversions:
DATE WRONG CONVERSION SHOULD BE
24-NOV-49 2049-11-24 1949-11-24
01-MEI-62 NULL 1962-05-62
05-DEC-71 NULL 1962-12-05
The default cut-off on two digit years for SQL Server is 50 so anything before this is moved to the current century and anything after into the previous one.
You can change the default and instructions are here
More likely though you'll need to handle it manually, break the string into year, month and day, apply logic to get the right numerical values and then build it up again with DATEFROMPARTS.
You may configure the Server properties of the-two-digit-year-cutoff-server-configuration-option as below:
Then try execute the below statements:
SELECT CONVERT(VARCHAR, CONVERT(DATE,ISNULL('24-NOV-49','')),23);
SELECT CONVERT(VARCHAR, CONVERT(DATE,ISNULL('05-DEC-71','')),23);
SELECT CONVERT(VARCHAR, CONVERT(DATE,ISNULL('01-MAY-62','')),23);
Ref: https://learn.microsoft.com/en-us/sql/database-engine/configure-windows/configure-the-two-digit-year-cutoff-server-configuration-option?view=sql-server-2017

Can't convert YYYYMMDD to date

I'm trying to view software that has been installed within the last 30 days. The format of my date is 20150327. When I try to the following condition in the where clause
and DateDiff(day,arp.InstallDate0,GetDate()) < 30
I receive the following error message:
Conversion failed when converting date and/or time from character
string.
I have also tried the following and was unsuccessful:
CONVERT(varchar(8),arp.InstallDate0,112)
As well as:
ISDATE(CONVERT(datetime,arp.InstallDate0,112))
When I add ISDATE, it finally runs the query, but it is not showing any data and I know that there are installs within the last 30 days, so I'm thinking the date is still not being recognized.
EDIT The InstallDate0 column is nvarchar.
You do not need a conversion format for YYYYMMDD when converting to date, datetime2, and datetimeoffset. SQL Server recognizes this ISO standard format with no conversion in these cases, regardless of internationalization settings (there is one setting that affects my preferred format of YYYY-MM-DD; the documentation is here). So, you could do:
where cast(arp.InstallDate0 as date) > dateadd(day, -30, getdate())
At this point: "Shame on you for storing dates as strings."
That said, it is better (in your case) to do the comparison as strings rather than dates. You have a good date format for this, so:
where arp.InstallDate0 > convert(varchar(8), dateadd(day, -30, getdate()), 112)
Why is this better? With no functions on the column name, the query can take advantage of an appropriate index (if one is available).
You must use the syntax below, as the first argument for the CONVERT function is the target data type
CONVERT(datetime,'20150327',112)
You must use the syntax below:
WHERE
DATEDIFF(day, CONVERT(datetime, arp.InstallDate0, 112), GetDate()) < 30
Try converting the format using a converter to convert it to a date/or time string through conversion of its characters, then using the string to convert the numbers into a more usuable format with additional conversion
CONVERT(datetime,'20150327',112)

Need to calculate date difference of today date vs converted date field

I have a table with a column that was previously converted using
(CONVERT(VARCHAR(19), GETDATE(), 112)
With the getdate being the date when the field was inserted. Now I have to compare the current date against the date the field was inserted.
The issue I'm facing is that when the date field is from last month, say 20131004, I calculate date difference by (CONVERT(VARCHAR(19), GETDATE(), 112) - 20131004, the result is 200. Obviously this is wrong...
Could you please suggest me how I could calculate the true date difference?
You should be using the DATE or DATETIME data type for that column. Why on earth would you ever store a date as a string? Do you know how much you lose by doing so? Validation, for one - a VARCHAR(19) column will accept 20131004 12:34 PM but will also accept nonsense values like I am not a date!.
If the data is actually good, you can simply do this instead of lazy shorthand and without any explicit conversions:
SELECT DATEDIFF(DAY, column_name, GETDATE()) FROM dbo.table;
If you get an error message with this, then you have bad data. You can identify it like this:
SELECT column_name FROM dbo.table WHERE ISDATE(column_name) = 0;
Please read:
Bad habits to kick : choosing the wrong data type
Bad habits to kick : mis-handling date / range queries
Bad Habits to Kick : Using shorthand with date/time operations
I agree with #Aaron that you should store a date field in a date field, not a text field.
If for some reason you do want to store it in a text field then the easiest way to calculate the number of days is to convert it back to a date field and then compare it:
SELECT DATEDIFF(DAY, CAST(column_name as DATETIME), GETDATE()) FROM dbo.table
This will throw an error if the value in the column cannot be converted to a date. You'll also need to make sure that the date is formatted correctly for your database. Assuming you use the format 112 you should be ok, but if you have the value 04/12/2013 in the column is that the 4th December 2013 or the 12th April 2013? It depends on how your database is configured.
But anyway, if you always insert dates in that field then you're nuts not making it a date field.
If you need to display the date somewhere then convert it on the way out.

How do I display varchar date string with mixed format to another format?

I am using SQL server 2008 R2. I know I can use CONVERT with different format code as the third parameter to do the conversion to DATETIME first and CONVERT again to VARCHAR with another format code to change the display format.
The real problem now is I have mixed raw data in a single column. So my question is how do you write a single SELECT statement to display from mixed YYYY/MM/DD, DD/MM/YYYY all to DD/MM/YYYY?
I tried to use ISDATE() but it think 31/01/2013 is not a date while 01/01/2013 is a date. Now I could only think of to see if the YYYY is on the left or on the right to determine the correct input format, but I dont know how to write it out in a single SELECT statement.
Any procedure to change the format first then do a simple SELECT is not an option. I am not allowed to change the source.
Thank you
Why not just use string manipulations? Something like:
select (case when substring(d, 5, 1) = '/' -- YYYY/MM/DD
then right(d, 2)+'/'+substring(6, 2)+'/'+left(d, 4)
else d
end)
By the way, if you are choosing formats for dates when represented as strings, I highly recommend YYYY-MM-DD (or YYYY/MM/DD) because comparison operators work on them.
If you are sure that only those 2 formats (yyyy/mm/dd and dd/mm/yyyy) exist in the data, then you could probably get away with a CASE statement along the lines of:
CASE
WHEN (SUBSTRING(dateColumn, 5, 1) = '/') THEN CONVERT(datetime, dateColumn, 111)
ELSE CONVERT(datetime, dateColumn, 103)
END