Convert character string to date in TSQL - sql-server-2008

I need to convert character string to date format to fetch the first and last day of the month.
Input.
DECLARE #InpDat AS VARCHAR(20)
SET #InpDat = 201308
Expected output 2013-08-31
I need to get the first and last day of the given yearmonth. Can you please help me to get that.
I tried with the convert option but couldnt get it. ?

Use CAST(#InpDat + '01' AS DATE) to convert it to a date and DateAdd for the date arithmetic.
DECLARE #InpDat AS VARCHAR(20) SET #InpDat = '201308'
DECLARE #Month DATE SET #Month = CAST(#InpDat + '01' AS DATE)
SELECT #MONTH AS First,
DATEADD(day, -1, DATEADD(month, 1, #MONTH)) AS Last
DEMO

DECLARE #InpDat AS VARCHAR(20)
SET #InpDat = '201308'
SELECT CONVERT(DATETIME(#InpDat+'01') AS FirstDate,
DATEADD(dd,-1,DATEADD(mm,1,CONVERT(DATETIME(#InpDat+'01'))) AS LastDate

Why do you expect that a random number will convert to a date format without any cajoling? The database is a powerful tool but not magical.
You have to parse the number into a date, then format the date the way you like. I might suggest this sequence of calls:
-- assume you can separate the year and month into separate parts.
-- use 01 as default day for now, we'll get last day shortly.
DECLARE #IntermediateDate AS DATE SET #IntermediateDate = DATEFROMPARTS(2013,08,01)
-- Advance the month by one, and subtract one day to find the last day of the month.
SET #IntermediateDate = DATEADD( dd, -1, DATEADD( mm, 1, #IntermediateDate))
Now format using your favorite formatting functions.

Related

Total Number of days of a Month

I need to write a query which returns No. of days of a Month.
Please understand that I cannot use DATE, and any query having DATE will not work.
I have created a parameter which takes int value. Like January is 1, February is 2 etc.
From the values 1 or 2, I wanted to get the number of days like the number of days of 1 should be 31 and 2 should be 28 or 29.
I am using Ms sql-server-2008.
Help is required.
Regards,
So, you can always build a date using date parts. You may want to validate the input and transform this logic to your needs.
DECLARE #year SMALLINT = 2017;
DECLARE #month TINYINT = 2;
DECLARE #dateFrom DATE = CONVERT(DATE,
CONVERT(CHAR(4), #year) + '-'
+ RIGHT('00' + CONVERT(VARCHAR(2), #month), 2)
+ '-01'
);
DECLARE #dateTo DATE = DATEADD(MONTH, 1, #dateFrom);
SELECT DATEDIFF(DAY, #dateFrom, #dateTo);
-- OR --
If you are really keen to not use any calculation, just a query, store these values in a table and query that table using the input values.

Given datetime, filter results by month of that datetime

For sql server 2008: what is the best way to filter results, to return only results that are in the same month as a certain date?
The best I could come up with is the following:
-- set up test data
DECLARE #TABLE1 AS TABLE (
ID INT,
STRING VARCHAR(MAX),
DATECOLUMN DATETIME
)
INSERT INTO #TABLE1
SELECT
0 ID,
'TABLE1 0' STRING,
CONVERT(DATETIME, '2016-10-13 12:45:00', 102) DATECOLUMN
UNION ALL SELECT 1, 'TABLE1 1', CONVERT(DATETIME, '2016-9-13 12:45:00', 102)
UNION ALL SELECT 2, 'TABLE1 2', CONVERT(DATETIME, '2016-10-1 00:00:00', 102)
UNION ALL SELECT 3, 'TABLE1 3', CONVERT(DATETIME, '2016-10-31 23:59:59', 102)
-- set up constraint
DECLARE #SOMEDATE DATETIME = CONVERT(DATETIME, '2016-10-13 12:45:00', 102)
-- filter
SELECT * FROM #TABLE1
WHERE MONTH(DATECOLUMN) = MONTH(#SOMEDATE)
Is this the best way?
Your query will return records where the month of DateColumn matches the month of #SomeDate, although (as #Jayvee points out) this would be true regardless of the year. So if that's what you want, your solution is fine.
But you asked whether that was the best solution. I would say no, because this won't take advantage of any index you may have that includes DateColumn.
So this is what I would do, if I were on SQL Server 2008:
declare #someDate datetime = GetDate()
declare #startDate date
declare #endDate date
-- I want the first day of the month, at 12:00:00AM (no time component).
-- The DateAdd expression subtracts days, and converting to the Date data type
-- ensures that I don't have a time component hanging around.
set #startDate = convert(date, DateAdd(day,- DatePart(day, #someDate) + 1, #someDate))
-- I want the first day of the next month. This is easy:
set #endDate = DateAdd(month, 1, #startDate)
-- Here's my actual query, that can take advantage of indexes that include DateColumn:
select *
from Table1
where DateColumn >= #startDate and DateColumn < #endDate
Note that I said >= for start date but < for the end date. That ensures that I'll pick up any date entries for the last day of the month that have a non-zero time component, but won't go into the next month.
The best way for a long-term solution is to create a date dimension table (you can find scripts out there to auto-generate one). The date dim table will just contain a list of dates as far back and forward as you care to go, and it includes columns like DayOfWeek, QuarterOfYear, YYYYMM, etc., so you can join CAST(YOURDATE AS DATE) to the date dim's date and pull nifty date info. Here you can join both of your tables to the date dim and use WHERE t1.YYYYMM = t2.YYYYMM.

Date difference in Hours format from bigint in SQL Server

I have a column of bigint type containing date & time information (like 1353056515, 1353067040, 1360839600 etc.)
My requirement is to get time difference in HOURS format between column which I mentioned above and current datetime.
I tried to find the solution, but those were so confusing. I'm new to SQL Server.
Please help.
Please try this.
declare #mydate datetime
DECLARE #LocalTimeOffset BIGINT
,#AdjustedLocalDatetime BIGINT
SET #LocalTimeOffset = DATEDIFF(second,GETDATE(),GETUTCDATE())
SET #AdjustedLocalDatetime = 1416474000 - #LocalTimeOffset
SELECT DATEADD(second,#AdjustedLocalDatetime, CAST('1970-01-01 00:00:00' AS datetime))
-- It will give you date 2014-11-20 14:30:00.000
The data difference operation:
select DATEDIFF(hour,#mydate,GETDATE())
or
Create Function
create FUNCTION dbo.fn_ConvertToDateTime (#Datetime BIGINT)
RETURNS DATETIME
AS
BEGIN
DECLARE #mydate datetime
DECLARE #LocalTimeOffset BIGINT
,#AdjustedLocalDatetime BIGINT
SET #LocalTimeOffset = DATEDIFF(second,GETDATE(),GETUTCDATE())
SET #AdjustedLocalDatetime = #Datetime - #LocalTimeOffset
SELECT #mydate=DATEADD(second,#AdjustedLocalDatetime, CAST('1970-01-01 00:00:00' AS datetime))
return #mydate
END;
GO
select mydate= dbo.fn_ConvertToDateTime (1416474000)
select DATEDIFF(hour,#mydate,GETDATE())
Hope that helps.
The number looks like a UNIX timestamp, which is the number of seconds since 1/1/1970 00:00:00 UTC. You can get the UNIX timestamp from a datetime with a simple DATEDIFF:
declare #date datetime='2014-11-20T10:00:00'
declare #epoch datetime='19700101'
select DATEDIFF(s,#epoch,#date)
To get the number of hours between two timestamps you simply need to divide the difference by 3600 (the number of seconds in an hour). You don't need to convert the timestamps to dates before calculating the difference :
declare #dateTS int=DATEDIFF(s,#epoch,#date)
declare #nowTS int=DATEDIFF(s,#epoch,GETUTCDATE())
select (#nowTS-#dateTS)/3600.0
Note that I used 3600.0 to get a decimal result. If 3600 is used the fractional part will be truncated and you'll get 0 for differences less than 1 hour. This is OK if you want to return whole hours.
In a query you could write something like this:
select (DATEDIFF(s,#epoch,GETUTCDATE())-[MY_TS_COLUMN])/3600.0 AS Hours
from [MY_TABLE]

SQL server 2008, datediff returns wrong value

I have two columns of Data type time. I'm using datediff to find the difference in hours.
The problem is when I try to find the difference between 00:00:00 to 06:00:00, it returns -18.
How can I fix it?
note: I need to calculate more difference with this so I can't just divide it with -3
my function- (datediff(HOUR, startHour, endHour))*60
Thanks in advance
You are not comparing 00:00:00 to 06:00:00. You have some date component
This gives -18 as an example
DECLARE #starthour datetime = '00:00:00';
DECLARE #endhour datetime = '18991231 06:00:00';
SELECT #starthour, #endhour, DATEDIFF(hour, #starthour, #endhour);
SET #starthour = '20120507 00:00:00';
SET #endhour = '20120506 06:00:00';
SELECT #starthour, #endhour, DATEDIFF(hour, #starthour, #endhour);
Reverse the parameters:
my function- (datediff(HOUR, endHour, startHour))*60
Edit:
The function DATEDIFF works with dates and for some reason, it thinks you're subtracting 6AM - Midnight (next day), which is 18 hours.
The following code sample works fine for me in SQL 2008, so you need to check your data type to make sure you're using TIME and not DATETIME or SMALLDATETIME.
declare #t1 time
set #t1 = '00:00:00'
declare #t2 time
set #t2 = '06:00:00'
select datediff(hour, #t1, #t2)
-- returns 6
Syntax:
DATEDIFF (datepart, startdate, enddate )
Examples:
SELECT DATEDIFF(hour, '00:00:00', '06:00:00');
Result: 6
SELECT DATEDIFF(hour, '00:00:00', '06:00:00')*60;
Result: 360
Refer DATEDIFF (Transact-SQL)
I'm late to the game, but I faced a similar problem.
DATEDIFF(HOUR,'23:00:00','06:00:00')
Result: -17
Reversing the two times (as suggested by another answer above) does not represent the time frame I want to capture. I don't want to know how many hours are between 6am and 11pm. I want 11pm to 6am.
To resolve this, wrap the DATEDIFF() in a CASE statement and add 24 when the start time is greater than the end time:
DECLARE #startTime TIME(0) = '23:00:00';
DECLARE #endTime TIME(0) = '06:00:00';
SELECT CASE WHEN #startTime > #endTime THEN 24 + DATEDIFF(HOUR,#startTime,#endTime) ELSE DATEDIFF(HOUR,#startTime,#endTime) END
Result: 7

How to use DATENAME in WHERE clause

Am using Sql Server 2008, I have a column named Date in my table, and I want to get the datas for the particular date.... I need to give this Date in my WHERE condition.
for example, if I want to get the records for the particular month in the given date, how can I use this Date in WHERE condition.
DATANAME(MONTH,'#Date')
if I give like this in my query I can get the month from the given DATE, the same way I tried by putting in WHERE condition like,
WHERE DATE= DATANAME(MONTH,'#Date')
here it reports conversion error...how can I display the datas for a particular month, can anyone help me
If you want a month of data for a table you should check against an interval. The query is not able to use indexes on the date column if you are applying functions on the column.
Use something like this to get data for April 2012.
-- The date parameter
declare #Date datetime
set #Date = '2012-04-11'
declare #FromDate datetime
declare #ToDate datetime
-- set FromFate to first of april
set #FromDate = dateadd(month, datediff(month, 0, #Date), 0)
-- set ToDate to first of may
set #ToDate = dateadd(month, 1+datediff(month, 0, #Date), 0)
select *
from YourTable
where [Date] >= #FromDate and [Date] < #ToDate
If you want to show data for a particular year and month you can use the YEAR and MONTH functions:
SELECT ...
FROM ...
WHERE YEAR(mydate) = 2012 AND MONTH(mydate) = 3 -- March, 2012
To me it seems that your field Date is not of type varchar or nvarchar, so using a condition where a Datetime = string is obviously wrong.
Have you tried
WHERE DATE= #Date
Shouldn't it be:
DATENAME(MONTH, #Date)
Instead of:
DATANAME(MONTH,'#Date')
(Notice "DATA" vs "DATE" and #Date isn't in quotations)
Then to use this against a date/datetime column you would have to cast both sides like below:
WHERE datename(Month, [Date]) = datename(Month, [Date])
Warning: The above does not use any indexes so isn't as efficient as "WHERE Date = Date"
First: Remove '' from variable. #Date, not '#Date'
If you want to find dates from specific month. (You have to remember about year condition also)
WHERE DATANAME(MONTH, #Date) = 'April'
if you want to find exact date:
WHERE DATE = #date