How to define if a string is date or datetime? - sql

I have incoming string, for instance 12.10.03 00:00:00.0000000. How to define if there is time in this string or just date?
Note that, date and time can have different formats. For example:
date can be January 03, 2012
time can be 1:1

If this doesn't return zero there is time:
SELECT DATEDIFF(SECOND,#VariableOrColumn,CAST(#VariableOrColumn AS DATE))
Add more precision for DATETIME2(7) by adding nano seconds if needed.

Use the LIKE operator;
if (#MyString like '%[0-9][0-9]:[0-9][0-9]:[0-9][0-9]%') ...

You can write as:
SELECT CASE WHEN PATINDEX( '%:%','12.10.03 00:00:00.0000000')> 0 THEN 'datetime'
ELSE 'Date' END AS Result
and to validate a date you can use ISDATE function.

You can take like this:
SELECT x = SUBSTRING('12.10.03 00:00:00.0000000', 1, 8);
Edit code for different formats;
SUBSTRING('12.10.03 00:00:00.0000000', 1,CHARINDEX(' ','12.10.03 00:00:00.0000000'));

First cast your string as datetime to put it in a proper format then just cast the resulting datetime as time and compare it with midnight as time and viola:
Select Case when Cast(Cast(#yourstring as datetime) as Time) = Cast('00:00:00.0000000' as time) then Cast(#yourstring as date) else Cast(#yourstring as datetime) end

if(#x='12.10.03').it is valid datetime and time is 00:00:00
if(#x='12.10.03 00:00:00.0000000').it is valid datetime and time is again 00:00:00
So what do you mean by saying if it contain time.
you can test this script thoroughly with different input .I tested and its running fine .
BEGIN TRY
declare #x varchar(32) = '12.10.03 00:00:00.0000000'
-- or '12.10.03' or '00:00:00.0000000' or '0000000' or 'fgdfgg'
Declare #outputdt datetime2(7)
Declare #hr int
Declare #minute int
Declare #sec int
set #outputdt=#x
--select #outputdt
if isdate(LEFT(#x, 21))=1
BEGIN
select LEFT(#x, 21)
select #hr=DATEPART(hour,#outputdt)
,#minute=DATEPART(minute,#outputdt)
,#sec=DATEPART(minute,#outputdt)
END
else
BEGIN
select #hr=DATEPART(hour,#outputdt)
,#minute=DATEPART(minute,#outputdt)
,#sec=DATEPART(minute,#outputdt)
select 'Not valid1'
END
END TRY
BEGIN CATCH
select 'not valid'
END CATCH
select #hr,#minute
if(#hr>0)
select 'Todo'

After some r&d , I do this and I think this will help you.
You are not mention Sql version, so this sample will work SQLSERVER2008 and above
For more info :-
http://blog.sqlauthority.com/2012/09/12/sql-server-get-date-and-time-from-current-datetime-sql-in-sixty-seconds-025-video/
declare #s nvarchar(200) = '12.10.03' -- 00:00:00.0000000'
--select CONVERT(time, #s)
Select
case
when isdate(#s ) = 1
then
case
when CONVERT(time, #s) = '00:00:00.0000000'
then 'no time'
else 'it has time'
end
else
'no time'
end
as dateHaveTimeOrNOT
set #s = '12.10.03 01:20:00'
Select cast (#s as date) , isdate(#s ),CONVERT(time, #s),
case
when isdate(#s ) = 1
then
case
when CONVERT(time, #s) = '00:00:00.0000000'
then 'no time'
else 'it has time'
end
else
'no time'
end
as dateHaveTimeOrNOT

Related

MSSQL Date Format

i want to get sql date format as follow
this is i tried code
select case when
left(datepart(day,getdate()),1)=4 then concat(datepart(day,getdate()),'th',' of ',DATENAME(month,GETDATE()),' ',datepart(year,getdate()))
end
this is output from my query 4th of August 2020
DECLARE #day int = datepart(day,getdate())
SELECT CONCAT(#day,
CASE WHEN #day=1 OR #day=21 OR #day=31 THEN 'st'
WHEN #day=2 OR #day=22 THEN 'nd'
WHEN #day=3 OR #day=23 THEN 'rd' ELSE 'th' END, ' of ',DATENAME(month,GETDATE()),' ',datepart(year,getdate()) )AS 'Date'
Would give you something like that.
Edit : if you make it as function, and pass it date as param you could use that pretty much anywhere. Will need to replace getdate() with parameter name then
CREATE FUNCTION [dbo].[fnc_GetDateString]
(
#date DATETIME
)
RETURNS nvarchar(100)
AS
BEGIN
--DECLARE #date DATETIME = '2020-08-31'
DECLARE #day int = datepart(day,#date)
DECLARE #DateString nvarchar(100)
SET #DateString = CONCAT(#day,
CASE WHEN #day=1 OR #day=21 OR #day=31 THEN 'st'
WHEN #day=2 OR #day=22 THEN 'nd'
WHEN #day=3 OR #day=23 THEN 'rd' ELSE 'th' END, ' of ',DATENAME(month,#date),' ',datepart(year,#date) )
RETURN #DateString
END

Select between two dynamic (variable) dates SQL

I have a query that runs once a day that I would like to share however I need to remove the part where the other users in my team will have to edit it. Essentially, it's run Monday thru Friday. I want, if today is Monday, give me the last 3 days worth of data. Any other day, just give me yesterday's data.
So far this is what I have:
Update: They are all strings, so now I get the following error.
"Incorrect syntax near the keyword 'BETWEEN'."
DECLARE #daychecker varchar(max) = FORMAT(GETDATE(), 'dddd')
DECLARE #daterange0 varchar(max)
DECLARE #daterange1 varchar(max) = FORMAT(GETDATE()-3, 'yyyy-MM-dd')
DECLARE #daterange2 varchar(max) = FORMAT(GETDATE()-1, 'yyyy-MM-dd')
IF #daychecker = 'Wednesday'
BEGIN
SET #daterange0 = BETWEEN #daterange1 AND #daterange2
END
ELSE
BEGIN
SET #daterange0 = FORMAT(GETDATE()-1, 'yyyy-MM-dd')
END
SELECT #daterange0;
The result for today as an example should return yesterday's date. But that doesn't work. I will consider all options including hardcoding some sort of master start date that we can count from like maybe the start of the year or something.
You're much better off defining 2 dates, a start date and end date, and filtering your query based on them. EDIT: I'm now unsure if you want actual dates for filtering data, or a label for a report. I modified my answer to include the latter, use whichever you want and ignore the other ...
DECLARE #DateStart DATE
DECLARE #DateEnd DATE
DECLARE #LableRange varchar(max)
SELECT DATEPART(WEEKDAY, GETDATE()) --Sun=1, Mon=2, ...
IF DATEPART(WEEKDAY, GETDATE()) = 2 BEGIN
SET #DateStart = DATEADD (DAY, -5,GETDATE())
SET #DateEnd = DATEADD (DAY, -2,GETDATE())
SET #LableRange = CONCAT(FORMAT(#DateStart, 'yyyy-MM-dd'), ', '
, FORMAT(DATEADD(day,1,#DateStart), 'yyyy-MM-dd'), ', '
, FORMAT(DATEADD(day,2,#DateStart), 'yyyy-MM-dd'))
-- or maybe this format is better
--SET #LableRange = CONCAT('BETWEEN '
--, FORMAT(#DateStart, 'yyyy-MM-dd'), ' AND '
--, FORMAT(DATEADD(day,2,#DateStart), 'yyyy-MM-dd'))
END ELSE BEGIN
SET #DateStart = DATEADD (DAY, -1,GETDATE())
SET #DateEnd = GETDATE()
SET #LableRange = FORMAT(#DateStart, 'yyyy-MM-dd')
END
SELECT #LableRange
SELECT * FROM SomeTable as T
WHERE T.TestDate < #DateEnd AND T.TestDate >= #DateStart
Note that this works even if the date you are filtering on is a datetime instead of pure date.

How to pass the Datetime value as parameter to a stored function?

I created a function in SQL SERVER that takes in parameter a datetime value, and when I tried to execute it, I didn't know how to pass a Datetime value as parameter to this function, I got this error : Failed to convert date and / or time from a string.
this is the code of my function :
CREATE FUNCTION [dbo].[nb_pieces_produites] (#dateInsertion datetime)
returns decimal(4,0)
AS
BEGIN
DECLARE #year decimal(4,0), #month decimal(2,0), #day decimal(2,0) ,#hour
decimal(2,0), #nbPiecesProduites decimal(4,0)
set #year = (select DATEPART(yyyy, #dateInsertion))
set #month = (select DATEPART(mm, #dateInsertion))
set #day = (select DATEPART(dd, #dateInsertion))
set #hour = (select DATEPART(hh, #dateInsertion))
set #nbPiecesProduites = (SELECT COUNT(DISTINCT Num_Serie) FROM [dbo].
[dbo_Test] WHERE #dateInsertion BETWEEN '#year-#month-#day #hour:00:00' AND
'#year-#month-#day #hour:59:59')
return #nbPiecesProduites
END
and this is my query :
select [dbo].[nb_pieces_produites]('2017-06-19 11:38:52')
Can anyone help me please ?
Don't spend lots of time fiddling around with strings - try to keep your data as datetime data throughout.
To round a datetime down to the previous hour boundary, use a DATEADD/DATEDIFF pair:
CREATE FUNCTION [dbo].[nb_pieces_produites] (#dateInsertion datetime)
returns decimal(4,0)
AS
BEGIN
set #nbPiecesProduites = (SELECT COUNT(DISTINCT Num_Serie) FROM [dbo].
[dbo_Test] WHERE
date_column_from_table >= DATEADD(hour,DATEDIFF(hour,0,#dateInsertion),0)
AND
date_column_from_table < DATEADD(hour,DATEDIFF(hour,0,#dateInsertion)+1,0)
)
return #nbPiecesProduites
END
And, just to be safe, call it like this:
select [dbo].[nb_pieces_produites]('2017-06-19T11:38:52')
(Occasionally, under some settings, SQL Server will interpret nnnn-nn-nn as yyyy-dd-mm rather than yyyy-mm-dd, if it's followed by a space and then a time, rather than using T as the separator)
it's error because your function expect dateTime value, but when you called it you passing string not dateTime
change your query into :
select [dbo].[nb_pieces_produites](getDate())
CREATE FUNCTION [dbo].[nb_pieces_produites] (#dateInsertion datetime)
RETURNS decimal(4,0)
AS
BEGIN
RETURN
(
SELECT COUNT(DISTINCT Num_Serie)
FROM dbo.dbo_Test
WHERE
-- Use the date part to compare
CONVERT(date, [datetimecolumn]) = CONVERT(date, #dateInsertion)
-- Then compare with hour
AND DATEPART(HOUR, [datetimecolumn]) = DATEPART(HOUR, #dateInsertion)
)
END

why doesn't date show am or pm

Why am I not getting time with am or pm
DECLARE #inputDate varchar(25)
SELECT #inputDate = '3/13/2012 13:00'
-- Declare the return variable here
DECLARE #Result DATETIME
DECLARE #toReturn NVARCHAR(25)
-- Add the T-SQL statements to compute the return value here
SET #inputDate = REPLACE(#inputDate, '24:00', '00:00')
SET #Result = null
SET #toReturn = null
IF (ISDATE(#inputDate)=1)
BEGIN
DECLARE #utcOffset int
SET #utcOffset = -(DATEDIFF(HH, GETUTCDATE(), GETDATE()))
SET #Result = DATEADD(HH, #utcOffset, #inputDate)
SET #toReturn = CONVERT(NVARCHAR, #Result, 101)
END
-- Return the result of the function
SELECT #toReturn
Returns only date portion?
You will need to change CONVERT(NVARCHAR, #Result, 101) to something else. 101 returns a mm/dd/yyyy format. See here for more details: http://msdn.microsoft.com/en-us/library/ms187928.aspx
You are using 101 in your last convert statement and that is date only.
Have a look here for other options. CAST and CONVERT (Transact-SQL)
Try another date format instead of 101 in CONVERT operator.
Because your final conversion uses a format that only includes dates - no time component.
Try the following, instead:
SET #toReturn = CONVERT(NVARCHAR, #Result, 121)

dateformat not as expected

I have the following function below.
It returns a date like Feb 29 2012 10:00PM. Is there a way to make it return the format as 2/29/2012 10:00PM
CREATE FUNCTION scrubDateString
(
-- Add the parameters for the function here
#inputDate varchar(150)
)
RETURNS DATETIME
AS
BEGIN
-- Declare the return variable here
DECLARE #Result DATETIME
-- Add the T-SQL statements to compute the return value here
DECLARE #tmpDate datetime
SET #Result = null
IF (ISDATE(#inputDate)=1)
BEGIN
SET #Result = DATEADD(HH, 5, #inputDate)
END
-- Return the result of the function
RETURN #Result
END
The function itself is returning a Date and time, "Feb 29 2012 10:00PM" and "2/29/2012 10:00AM" are merely string representations of that date (I am assuming that the AM and PM switch are not relevant to the question and are just a mistake). IF you want to format the date as a particular string look at the CONVERT function. e.g:
DECLARE #Date DATETIME
SET #Date = scrubDateString(#YourString)
SELECT CONVERT(VARCHAR, #Date, 101) + ' ' + RIGHT(CONVERT(VARCHAR, #Date, 0), 7) [Date]
Although I'd strongly advise leaving your date as a date, and doing any formatting on the application side if at all possible. If I have assumed wrong about the AM PM switch you could alter the code above to the following:
DECLARE #Date DATETIME
SET #Date = scrubDateString(#YourString)
IF (DATEPART(HOUR, #Date) > 12)
BEGIN
SET #Date = DATEADD(HOUR, -12, #Date)
END
SELECT CONVERT(VARCHAR, #Date, 101) + ' ' + RIGHT(CONVERT(VARCHAR, #Date, 0), 7) [Date]
If you want to format a DateTime you will need to return it as VARCHAR instead of as a date. If you declare a FUNCTION to return DateTime then it will always return a DateTime formatted in the standard SQL way.
You can return it as a string by using the sql CONVERT function:
RETURN CONVERT(varchar(500), #Result, 101)
A list of formats can be found on msdn. If you want a different format then you need to do something like what's discussed in this question
just change\add this:
SET #Result = DATEADD(HH, 5, #inputDate)
SET #Result = CONVERT(VARCHAR(10), #Result , 101) + ' ' + RIGHT(CONVERT(VARCHAR, GETDATE(), 100), 7)
you can make it on one line, of course, just did on 2 for clarity
forgot to add that you need to change the return variable to varchar, instead of datetime.
If you cant do that, maybe you can add the convert to the places that are calling the function (which would be worst, for sure)