dateadd - finding a date in the past - sql

I have an odd problem with subtracting 18 months from a date.
Consider the following snippet:
Convert(dateTime,CREATION_DATE,103) >
DateAdd (MONTH, -18, Convert (DateTime, #IN_ACTIVITY_DATE, 103))
This forms part of a where clause in a stored procedure. When I run:
exec theSP #IN_ACTIVITY_DATE = '21/02/2013'
it runs fine, but when I change it to this:
exec theSP #IN_ACTIVITY_DATE = '21/01/2013'
it breaks with the error:
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
Does anyone have any thoughts on why it might be January (all other months are ok) that is breaking my code?
Thanks.
DS

To pass string as datetime use ISO format as yyyymmdd which guaranteed to work in any server with any culture info.;
exec theSP #IN_ACTIVITY_DATE = '20130121'
Also as a side note, if CREATION_DATE is already datetime then you don't need to CONVERT CREATION_DATE for comparison.
--if CREATION_DATE is DATETIME/DATE column
CREATION_DATE >
DateAdd (MONTH, -18, Convert (DateTime, #IN_ACTIVITY_DATE))

Specify the date in YYYY-MM-DD format.
Eg.:
exec theSP #IN_ACTIVITY_DATE = '2013-01-21'
Also, you can use SET DATEFORMAT to specify the date format:
Eg.:
SET DATEFORMAT dmy;
exec theSP #IN_ACTIVITY_DATE = '21/02/2013'
exec theSP #IN_ACTIVITY_DATE = '21/01/2013'
SET DATEFORMAT: Sets the order of the month, day, and year date parts for interpreting date, smalldatetime, datetime, datetime2 and datetimeoffset character strings.
SET DATEFORMAT { format | #format_var }
format | #format_var: Is the order of the date parts. Valid parameters are mdy, dmy, ymd, ydm, myd, and dym.

There might be something in your database, perhaps a check constraint, that doesn't like the January date. The conversion to seems to work on SQL Server 2008 (Fiddle). Something else might be causing the problem.
Also, the date formatting suggestions provided by the others are good advice.

Related

How to subtract one month from a date using SQL Server

I have a date in format dd/mm/yyyy. I want to subtract one month from it.
I am using this code but the output is "09/10/2020" I don't know why my code does the subtraction of the year -2 also.
This is my request
SELECT
FORMAT(CONVERT (DATE, DATEADD(MONTH, -1, CONVERT(char(9), GETDATE()))), 'dd/MM/yyyy')
you need to change it to:
select format(CONVERT (date,DATEADD(MONTH, -1,GETDATE())), 'dd/MM/yyyy' )
but as Larnu stated. it seems like you need to change the column.
Your current code doesn't work as expected because:
SELECT CONVERT(char(9), GETDATE());
Returns this (at least in my language):
Nov 9 20
Which is, unfortunately, and again in my language, a valid date (but in {20}20, not {20}22).
Even in the right style (103), char(9) would yield 10/11/202 tomorrow, since 9 digits is only enough if either the day or month is a single digit.
Don't know why you are converting GETDATE() to a string. Just perform date math on it and then format it if you need to (using a specific style number, e.g. 103 for d/m/y):
SELECT CONVERT(char(10), DATEADD(MONTH, -1, GETDATE()), 103);
I really wouldn't use FORMAT() for such simple output, as the CLR overhead really isn't worth it. Ideally you leave it as a date/time type until presentation time - surely your presentation layer can present your date as d/m/y if that's really a wise idea.
And if you are storing or passing dates as strings (and worse, in regional formats like d/m/y) you really should consider fixing that.
First of all,
You should be storing your Date as a string for easier manipulation. If you don't want to change the column, you can always convert from Date to Varchar and then (re)convert it.
Example:
First, convert Date to varchar using the style code '112' ISO for formatting as yyyyMMdd:
DECLARE #date DATE = GETDATE();
DECLARE #dateConverted as VARCHAR (8) = (SELECT CONVERT(VARCHAR, #date, 112));
Then you just subtract the month using DATEADD():
DECLARE #previousMonth AS VARCHAR (8) = (SELECT FORMAT(DATEADD(month, -1, #dateConverted), 'yyyyMMdd'));
Finally, convert varchar do Date again:
DECLARE #previousMonthConverted AS DATE = (SELECT CONVERT(CHAR(10), CONVERT(date, #previousMonth), 120));

Dutch varchar date issue in SQL server 13 month

I have the following datetime format ( as varchar ) in my database 13-04-2018 1:05:00.
I need to convert it to the following format: 2018-04-13 01:05:00. As datetime.
Normal convert functions can't do this because they try to take the 13th month, and that month doesn't exist. This error:
The conversion of a varchar data type to a datetime data type resulted
in an out-of-range value.
Does someone know how to convert this date issue?
Using datetimes is always a pain regardless of the language because of all the different formats across the world.
To sort your issue out currently, you need to use a format style which is a third parameter to CONVERT. Personally what I would suggest here is to store as a datetime, because storing datetimes as strings is never a good idea. It just gets too messy later on, but if saved in the format you would like, it would be saved as yyyy-MM-dd hh:mm:ss
SELECT CONVERT(DATETIME, '13-04-2018 1:05:00',103)
You can create your own function to format it in your desired output string.
CREATE FUNCTION FormatMyDate
(#Date DATETIME) RETURNS VARCHAR(20)
AS
BEGIN
RETURN FORMAT(#Date,'yyyy-dd-MM hh:mm:ss')
END
And then you can call it in SELECT statements like this:
SELECT dbo.FormatMyDate(yourDateCol)
FROM yourTable
this takes the date from the format where month comes before day and reverses the 2 values (month and day)
SELECT CONVERT(DATETIME, '2018-13-04 01:05:00', 103);
Results:
2018-04-13 01:05:00.000
This should work for you requirement...
SELECT FORMAT(yourdate, 'yyyy-dd-MM')
Your Solution Bro...
DECLARE #d DATETIME = GETDATE()
SELECT FORMAT ( #d, 'MM-dd-yyyy hh:mm:ss', 'de-de' ) AS 'Hoping your result'

Conversion failed when converting date and/or time from character string in sql on different dates

I have a simple question:
select cast( '11-04-15' as date)
works in SQL, but
select cast( '14-04-15' as date)
throws an error
Conversion failed when converting date and/or time from character string
Why does it happen?
Dates above 12 throw the error.
yes, it's logical that it'll throw an exception. the cause is you need
to maintain a specific date format like dd-mm-yyyy or mm-dd-yy or
something else
you can set the date format yourself using DATEFORMATSET DATEFORMAT { format | #format_var }
default is mdy and Valid parameters are mdy, dmy, ymd, ydm, myd, and dym
see here for more clarification.
when you are trying select cast( '11-04-15' as date), it's accept 11 as a month and 04 as a date, which is valid because default date format id mm-dd-yyyy
but in select cast( '14-04-15' as date) this it's accept 14 as a month which is invalid for the default date format, so you need to change it using set dateformat your_specific_date_format.
try
set dateformat dmy
select cast('11-04-15' as date)
select cast( '14-04-15' as date)
both will work,because current date format is dd-mm-yyy
11 and 14 both treat as a day which's valid for a date.
Use the SET DATEFORMAT to set the date format to DDMMYY. Something like this.
SET DATEFORMAT DMY;
SELECT CAST( '11-04-15' as date);
SELECT CAST( '14-04-15' as date);
you can also use CONVERT
SELECT CONVERT(DATE,'11-04-15',3);
SELECT CONVERT(DATE,'14-04-15',3);
or YYYYMMDD format to input the date string as suggested by Giorgos Betsos
SELECT CAST ('20150414' AS DATE)

SQL - Date Query Issue - varchar to datetime conversion resulted in out-of-range value

I have a SQL query written by a colleague who is no longer here. The query runs as part of an SSIS job, and as of this month has started failing with the following error:
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
The query itself is just a basic select with a where clause that looks for values in a certain time range (the date range between #startdate and #enddate)
The code to determine the time range is below:
DECLARE #RunDateTime datetime
DECLARE #RunDate datetime
DECLARE #StartDate datetime
DECLARE #EndDate datetime
DECLARE #Month int
DECLARE #Year int
DECLARE #strStartDate varchar(10)
SET #RunDateTime = GetDate()
SET #RunDate = cast(round(convert(real, #RunDateTime),0,1) as datetime)
IF DATEPART(d, #RunDate) = 16
BEGIN
SET #StartDate = DATEADD(d, -15, #RunDate)
SET #EndDate = #RunDate
END
ELSE
BEGIN
IF Month(#RunDate) = 1
SET #Month = 12
ELSE
SET #Month = Month(#RunDate) - 1
IF Month(#RunDate) = 1
SET #Year = Year(#RunDate) - 1
ELSE
SET #Year = Year(#RunDate)
SET #strStartDate = CONVERT(varchar(2), #Month)+ '/16/' + CONVERT(varchar(4), #Year)
SET #StartDate = CONVERT(datetime, #strStartDate, 101)
SET #EndDate = #RunDate
END
This job runs twice a month. Once on the 16th for data from the 1st to the 15th of the month, and once on the 1st of the next month for data from the 16th to the end of the previous month.
From what I can find online, the use of the varchar for strStartDate is the likely culprit? I'm not familiar enough with SQL to know how to replace all that convert stuff that's going on there? Also, is there a better way to determine the end of the month date than just getting the run time? Any help at all would be greatly appreciated.
(PS, we run this job on SQL Server 2008 R2) And I checked with the DBA and he said nothing about localization or regional settings has changed on the SQL server.
There are many formats supported by SQL Server - see the MSDN Books Online on CAST and CONVERT. Most of those formats are dependant on what settings you have - therefore, these settings might work some times - and sometimes not.
The way to solve this is to use the (slightly adapted) ISO-8601 date format that is supported by SQL Server - this format works always - regardless of your SQL Server language and dateformat settings.
The ISO-8601 format is supported by SQL Server comes in two flavors:
YYYYMMDD for just dates (no time portion); note here: no dashes!, that's very important! YYYY-MM-DD is NOT independent of the dateformat settings in your SQL Server and will NOT work in all situations!
or:
YYYY-MM-DDTHH:MM:SS for dates and times - note here: this format has dashes (but they can be omitted), and a fixed T as delimiter between the date and time portion of your DATETIME.
This is valid for SQL Server 2000 and newer.
If you use SQL Server 2008 or newer and the DATE datatype (only DATE - not DATETIME!), then you can indeed also use the YYYY-MM-DD format and that will work, too, with any settings in your SQL Server.
Also: with SQL Server 2008, it is recommended to use DATETIME2 (instead of DATETIME) if at all ever possible. DATETIME2 parsing of strings is a lot more forgiving for error and/or different formats (like US AM/PM formatting etc.) .
Don't ask me why this whole topic is so tricky and somewhat confusing - that's just the way it is. But with the YYYYMMDD format, you should be fine for any version of SQL Server and for any language and dateformat setting in your SQL Server.

Convert varchar into datetime in SQL Server

How do I convert a string of format mmddyyyy into datetime in SQL Server 2008?
My target column is in DateTime
I have tried with Convert and most of the Date style values however I get an error message:
'The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.'
OP wants mmddyy and a plain convert will not work for that:
select convert(datetime,'12312009')
Msg 242, Level 16, State 3, Line 1
The conversion of a char data type to a datetime data type resulted in
an out-of-range datetime value
so try this:
DECLARE #Date char(8)
set #Date='12312009'
SELECT CONVERT(datetime,RIGHT(#Date,4)+LEFT(#Date,2)+SUBSTRING(#Date,3,2))
OUTPUT:
-----------------------
2009-12-31 00:00:00.000
(1 row(s) affected)
SQL Server can implicitly cast strings in the form of 'YYYYMMDD' to a datetime - all other strings must be explicitly cast. here are two quick code blocks which will do the conversion from the form you are talking about:
version 1 uses unit variables:
BEGIN
DECLARE #input VARCHAR(8), #mon CHAR(2),
#day char(2), #year char(4), #output DATETIME
SET #input = '10022009' --today's date
SELECT #mon = LEFT(#input, 2), #day = SUBSTRING(#input, 3,2), #year = RIGHT(#input,4)
SELECT #output = #year+#mon+#day
SELECT #output
END
version 2 does not use unit variables:
BEGIN
DECLARE #input CHAR(8), #output DATETIME
SET #input = '10022009' --today's date
SELECT #output = RIGHT(#input,4) + SUBSTRING(#input, 3,2) + LEFT(#input, 2)
SELECT #output
END
Both cases rely on sql server's ability to do that implicit conversion.
Likely you have bad data that cannot convert. Dates should never be stored in varchar becasue it will allow dates such as ASAP or 02/30/2009. Use the isdate() function on your data to find the records which can't convert.
OK I tested with known good data and still got the message. You need to convert to a different format becasue it does not know if 12302009 is mmddyyyy or ddmmyyyy. The format of yyyymmdd is not ambiguous and SQL Server will convert it correctly
I got this to work:
cast( right(#date,4) + left(#date,4) as datetime)
You will still get an error message though if you have any that are in a non-standard format like '112009' or some text value or a true out of range date.
I found this helpful for my conversion, without string manipulation. https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql
CONVERT(VARCHAR(23), #lastUploadEndDate, 121)
yyyy-mm-dd hh:mi:ss.mmm(24h) was the format I needed.
Convert would be the normal answer, but the format is not a recognised format for the converter, mm/dd/yyyy could be converted using convert(datetime,yourdatestring,101) but you do not have that format so it fails.
The problem is the format being non-standard, you will have to manipulate it to a standard the convert can understand from those available.
Hacked together, if you can guarentee the format
declare #date char(8)
set #date = '12312009'
select convert(datetime, substring(#date,5,4) + substring(#date,1,2) + substring(#date,3,2),112)
Look at CAST / CONVERT in BOL that should be a start.
If your target column is datetime you don't need to convert it, SQL will do it for you.
Otherwise
CONVERT(datetime, '20090101')
Should do it.
This is a link that should help as well:
I'd use STUFF to insert dividing chars and then use CONVERT with the appropriate style. Something like this:
DECLARE #dt VARCHAR(100)='111290';
SELECT CONVERT(DATETIME,STUFF(STUFF(#dt,3,0,'/'),6,0,'/'),3)
First you use two times STUFF to get 11/12/90 instead of 111290, than you use the 3 to convert this to datetime (or any other fitting format: use . for german, - for british...) More details on CAST and CONVERT
Best was, to store date and time values properly.
This should be either "universal unseparated format" yyyyMMdd
or (especially within XML) it should be ISO8601: yyyy-MM-dd or yyyy-MM-ddThh:mm:ss More details on ISO8601
Any culture specific format will lead into troubles sooner or later...
use Try_Convert:Returns a value cast to the specified data type if the cast succeeds; otherwise, returns null.
DECLARE #DateString VARCHAR(10) ='20160805'
SELECT TRY_CONVERT(DATETIME,#DateString)
SET #DateString ='Invalid Date'
SELECT TRY_CONVERT(DATETIME,#DateString)
Link:MSDN TRY_CONVERT (Transact-SQL)
I had luck with something similar:
Convert(DATETIME, CONVERT(VARCHAR(2), #Month) + '/' + CONVERT(VARCHAR(2), #Day)
+ '/' + CONVERT(VARCHAR(4), #Year))
The root cause of this issue can be in the regional settings - DB waiting for YYYY-MM-DD while an app sents, for example, DD-MM-YYYY (Russian locale format) as it was in my case. All I did - change locale format from Russian to English (United States) and voilĂ .
This seems the easiest way..
SELECT REPLACE(CONVERT(CHAR(10), GETDATE(), 110),'-','')
SQL standard dates while inserting or updating Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.
So if you are inserting/Updating below 1/1/1753 you will get this error.
DECLARE #d char(8)
SET #d = '06082020' /* MMDDYYYY means June 8. 2020 */
SELECT CAST(FORMAT (CAST (#d AS INT), '##/##/####') as DATETIME)
Result returned is the original date string in #d as a DateTime.