I have used a tool to convert PL/SQL to TSQL but I am getting weird errors for some cases.
CREATE PROC Dates
(
#PeriodType varchar(15),
#ReportStart varchar(15),
#ReportEnd varchar(15)
)
AS
BEGIN
SELECT CASE
WHEN #PeriodType = 'CUR_WEEK' THEN CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() + 1 - CONVERT(NUMERIC(8, 2), CONVERT(VARCHAR(23), GETDATE())), 112))
WHEN #PeriodType = 'NEXT_WEEK' THEN CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() + 8 - CONVERT(NUMERIC(8, 2), CONVERT(VARCHAR(23), GETDATE())), 112))
WHEN #PeriodType = 'PREV_DAY' THEN CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() - 1, 112))
WHEN #PeriodType = 'PREV_WEEK' THEN CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() - 6 - CONVERT(NUMERIC(8, 2), CONVERT(VARCHAR(23), GETDATE())), 112))
WHEN #PeriodType = 'PREV_2WEEK' THEN CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() - 13, 112))
WHEN #PeriodType = 'CUR_MONTH' THEN CONVERT(DATETIME, CAST(CONVERT(VARCHAR(23), GETDATE()) AS VARCHAR) + '01', 112)
WHEN #PeriodType = 'DATE_RANGE' THEN CONVERT(DATETIME, #ReportStart)
END AS "StartDate",
CASE
WHEN #PeriodType = 'CUR_WEEK' THEN CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() + 8 - CONVERT(NUMERIC(8, 2), CONVERT(VARCHAR(23), GETDATE())), 112)) - (1 / CONVERT(FLOAT, 86400))
WHEN #PeriodType = 'NEXT_WEEK' THEN CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() + 15 - CONVERT(NUMERIC(8, 2), CONVERT(VARCHAR(23), GETDATE())), 112)) - (1 / CONVERT(FLOAT, 86400))
WHEN #PeriodType = 'PREV_DAY' THEN CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE(), 112)) - (1 / CONVERT(FLOAT, 86400))
WHEN #PeriodType = 'PREV_WEEK' THEN CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() - CONVERT(NUMERIC(8, 2), CONVERT(VARCHAR(23), GETDATE())), 112)) + 1 - (1 / CONVERT(FLOAT, 86400))
WHEN #PeriodType = 'PREV_2WEEK' THEN CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() + 1, 112)) - (1 / CONVERT(FLOAT, 86400))
WHEN #PeriodType = 'CUR_MONTH' THEN DATEADD(M, 1, CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE(), 112)) - (CONVERT(NUMERIC(8, 2), DATEPART(DD, GETDATE())) - 1)) - 1
WHEN #PeriodType = 'DATE_RANGE' THEN CONVERT(DATETIME, #ReportEnd) + 1
END AS "EndDate"
END
My stored proc is executing for PREV_DAY and PREV_2WEEK for the remaining period type I am getting conversions errors.
exec proc Dates 'PREV_DAY','',''
exec proc Dates 'PREV_2WEEK','',''
My PL\SQL code is
SELECT CASE
WHEN :PeriodType = 'CUR_WEEK'
THEN TRUNC(SYSDATE + 1 - TO_NUMBER(TO_CHAR(SYSDATE, 'D')))
WHEN :PeriodType = 'NEXT_WEEK'
THEN TRUNC(SYSDATE + 8 - TO_NUMBER(TO_CHAR(SYSDATE, 'D')))
WHEN :PeriodType = 'PREV_DAY'
THEN TRUNC(SYSDATE - 1)
WHEN :PeriodType = 'PREV_WEEK'
THEN TRUNC(SYSDATE - 6 - TO_NUMBER(TO_CHAR(SYSDATE, 'D')))
WHEN :PeriodType = 'PREV_2WEEK'
THEN TRUNC(SYSDATE - 13)
WHEN :PeriodType = 'CUR_MONTH'
THEN to_date(to_char(sysdate,'YYYYMM') || '01','YYYYMMDD')
WHEN :PeriodType = 'DATE_RANGE'
THEN TO_DATE(:ReportStart)
END AS "StartDate",
CASE
WHEN :PeriodType = 'CUR_WEEK'
THEN TRUNC(SYSDATE + 8 - TO_NUMBER(TO_CHAR(SYSDATE, 'D'))) - (1/86400)
WHEN :PeriodType = 'NEXT_WEEK'
THEN TRUNC(SYSDATE + 15 - TO_NUMBER(TO_CHAR(SYSDATE, 'D'))) - (1/86400)
WHEN :PeriodType = 'PREV_DAY'
THEN TRUNC(SYSDATE)-(1/86400)
WHEN :PeriodType = 'PREV_WEEK'
THEN TRUNC(SYSDATE - TO_NUMBER(TO_CHAR(SYSDATE, 'D'))) + 1 - (1/86400)
WHEN :PeriodType = 'PREV_2WEEK'
THEN TRUNC ( SYSDATE+1) - (1/86400)
WHEN :PeriodType = 'CUR_MONTH'
THEN ADD_MONTHS(TRUNC(SYSDATE) - (TO_NUMBER(TO_CHAR(SYSDATE,'DD')) - 1), 1) -1
WHEN :PeriodType = 'DATE_RANGE'
THEN TO_DATE(:ReportEnd)+1
END AS "EndDate"
FROM DUAL
At least one problem is this expression in the first then clause:
CONVERT(NUMERIC(8, 2), CONVERT(VARCHAR(23), GETDATE()))
This expression:
select CONVERT(VARCHAR(23), GETDATE())
just returned:
May 23 2014 3:01AM
And that just won't convert to numeric.
I think you need to go through the code line by line to figure out the best way to do things. Also, whenever you use varchar or char, you should have a length associated with them. The default is sometimes (but not always) 1, and that can cause problems.
Oracle and SQLServer work with datetime in different manner.
The tool converted the script as well as a string parser can, like someone translating a quote word by word between two languages.
In SQLServer to work with that data type you have to use the functions DATEADD, DATEDIFF and other ones that can be found on the help page from MS.
Using the date function of SQLServer the original function translate to
CREATE PROC Dates(
#PeriodType varchar(15),
#ReportStart varchar(15),
#ReportEnd varchar(15)
)
AS
BEGIN
SELECT CASE WHEN #PeriodType = 'CUR_WEEK' THEN DATEADD(DAY, - DATEPART(dw, GETDATE()) + 1, cast(cast(GETDATE() AS date) AS datetime))
WHEN #PeriodType = 'NEXT_WEEK' THEN DATEADD(DAY, 8 - DATEPART(dw, GETDATE()), cast(cast(GETDATE() AS date) AS datetime))
WHEN #PeriodType = 'PREV_DAY' THEN DATEADD(DAY, -1, cast(cast(GETDATE() AS date) AS datetime))
WHEN #PeriodType = 'PREV_WEEK' THEN DATEADD(DAY, - DATEPART(dw, GETDATE()) - 6, cast(cast(GETDATE() AS date) AS datetime))
WHEN #PeriodType = 'PREV_2WEEK' THEN DATEADD(DAY, - 13, cast(cast(GETDATE() AS date) AS datetime))
WHEN #PeriodType = 'CUR_MONTH' THEN DATEADD(DAY, - DATEPART(DAY, GETDATE()) + 1, cast(cast(GETDATE() AS date) AS datetime))
WHEN #PeriodType = 'DATE_RANGE' THEN CONVERT(DATETIME, #ReportStart)
END AS StartDate,
, CASE WHEN #PeriodType = 'CUR_WEEK' THEN DATEADD(mi, -1, DATEADD(DAY, 8 - DATEPART(dw, GETDATE()), cast(cast(GETDATE() AS date) AS datetime)))
WHEN #PeriodType = 'NEXT_WEEK' THEN DATEADD(mi, -1, DATEADD(DAY, 15 - DATEPART(dw, GETDATE()), cast(cast(GETDATE() AS date) AS datetime)))
WHEN #PeriodType = 'PREV_DAY' THEN DATEADD(mi, -1, DATEADD(DAY, - DATEPART(dw, GETDATE()) + 1, cast(cast(GETDATE() AS date) AS datetime)))
WHEN #PeriodType = 'PREV_WEEK' THEN DATEADD(mi, -1, DATEADD(DAY, 8 - DATEPART(dw, GETDATE()), cast(cast(GETDATE() AS date) AS datetime)))
WHEN #PeriodType = 'PREV_2WEEK' THEN DATEADD(mi, -1, cast(cast(dateadd(DAY, 1, GETDATE()) AS date) AS datetime))
WHEN #PeriodType = 'CUR_MONTH' THEN DATEADD(DAY, -1, DATEADD(mm, DATEDIFF(mm, 0, cast(cast(GETDATE() AS date) AS datetime))+1,0))
WHEN #PeriodType = 'DATE_RANGE' THEN CONVERT(DATETIME, #ReportEnd) + 1
END AS EndDate
END
The double CAST in CAST(CAST(GETDATE() AS DATE) AS DATETIME) is a little hack to get midnight of today, as GETDATE() is of datetime type and returns the current date and time.
Related
This is my query:
SELECT DISTINCT
'wk ' + TRIM(CONVERT(varchar(max), DATEADD(Week, DATEDIFF(week, 0, CONVERT(VARCHAR(max), period)), -1))) [week]
FROM
ABC
GROUP BY
TRIM(CONVERT(varchar(max), DATEADD(Week, DATEDIFF(week, 0, CONVERT(VARCHAR(max), period)), -1)))
I get a result like this: wk Aug 7 2022 12:00AM
But I want this format wk Aug 7, 2022
There was an error in the answer, it always returned january, the error is fixed now
You could build your string using the datepart function
declare #period datetime = '20220807' -- getdate()
SELECT 'wk ' +
left(datename(month, #period), 3) +
' ' + convert(varchar(2), datepart(day, #period)) +
' ,' + convert(varchar(4), datepart(year, #period))
looks like this wk Aug 7 ,2022
To convert your select clause to use this,
declare #table1 table (id int, period date)
insert into #table1 (id, period) values (1, '20220807'), (2, '20211130')
SELECT 'wk ' +
left(datename(month, dateadd( week, DATEDIFF( week, 0, CONVERT(VARCHAR(12), convert(date, period))), -1)), 3) +
' ' + convert(varchar(2), datepart(day, dateadd( week, DATEDIFF( week, 0, CONVERT(VARCHAR(12), convert(date, period))), -1))) +
' ,' + convert(varchar(4), datepart(year, dateadd( week, DATEDIFF( week, 0, CONVERT(VARCHAR(12), convert(date, period))), -1)))
from #table1
it looks like this
COLUMN1
wk Aug 7 ,2022
wk Nov 28 ,2021
I am trying to get the time difference between 2 times. I have a query which calculate the time in hours but what I want is to calculate in this (hh:mm) or (hh:mm:ss) format.
Is there any function or way I can achieve this ?
DECLARE #T TABLE
([EmpID] int, [TimeIn] datetime, [TimeOut] datetime);
INSERT INTO #T
([EmpID], [TimeIn], [TimeOut]) VALUES
(1, '2018-01-10 9:00:00', NULL),
(1, NULL, '2018-01-10 11:00'),
(1, '2018-01-10 11:30:00', NULL),
(1, NULL, '2018-01-10 13:00'),
(1, '2018-01-10 13:30:00', NULL),
(1, NULL, '2018-01-10 18:00'),
(1, '2018-01-11 9:00:00', NULL),
(1, NULL, '2018-01-11 11:00'),
(1, '2018-01-11 11:30:00', NULL),
(1, NULL, '2018-01-11 13:00'),
(1, '2018-01-11 13:30:00', NULL),
(1, NULL, '2018-01-11 18:33')
;
SELECT
FirstIN = CAST(MIN([AttendanceTimeIn]) AS TIME),
LastOUT = CAST(MAX([AttendanceTimeOut]) AS TIME),
HoursSpent = DATEDIFF(HOUR, CAST(MIN(AttendanceTimeIn) AS TIME), CAST(MAX(AttendanceTimeOut) AS TIME)),
CAST(COALESCE(AttendanceTimeIn, AttendanceTimeOut) AS DATE) [Date]
FROM #T
GROUP BY
CAST(COALESCE(AttendanceTimeIn, AttendanceTimeOut) AS DATE)
You can use this for With DATETIME
DECLARE #START_DATE datetime DECLARE #END_DATE datetime
-- Set the timeframe variables
SET #START_DATE = '2011-01-01 16:00:00' SET #END_DATE = '2011-01-01 22:47:22'
-- Use datediff to show the results in the
-- HH:MM:SS format
SELECT CONVERT(VARCHAR(6), datediff(second, #START_DATE, #END_DATE)/3600) + ':'
+ RIGHT('0' + CONVERT(VARCHAR(2), (datediff(second, #START_DATE, #END_DATE) %
3600) / 60), 2) + ':' + RIGHT('0' + CONVERT(VARCHAR(2), datediff(second,
#START_DATE, #END_DATE) % 60), 2)
Result :
HH:MM:SS
6:47:22
OR With TIME
-- Declare some variables for the requested timeframe
DECLARE #START_DATE TIME
DECLARE #END_DATE TIME-- Set the timeframe variables
SET #START_DATE = '16:00:00'
SET #END_DATE = '22:47:22'-- Use datediff to show the results in the
-- HH:MM:SS format
SELECT CONVERT(VARCHAR(6), Datediff(second, #START_DATE, #END_DATE)/3600)
+ ':'
+ RIGHT('0' + CONVERT(VARCHAR(2), (Datediff(second, #START_DATE,
#END_DATE) %
3600) / 60), 2)
+ ':'
+ RIGHT('0' + CONVERT(VARCHAR(2), Datediff(second, #START_DATE, #END_DATE
) % 60)
, 2) AS 'HH:MM:SS'
AS Per Edit
;
WITH cte
AS (SELECT EMPID,
Min(TIMEIN) timein,
Max(TIMEOUT) timeout,
Cast(COALESCE(TIMEIN, TIMEOUT) AS DATE) d
FROM #T
GROUP BY EMPID,
Cast(COALESCE(TIMEIN, TIMEOUT) AS DATE))
SELECT EMPID,
D AS Day,
CONVERT(VARCHAR(6), Datediff(second, TIMEIN, TIMEOUT)/3600)
+ ':'
+ RIGHT('0' + CONVERT(VARCHAR(2), (Datediff(second, TIMEIN, TIMEOUT) %
3600) /
60), 2)
+ ':'
+ RIGHT('0' + CONVERT(VARCHAR(2), Datediff(second, TIMEIN, TIMEOUT) % 60)
, 2 )
AS [Hours Worked]
FROM cte
ORDER BY D ASC
Result
empid Day Hours Worked
1 2018-01-10 9:00:00
1 2018-01-11 9:33:00
Resolve After Mistake of preiviuos senario
SELECT FirstIN, LastOUT,
CONVERT(VARCHAR(6), Datediff(second, FirstIN, LastOUT)/3600)
+ ':'
+ RIGHT('0' + CONVERT(VARCHAR(2), (Datediff(second, FirstIN, LastOUT) %
3600) /
60), 2)
+ ':'
+ RIGHT('0' + CONVERT(VARCHAR(2), Datediff(second, FirstIN, LastOUT) % 60)
, 2 ) AS
HoursSpent,[Date] FROM (
SELECT
FirstIN = CAST(MIN([TimeIn]) AS TIME),
LastOUT = CAST(MAX([TimeOut]) AS TIME),
HoursSpent = DATEDIFF(HOUR, CAST(MIN(TimeIn) AS TIME), CAST(MAX(TimeOut) AS TIME)),
CAST(COALESCE(TimeIn, TimeOut) AS DATE) [Date]
FROM #T
GROUP BY
CAST(COALESCE(TimeIn, TimeOut) AS DATE)) AS a
Check this snippet which returns difference at seconds level (HH:mm:ss)
SELECT CONVERT(time,
DATEADD(s,
DATEDIFF(s,
'2018-01-07 09:53:00',
'2018-01-07 11:53:01'),
CAST('1900-01-01 00:00:00.0000000' as datetime2)
)
)
If you need HH:mm only change 's' for 'mi'
And if you need difference in days too use this one:
SELECT CONVERT(datetime2,
DATEADD(s,
DATEDIFF(s,
'2018-01-07 09:53:00',
'2018-01-07 11:53:01'),
CAST('0001-01-01 00:00:00.0000000' as datetime2)
)
)
I have this query but I'm not sure what function to use so I can get time difference in this "hh:mm" format. Can anybody help ?
SELECT
EI.[FirstName]+' '+EI.[LastName] [EmployeeName], [Dpt].[FullName] [Department], [Desig].[FullName] [Designation],
FirstIN = CAST(MIN([AttendanceTimeIn]) AS TIME),
LastOUT = CAST(MAX([AttendanceTimeOut]) AS TIME),
HoursSpent = DATEDIFF(HOUR, CAST(MIN(AttendanceTimeIn) AS TIME), CAST(MAX(AttendanceTimeOut) AS TIME)),
CAST(COALESCE(AttendanceTimeIn, AttendanceTimeOut) AS DATE) [Date]
FROM [HRM].[tbl_Designation] [Desig], [HRM].[tbl_Department] [Dpt], [HRM].[tbl_EmployeeInfo] [EI]
FULL OUTER JOIN [HRM].[tbl_EmployeeAttendance] [Attendance] ON [Attendance].[EmpCode] = [EI].[ID]
WHERE
[Dpt].[ID] = [EI].[DeptCode] AND [Desig].[ID] = [EI].[DesignationCode]
AND
[EI].[RecordStatusCode] != '13'
AND
CAST((GETDATE()-1) AS DATE) = CAST(ISNULL([AttendanceTimeIn], [AttendanceTimeOut]) AS Date)
GROUP BY
EI.[FirstName]+' '+EI.[LastName], [Dpt].[FullName], [Desig].[FullName], CAST(COALESCE(AttendanceTimeIn, AttendanceTimeOut) AS DATE)
Maybe you can use something like this:
declare #d1 datetime = '2018-01-11 23:40:18.010'
declare #d2 datetime = '2018-01-12 11:59:18.010'
SELECT CONVERT(VARCHAR(2),DATEPART(HOUR,#d2 - #d1)) + ':' + CONVERT(VARCHAR(2),DATEPART(MINUTE,#d2 - #d1));
If to leave out your concept of using the time for the duration, you can use a query like below:
DECLARE #d1 DATETIME
DECLARE #d2 DATETIME
SELECT #d1 = GETDATE() - 1.465, #d2 = GETDATE()
SELECT
FirstIN = #d1,
LastOUT = #d2,
HoursSpent = CAST(DATEDIFF(HOUR, #d1, #d2) AS VARCHAR) + ':' + RIGHT('0' + CAST(DATEDIFF(MINUTE, #d1, #d2) % 60 AS VARCHAR), 2)
Let's expand step by step:
declare
#start datetime = getdate(),
#end datetime = dateadd(second, getdate(), 5000)
-- datediff(hour, #start, #end) -> hour difference
-- dateadd(hour, #start, datediff(hour, #start, #end)) -> start + integer hour difference to get less-than-an-hour diff
-- datediff(minute, dateadd(hour, #start, datediff(hour, #start, #end)), #end) -> minute difference from there
select
cast(datediff(hour, #start, #end) as varchar(2))
+ ':'
+ cast(datediff(minute, dateadd(hour, #start, datediff(hour, #start, #end)), #end) as varchar(2)) as [hh:mm]
I am trying to get the date difference in a given date excluding the week days.
Here is what I have:
SELECT DATEADD (w, -4, GETDATE())
This returns 2013-05-04 19:01:53.170, which means that it also counts weekends.
Same for
SELECT DATEADD (dw, -4, GETDATE())
Any help will be appreciated.
Thanks in advance.
I'm using these functions that return the non-weekend seconds between two dates:
CREATE FUNCTION [dbo].[DateDiff_NoWeekends](
#date1 DATETIME,
#date2 DATETIME
)
RETURNS INT AS BEGIN
DECLARE #retValue INT
SET #date1 = dbo.__CorrectDate(#date1, 1)
SET #date2 = dbo.__CorrectDate(#date2, 0)
IF (#date1 >= #date2)
SET #retValue = 0
ELSE BEGIN
DECLARE #days INT, #weekday INT
SET #days = DATEDIFF(d, #date1, #date2)
SET #weekday = DATEPART(dw, #date1) - 1
SET #retValue = DATEDIFF(s, #date1, #date2) - 2 * 24 * 3600 * ((#days + #weekday) / 7)
END
RETURN #retValue
END
GO
CREATE FUNCTION [dbo].[__CorrectDate](
#date DATETIME,
#forward INT
)
RETURNS DATETIME AS BEGIN
IF (DATEPART(dw, #date) > 5) BEGIN
IF (#forward = 1) BEGIN
SET #date = #date + (8 - DATEPART(dw, #date))
SET #date = DateAdd(Hour, (8 - DatePart(Hour, #date)), #date)
END ELSE BEGIN
SET #date = #date - (DATEPART(dw, #date)- 5)
SET #date = DateAdd(Hour, (18 - DatePart(Hour, #date)), #date)
END
SET #date = DateAdd(Minute, -DatePart(Minute, #date), #date)
SET #date = DateAdd(Second, -DatePart(Second, #date), #date)
END
RETURN #date
END
Here's a sql-fiddle demo for all non-weekend days in april (22).
SELECT [no weekend days in april] =
(dbo.DateDiff_NoWeekends('2013-04-01','2013-05-01')
/ 3600 / 24)
The query below gives the difference for week days alone , Ie counts the no od days between two days and subtracts the no of weekend days ,
DECLARE #StartDate DATETIME,
#EndDate DATETIME
SELECT #StartDate = '01-July-2008',
#EndDate = '30-July-2008'
;WITH DATE (Date1)
AS (
SELECT DATEADD(DAY, DATEDIFF(DAY, '19000101', #StartDate), '19000101')
UNION ALL
SELECT DATEADD(DAY, 1, Date1)
FROM DATE
WHERE Date1 < #EndDate
)
SELECT count(*) -
(
SELECT count(*)
--CONVERT(VARCHAR(15),d1.DATE1 ,110) as [Working Date],
--DATENAME(weekday, d1.Date1) [Working Day]
from DATE d1 where (DATENAME(weekday, d1.Date1)) in ('Saturday','Sunday')
)
--CONVERT(VARCHAR(15),d1.DATE1 ,110) as [Working Date],
--DATENAME(weekday, d1.Date1) [Working Day]
from DATE d1 where (DATENAME(weekday, d1.Date1)) not in ('Saturday','Sunday')
please let me know for any clarifications
Maybe I am still missing some full testing, but this works for me too: take the difference in days and then subtract 2 days for each weekend
DateDiff(d, d1, d2) - 2*DateDiff(wk, d1, d2)
Could be put in a function as well
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Get just the Date from grouping in select from DateTime column in SQL Server
How can I get only the Date part of a DateTime ? I'm searching for something like year() function but for the whole date.
This may also help:
SELECT convert(varchar, getdate(), 100) -- mon dd yyyy hh:mmAM (or PM)
-- Oct 2 2008 11:01AM
SELECT convert(varchar, getdate(), 101) -- mm/dd/yyyy - 10/02/2008
SELECT convert(varchar, getdate(), 102) -- yyyy.mm.dd – 2008.10.02
SELECT convert(varchar, getdate(), 103) -- dd/mm/yyyy
SELECT convert(varchar, getdate(), 104) -- dd.mm.yyyy
SELECT convert(varchar, getdate(), 105) -- dd-mm-yyyy
SELECT convert(varchar, getdate(), 106) -- dd mon yyyy
SELECT convert(varchar, getdate(), 107) -- mon dd, yyyy
SELECT convert(varchar, getdate(), 108) -- hh:mm:ss
SELECT convert(varchar, getdate(), 109) -- mon dd yyyy hh:mm:ss:mmmAM (or PM)
-- Oct 2 2008 11:02:44:013AM
SELECT convert(varchar, getdate(), 110) -- mm-dd-yyyy
SELECT convert(varchar, getdate(), 111) -- yyyy/mm/dd
SELECT convert(varchar, getdate(), 112) -- yyyymmdd
SELECT convert(varchar, getdate(), 113) -- dd mon yyyy hh:mm:ss:mmm
-- 02 Oct 2008 11:02:07:577
SELECT convert(varchar, getdate(), 114) -- hh:mm:ss:mmm(24h)
SELECT convert(varchar, getdate(), 120) -- yyyy-mm-dd hh:mm:ss(24h)
SELECT convert(varchar, getdate(), 121) -- yyyy-mm-dd hh:mm:ss.mmm
SELECT convert(varchar, getdate(), 126) -- yyyy-mm-ddThh:mm:ss.mmm
-- 2008-10-02T10:52:47.513
-- SQL create different date styles with t-sql string functions
SELECT replace(convert(varchar, getdate(), 111), '/', ' ') -- yyyy mm dd
SELECT convert(varchar(7), getdate(), 126) -- yyyy-mm
SELECT right(convert(varchar, getdate(), 106), 8) -- mon yyyy
The Source
The solution you want is the one proposed here:
https://stackoverflow.com/a/542802/50776
Basically, you do this:
cast(floor(cast(#dateVariable as float)) as datetime)
There is a function definition in the link which will allow you to consolidate the functionality and call it anywhere (instead of having to remember it) if you wish.
Another nifty way is:
DATEADD(dd, 0, DATEDIFF(dd, 0, [YourDate]))
Which gets the number of days from DAY 0 to YourDate and the adds it to DAY 0 to set the baseline again. This method (or "derivatives" hereof) can be used for a bunch of other date manipulation.
Edit - other date calculations:
First Day of Month:
DATEADD(mm, DATEDIFF(mm, 0, getdate()), 0)
First Day of the Year:
DATEADD(yy, DATEDIFF(yy, 0, getdate()), 0)
First Day of the Quarter:
DATEADD(qq, DATEDIFF(qq, 0, getdate()), 0)
Last Day of Prior Month:
DATEADD(ms, -3, DATEADD(mm, DATEDIFF(mm, 0, getdate()), 0))
Last Day of Current Month:
DATEADD(ms, -3, DATEADD(mm, DATEDIFF(m, 0, getdate()) + 1, 0))
Last Day of Current Year:
DATEADD(ms, -3, DATEADD(yy, DATEDIFF(yy, 0, getdate()) + 1, 0))
First Monday of the Month:
DATEADD(wk, DATEDIFF(wk, 0, DATEADD(dd, 6 - DATEPART(day, getdate()), getdate())), 0)
Edit:
True, Joe, it does not add it to DAY 0, it adds 0 (days) to the number of days which basically just converts it back to a datetime.
We can use this method:
CONVERT(VARCHAR(10), GETDATE(), 120)
Last parameter changes the format to only to get time or date in specific formats.
This may not be as slick as a one-liner, but I use it to perform date manipulation mainly for reports:
DECLARE #Date datetime
SET #Date = GETDATE()
-- Set all time components to zero
SET #Date = DATEADD(ms, -DATEPART(ms, #Date), #Date) -- milliseconds = 0
SET #Date = DATEADD(ss, -DATEPART(ss, #Date), #Date) -- seconds = 0
SET #Date = DATEADD(mi, -DATEPART(mi, #Date), #Date) -- minutes = 0
SET #Date = DATEADD(hh, -DATEPART(hh, #Date), #Date) -- hours = 0
-- Extra manipulation for month and year
SET #Date = DATEADD(dd, -DATEPART(dd, #Date) + 1, #Date) -- day = 1
SET #Date = DATEADD(mm, -DATEPART(mm, #Date) + 1, #Date) -- month = 1
I use this to get hourly, daily, monthly, and yearly dates used for reporting and performance indicators, etc.