I need to validate a date inside a social security number checking function. The date format it should accept is ddmmyyyy, for example 01012000 (first of Jan, 2000).
I have tried converting this string into yyyy-mm-dd, and using IsDate() function, but the problem is that sometimes the datetimeformat of SqlServer might be something else like dmy, and I cannot use the "set DateFormat ymd" inside a function because it gives this error:
Invalid use of a side-effecting operator 'SET COMMAND' within a function.
Also tried a try .. catch block but with the same results.
So I need a way to validate datetime, regardless of the SqlServer dateformat, in a user function.
This snippet of code will try to convert the input. It first changes the string to a German time format dd.mm.yyyy with convert format 104. It uses begin try to suppress any error during the conversion.
If it succeeds, the date is in #output_dt. If it fails, #output_dt will be null.
declare #input_str varchar(25)
declare #output_dt date
set #input_str = '31122011'
if len(#input_str) >= 8
begin
declare #german_str varchar(25)
select #german_str = substring(#input_str, 1, 2) + '.' +
substring(#input_str, 3, 2) + '.' +
substring(#input_str, 5, 4)
begin try
select #output_dt = convert(date, #german_str, 104)
end try
begin catch
end catch
end
select #output_dt
If you can't use begin catch, you could create a table with valid dates. This example creates a table called ValidDates with dates from 1900 to 2100:
if object_id('ValidDates') is not null
drop table ValidDates
create table ValidDates (date_str varchar(8), dt date)
go
truncate table ValidDates
declare #start_dt date
declare #end_dt date
set #start_dt = '1900-01-01'
set #end_dt = '2100-01-01'
; with cte as
(
select #start_dt as dt
union all
select dateadd(day, 1, dt)
from cte
where dt < #end_dt
)
insert ValidDates
(date_str, dt)
select replace(convert(varchar(10), dt, 104),'.','')
, dt
from cte
option (maxrecursion 0);
You can then check for a valid date like:
select #output_dt = dt from ValidDates where date_str = #input_dt
Seems like
SELECT ISDATE('2005-05-22') is affected by SET DATEFORMAT dmy and returns zero
but
SELECT ISDATE('20050522') is not affected even when dateformat is dmy, so this one can be used independently from any dateformat used as default by database.
Related
I have similar requirement, i have file feeding to SQL Server 2012 for a month but i wanted to convert the same file as a next month file.
For Example I have below
02/22/2018 02/23/2018 02/24/2018
and I want 03/22/2018 03/23/2018 02/24/2018
I am able to get upto this point but facing issue when i have below situation.
02/28/2018 02/24/2018
and I want 03/31/2018 03/31/2018
I have a normal calendar set up which I can use Can somebody please help.
you can use DATEADD() function for this like below :
SELECT DATEADD(month, 1, '02/22/2018') AS DateAdd;
I guess you are looking for EOMONTH function
somethink like this might help you solve your issue
DECLARE #date VARCHAR(10) = '02/28/2019'
SELECT CASE WHEN (EOMONTH(#date) = FORMAT(CAST(#date AS DATETIME),'yyyy-MM-dd'))
THEN EOMONTH(DATEADD(month,1,#date))
ELSE DATEADD(month,1,#date)
END
Note: I have used format function because EOMONTH returns date in 'yyyy-MM-dd' format
UPDATE
DECLARE #dates TABLE
(
FromDate DATETIME,
ToDate DATETIME
)
INSERT INTO #dates (FromDate)
VALUES('12/31/2017'),('1/31/2018'),('2/28/2018'),('3/31/2018')
select * from #dates
UPDATE #dates
SET ToDate =CASE WHEN (EOMONTH(FromDate) = FORMAT(CAST(FromDate AS DATETIME),'yyyy-MM-dd'))
THEN EOMONTH(DATEADD(month,1,FromDate))
ELSE DATEADD(month,1,FromDate)
END
SELECT * FROM #dates
Run this and you can see the final output
I have tried with the following sample
SELECT
FORMAT(CONVERT(DATETIME,'01011900'), 'dd/MM/yyyy')
FROM
identities
WHERE
id_type = 'VID'
Try this:
SELECT FORMAT(CONVERT(DATETIME,STUFF(STUFF('01011900',5,0,'/'),3,0,'/')),'dd/MM/yyyy')
Insert / using STUFF, and then convert it.
STUFF(STUFF('01011900',5,0,'/'),3,0,'/') -- 01/01/1900
Update:
I tried the following also,
DECLARE #DateString varchar(10) = '12202012' --19991231 --25122000
DECLARE #DateFormat varchar(10)
DECLARE #Date datetime
BEGIN TRY
SET #Date = CAST(#DateString AS DATETIME)
SET #DateFormat = 'Valid'
END TRY
BEGIN CATCH
BEGIN TRY
SET #DateFormat = 'ddMMyyyy'
SET #Date = CONVERT(DATETIME,STUFF(STUFF(#DateString,5,0,'/'),3,0,'/'))
END TRY
BEGIN CATCH
SET #DateFormat = 'MMddyyyy'
SET #Date = CONVERT(DATETIME,STUFF(STUFF(#DateString,1,2,''),3,0,
'/' + LEFT(#DateString,2) + '/'))
END CATCH
END CATCH
SELECT
#DateString InputDate,
#DateFormat InputDateFormat,
#Date OutputDate
Your data should be 19000101.So your input needs to be modified first then we need to use Convert to get your appropriate format.
declare #inp varchar(10) = '01011900'
select CONVERT(varchar, cast(right(#inp,4)+''+left(#inp,4) as datetime), 101)
--Output : 01/01/1900
Right now your question is absurd. There cannot be a generic format that can handle all the date formats, you need to provide that information to your query ( you would be much better of with a stored procedure in this scenario ) where you pass the date format string too. You could do something like this in your SELECT CASE
if the format is ddmmyyyy, do what JesuRaja suggested. But its already answered in SO
SELECT CONVERT (datetime, Stuff(Stuff('311012',5,0,'.'),3,0,'.'), 4)
if its mmddyyyy, see this answer
DECLARE #Date char(8)
SET #Date='12312009'
SELECT CONVERT(datetime,RIGHT(#Date,4)+LEFT(#Date,2)+SUBSTRING(#Date,3,2))
if its yyyymmdd, just do a CAST
SELECT CAST('20041223' AS datetime)
Bottomline is, you must specify the date format. For example, consider the string 20122012. Can you guess the date format?
Also, you cannot force the server to use / as your separator. The SQL Server will use either /, . or - depending on the Culture of the server.
I get this error in stored procedure code and I discovered one of the records is from a leap year date 2008-02-29. How do I get around this with the code I have. Here is the code:
set #ContractDate = cast(cast(#Year as nvarchar(4))
+ '/' + cast(datepart(mm,#ContractDate) as nvarchar(2))
+ '/' + cast(datepart(dd,#ContractDate) as nvarchar(2)) as datetime)
First off:
What values do you have for #Year and #ContractDate?
And what format/type is #ContractDate?
I ask because this works for me on us_english SQL Server 2012
SELECT cast('2008/02/29' as datetime)
However, if I change SET DATEFORMAT then I can break the above code
-- breaks
SET DATEFORMAT DMY;
SELECT cast('2008/02/29' as datetime)
Using ISO date format is OK no matter what I use for SET DATEFORMAT
SET DATEFORMAT DMY;
SELECT cast('20080229' as datetime);
SET DATEFORMAT MDY;
SELECT cast('20080229' as datetime);
SET DATEFORMAT YDM;
SELECT cast('20080229' as datetime);
Conclusion: you are using non ISO date formats and relying on implicit conversions
It is better to get the string in ISO format (yyyymmdd) before converting to datetime/date and it will work in any server regardless of culture settings
If #ContractDate is a datetime/date type and #year is like 2012/'2012' then following should work. Working Example
Set #ContractDate = convert(datetime,
convert(varchar(4),#year) + right(convert(varchar(8),#ContractDate,112),4))
ALTER PROCEDURE [dbo].[Sden_report1]
#fromdt nvarchar(13),
#todt nvarchar(13)
AS
BEGIN
select AD_PID,AD_Appointmentdate,AD_Patientname,AD_Patientphno,AD_Visitpurpose
from Appointment_Details1
where
--PL_CID = #CID and PL_Itemcode = #JCode AND
(#fromdt = '' OR (DATEDIFF(DAY,AD_Appointmentdate, #fromdt) <= 0))
AND (#todt = '' OR (DATEDIFF(DAY,AD_Appointmentdate, #todt) >= 0))
end
GO
When i Execute the procedure
i will get below error:
EXEC Sden_report1 '20-11-2012','20-05-2013'
Error
The conversion of a nvarchar data type to a datetime data type resulted in an out-of-range value.
Anyone Help...`enter code here`
I have the following procedure:
ALTER PROCEDURE [dbo].[myProcedute]
#mydate VARCHAR(8000) = NULL
IF #mydate = ''
BEGIN
SET #mydate = NULL
END
ELSE
BEGIN
SET #mydate = CONVERT(DATETIME, #mydate, 103) -- dd/mm/yy
END
INSERT INTO dbo.myTable(theDate) VALUES(#mydate)
And I execute it like this:
EXEC [dbo].[myProcedure] '02/02/2012'
After execution I get this error:
Conversion failed when converting datetime from character string.
I execute it from my vb6 code and the date can vary. This time is
'02/02/2012' but next time it may be ''(empty).
When it comes as '', I need it to insert a NULL as you can see in the IF clause.
Why am I getting this error?
Thanks a lot !
Use ISDATE() to check if it is a valid date.
Conversion seems fine. And as comments suggests, it would solve a lot if you could change parameter to DATE
ALTER PROCEDURE [dbo].[myProcedute]
#mydate VARCHAR(8000) = NULL
IF ISDATE(#mydate)
BEGIN
SET #mydate = CONVERT(DATETIME, #mydate, 103) -- dd/mm/yy
END
ELSE
BEGIN
SET #mydate = NULL
END
INSERT INTO dbo.myTable(theDate) VALUES(#mydate)
It is better to format your date string to ISO format (yyyymmdd) which guaranteed to work on any sql-server. Assuming you vb code passing it like dd/mm/yyyy (as per your data). Try this;
--Format #mydate to yyyymmdd
SELECT #mydate = CASE LEN(#mydate) WHEN 10
THEN RIGHT(#mydate,4)+ SUBSTRING(#mydate,4,2)+ LEFT(#mydate,2)
ELSE NULL END
--Insert
INSERT INTO dbo.myTable(theDate) VALUES(#mydate)
I have a function which converts all of the strings to datetime.
ALTER FUNCTION formatit(
#fromtime VARCHAR(50) -- varchar
)
RETURNS DATETIME
AS
BEGIN
DECLARE #from datetime
IF (CHARINDEX('NOON',#fromtime,0)) = 0
SET #from = CONVERT(DATETIME, #fromtime)
ELSE
SET #from =CONVERT(DATETIME, '01/01/2000 12pm')
RETURN(#from)
END
SELECT dbo.formatit('04/12/2011 12 ')
So when u see the last select stmt it throws an error saying:
The conversion of a char data type to a datetime data type
resulted in an out-of-range datetime value.
It works fine if i give time 4 pm or 4:00. But it gives an error if i give just 4. Kindly let me know how i can handle this?
You could add a lot of code to look at the string and see if there is a ':' (like you have code to look for NOON). The problem is that if the string ends in 12PM the conversion will work too. So you would have to do something like
ALTER FUNCTION formatit(
#fromtime VARCHAR(50) -- varchar
)
RETURNS DATETIME
AS
BEGIN
DECLARE #from datetime
IF (CHARINDEX('NOON',#fromtime,0)) <> 0
BEGIN
SET #from =CONVERT(DATETIME, '01/01/2000 12pm')
END
ELSE IF (CHARINDEX('PM',#fromtime,0)) = 0 AND (CHARINDEX('AM',#fromtime,0)) = 0 AND (CHARINDEX(':',#fromtime,0)) = 0
BEGIN
SET #fromtime = #fromtime+':00'
SET #from =CAST(#fromtime AS datetime)
END
ELSE
BEGIN
SET #from =CAST(#fromtime AS datetime)
END
return(#from)
END
It looks like whitespace is ignored - I tried these and they all worked...
SELECT dbo.formatit('04/12/2011 12 ')
SELECT dbo.formatit('04/12/2011 12:00')
SELECT dbo.formatit('04/12/2011 12PM')
SELECT dbo.formatit('04/12/2011 12AM')
SELECT dbo.formatit('NOON')
Really you should look at the data you are using to feed this function with something other than TSQL so you have a better string parser.
Your call to dbo.formatit('04/12/2011 12 ') results in a call to convert(datetime, '04/12/2011 12 '). This string is not a valid input to convert to a date/time value.
See the list of formats in the CAST and CONVERT reference in MSDN. If you need to convert this string, you will need to change the time portion into "12:00PM" or just "12:00" (which is assumed to be in the 24-hour format).
First, I would find all the unique time occurrences in your table, something like:
select distinct rtrim(substring(#timeField,charindex(' ',#timeField)+1,99))
as TimePortion
This will give you a sense of what you are dealing with.
Then, in your function, break apart the date and time portions...
Now, based on what you found from the query, you need to spell out what to do with the times you find. For example, if the time portion is numeric, you might simply append :00 to it (i.e. 4 becomes 4:00). If you see NOON, you might replace it with 12:00pm, etc.
ALTER FUNCTION formatit( #fromtime VARCHAR(50) )
RETURNS DATETIME
AS
BEGIN
declare #dtPortion VARCHAR(12)
declare #tmPortion VARCHAR(32)
declare #x INT
SET #x = charindex(' ',#fromTime)
SET #dtPortion = left(#fromTime,#x-1)
SET #tmPortion = rtrim(substring(#fromTime,#x+1,99))
-- Figure out what to do
SELECT #FromTime =
CASE
WHEN IsNumeric(#tmPortion) = 1 THEN #dtPortion+' '+#tmPortion+':00'
WHEN #tmPortion = 'NOON' THEN #dtPortion+' 12:00pm'
ELSE
#dtPortion+' 12:00pm'
END
SET #from =CONVERT(DATETIME, '01/01/2000 12pm')
RETURN(#from)
END
Go
Hope this gets you started