Convert a string to date in SQL Server - sql

I am facing a problem where I need to convert a string to date like
11 years 10 months 12 days to a date in SQL Server.
Please help any help would be appreciated.

I guess you want something like this
DECLARE #str VARCHAR(50)= '1 year 12 months 2 days'
DECLARE #days INT= LEFT(#str, Charindex(' ', #str)),
#months INT = Substring(#str, Charindex('months', #str) - 3, 2),
#years INT = Substring(#str, Charindex('days', #str) - 3, 2);
WITH days_back
AS (SELECT Dateadd(day, -#days, Cast(Getdate() AS DATE)) AS day_date),
month_back
AS (SELECT Dateadd(month, -#months, day_date) AS month_date
FROM days_back)
SELECT Result = Dateadd(year, -#years, month_date)
FROM month_back

declare #fuzzy_date varchar(255) = '11 years 10 months 12 days'
declare #date date
declare #startdate date = '1999-12-31'
declare #today_to_before date = getdate()
declare #today_to_after date = getdate()
declare #years int, #months int, #days int, #foo varchar(255)
Set #years = left(#fuzzy_date, charindex('years', #fuzzy_date) - 1)
Select #fuzzy_date = right(#fuzzy_date, len(#fuzzy_date) - charindex('years', #fuzzy_date) - 5)
select #months = left(#fuzzy_date, charindex('months', #fuzzy_date) - 1)
Select #days = replace(right(#fuzzy_date, len(#fuzzy_date) - charindex('months', #fuzzy_date) - 6), 'days', '')
Select #years, #months, #days
Set #date = dateadd(yy, #years, #startdate)
Set #date = dateadd(mm, #months, #date)
Set #date = dateadd(dd, #days, #date)
Set #today_to_after = dateadd(yy, #years, #today_to_after)
Set #today_to_after = dateadd(mm, #months, #today_to_after)
Set #today_to_after = dateadd(dd, #days, #today_to_after)
Set #today_to_before = dateadd(yy, -#years, #today_to_before)
Set #today_to_before = dateadd(mm, -#months, #today_to_before)
Set #today_to_before = dateadd(dd, -#days, #today_to_before)
Select #date,#today_to_after,#today_to_before

Related

Calculate age on integer field

The date field I have to calculate age on is yyyymmdd.
I've tried below and converted getdate to yyyymmdd format but can't seem to get the age from that. I've tried with datediff but can't seem to get it to work either.
SELECT CLAIM.BTHDAT
, (CONVERT(VARCHAR(8),GETDATE(), 112) - CLAIM.BTHDAT)/365.25
FROM CLAIM
Assuming you want AGE in YEARS... How about datediff()
Select Age = datediff(YEAR,left(CLAIM.BTHDAT,8),getdate())
From CLAIM
try this....
SELECT CLAIM.BTHDAT, DATEDIFF(hour,CLAIM.BTHDAT,GETDATE())/8766.0 AS AgeYearsDecimal
,CONVERT(int,ROUND(DATEDIFF(hour,CLAIM.BTHDAT,GETDATE())/8766.0,0)) AS AgeYearsIntRound
,DATEDIFF(hour,CLAIM.BTHDAT,GETDATE())/8766 AS AgeYearsIntTrunc FROM CLAIM
If you want to Age in Day,Month & year then you can try this.Create Function to Calcuate Age and call it in Query like this
Create function [dbo].[GetAge](#dayOfBirth datetime, #today datetime)
RETURNS varchar(100)
AS
Begin
DECLARE #tmpdate datetime, #date datetime, #years int, #months int, #days int
SELECT #tmpdate = #dayOfBirth
SELECT #years = DATEDIFF(yy, #tmpdate, #today) - CASE WHEN (MONTH(#tmpdate) > MONTH(#today)) OR (MONTH(#tmpdate) = MONTH(#today) AND DAY(#tmpdate) > DAY(#today)) THEN 1 ELSE 0 END
SELECT #tmpdate = DATEADD(yy, #years, #tmpdate)
SELECT #months = DATEDIFF(m, #tmpdate, #today) - CASE WHEN DAY(#tmpdate) > DAY(#today) THEN 1 ELSE 0 END
SELECT #tmpdate = DATEADD(m, #months, #tmpdate)
SELECT #days = DATEDIFF(d, #tmpdate, #today)
return cast(#years as varchar(2)) + ' years,' + cast(#months as varchar(2)) + ' months,' + cast(#days as varchar(3)) + ' days'
end
Select CLAIM.BTHDAT,dbo.[GetAge](CLAIM.BTHDAT,getdate()) From CLAIM
Here's an option to get the age accurately, with the assumption that all dates will follow the yyyymmdd format and will be valid dates.
SELECT CLAIM.BTHDAT
,DATEDIFF( YY, CONVERT(CHAR(8),CLAIM.BTHDAT), GETDATE())
- CASE WHEN SUBSTRING( CONVERT( char(8), GETDATE(), 112), 5, 4) < SUBSTRING( CONVERT( char(8), BTHDAT), 5, 4) THEN 1 ELSE 0 END
FROM CLAIM

An SQL query to show the last BUSINESS day of the month

Here is my query:
CREATE FUNCTION dbo.ufn_LastBusinessDayOfMonth (#Dt datetime)
RETURNS datetime
AS
BEGIN
DECLARE #dt2 datetime
DECLARE #Df int
DECLARE #dSat int
DECLARE #dSun int
SELECT
#dt2 = DATEADD(D, -1, DATEADD(m, 1 + DATEDIFF(m, 0, #Dt), 0))
SELECT
#dSat = DATEPART(dw, '2018-01-06') -- Known Saturday
SELECT
#dSun = (#dSat % 7) + 1
SELECT
#dt2 = (
CASE
WHEN DATEPART(dw, #dt2) = #dSun THEN DATEADD(DAY, -2, #dt2)
WHEN DATEPART(dw, #dt2) = #dSat THEN DATEADD(DAY, -1, #dt2)
ELSE #dt2
END)
RETURN #dt2
END
DECLARE #Dt datetime
SET #Dt = '03/21/2018'
DECLARE #lastOfMonth datetime, #3DaysBeforeTheEnd DATETIME
set #lastOfMonth = DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#Dt)+1,0))
SET #3DaysBeforeTheEnd = DATEADD(d,-2,#lastOfMonth)
select top 1 DATENAME(weekday, x.[Date]), x.[Date]
from (
SELECT TOP (DATEDIFF(DAY, #3DaysBeforeTheEnd, #lastOfMonth) + 1)
[Date] = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, #3DaysBeforeTheEnd)
FROM sys.all_objects a
CROSS JOIN sys.all_objects b
)x
WHERE DATENAME(weekday, x.[Date]) NOT IN ('Saturday','sunday')
order by x.[Date] desc

SQL Server : get date with inparameters year,week,weekday

I have searched and have yet to find this little helpful snippet.
I want to input...
Year (2014)
Weeknumber (2)
Weekday (2 = Tuesday, in my case)
Expected result: 2014-01-07 (seventh of January)
And get the full date in return, anyone?
EDIT: My server is SQL 2008
The finished code thanks to all!.
declare #year int = 2014
declare #weeknr int = 2
declare #daynroffset int = 2
SELECT
DATEADD(DAY,+ (#daynroffset-1),
DATEADD(DAY,-DATEPART(DW,CAST('1/1/' + cast(#year as varchar) AS Date))+2,DATEADD(WK,#weeknr- 1,CAST('1/1/' + cast(#year as varchar) AS Date)))
)
The other answers (so far) use SQL Server default mechanisms to determine week and day of week. In this case the current language setting determines the day of the week (through the ##DATEFIRST setting) and the DATEPART(wk uses Jan 1st as the fixed date contained in week 1.
To get a deterministic answer independent of the language setting one can use the ISO 8601 week standard which starts a week on Mondays and where the first week always contains Jan 4th.
This code determines the date based on ISO weeks:
declare #year int = 2016
declare #isoweek int = 22
declare #isoday int = 2
-- ISO-WEEK 1 always contains 4th Jan, so let's use this as a base
declare #date datetime = cast(cast(#year as varchar(4)) + '-01-04T12:00:00' as datetime)
-- Offset the wanted DayOfWeek versus our base date
-- We also set DATEFIRST temporarily because it affects DayOfWeek
-- ISO-Weeks always start on Monday
declare #datefirst int = ##DATEFIRST
SET DATEFIRST 1
declare #offset int = datepart(dw, #date) - 1
SET DATEFIRST #datefirst
-- Add given day and week to basedate
set #date = dateadd(day, #isoday - 1 - #offset, dateadd(wk, #isoweek - 1, #date))
print #date
CODE:
2012+:
DATEADD(DAY,-DATEPART(DW,DATEFROMPARTS("YEAR",1,1))+1+"DAY OF WEEK",DATEADD(WK,"WEEK NUMBER"-1,DATEFROMPARTS(2014,1,1)))
2008+:
SELECT DATEADD(DAY,-DATEPART(DW,CAST(CONCAT('1/1/',"YEAR") AS Date))+1+"DAY OF WEEK",DATEADD(WK,"WEEK NUMBER"-1,CAST(CONCAT('1/1/',"YEAR") AS Date)))
Simply substitue the values where necessary.
This will work for any date.
declare #year int = 2014
declare #week int = 2
declare #day int = 2
declare #date datetime = cast(cast(#year as varchar(20)) + '-01-01' as datetime)
declare #offset int = datepart(dw, #date) - 1
set #date = dateadd(day, #day - #offset, dateadd(ww, #week - 1, #date))
print #date
This may have issues near the year boundary, but it works for the example data given. You may want to add further validations. I've broken down each step of the datetime manipulation into a new field, so you can see it being constructed
2008
DECLARE #Year INT = 2014
DECLARE #WeekNum INT = 2
DECLARE #WeekDay INT = 2
SELECT
BaseDate = CAST( #year AS VARCHAR(4) )
, RoundToWeekStart = DATEADD(WEEK, DATEDIFF(WEEK, 0, CAST( #year AS VARCHAR(4) )), 0) -- Will be a Monday
, AddWeeksToRoundedDate = DATEADD(WEEK, #WeekNum - 1, DATEADD(WEEK, DATEDIFF(WEEK, 0, CAST( #year AS VARCHAR(4) )), 0) )
, AddWeekDay = DATEADD( DAY, #WeekDay - 1, DATEADD(WEEK, #WeekNum - 1, DATEADD(WEEK, DATEDIFF(WEEK, 0, CAST( #year AS VARCHAR(4) )), 0) ) )
2012+
DECLARE #Year INT = 2014
DECLARE #WeekNum INT = 2
DECLARE #WeekDay INT = 2
SELECT
BaseDate = DATEFROMPARTS(#Year, 1, 1)
, RoundToWeekStart = DATEADD(WEEK, DATEDIFF(WEEK, 0, DATEFROMPARTS(#Year, 1, 1)), 0) -- Will be a Monday
, AddWeeksToRoundedDate = DATEADD(WEEK, #WeekNum - 1, DATEADD(WEEK, DATEDIFF(WEEK, 0, DATEFROMPARTS(#Year, 1, 1)), 0) )
, AddWeekDay = DATEADD( DAY, #WeekDay - 1, DATEADD(WEEK, #WeekNum - 1, DATEADD(WEEK, DATEDIFF(WEEK, 0, DATEFROMPARTS(#Year, 1, 1)), 0) ) )

How to get full date from the given month and year in SQL SERVER?

I have following script where I need to get the full date
DECLARE #BeginDate DateTime
DECLARE #EndDate DateTime
Declare #month int
Declare #year int
set #month = 6
set #year = 2014
Select beginDate = CAST(#month AS VARCHAR(10)) + '/01/' + CAST(#year AS VARCHAR(10))
SELECT endDate = DATEADD(d, -1, DATEADD(m, DATEDIFF(m, 0, #beginDate) + 1, 0))
This script returns endDate as null. How do I get full endDate by passing only Date (not time)?
I think you forgot to put # sign in front of the variables. If you change the last two lines with the following:
Select #beginDate = CAST(#month AS VARCHAR(10)) + '/01/' + CAST(#year AS VARCHAR(10))
SELECT #endDate = DATEADD(d, -1, DATEADD(m, DATEDIFF(m, 0, #beginDate) + 1, 0))
it should work. By putting "select #enddate" at the end, I got 2014-06-30 00:00:00.000 .
Well I found it.
DECLARE #BeginDate DateTime
DECLARE #EndDate DateTime
Declare #month int
Declare #year int
set #month = 7
set #year = 2014
Select #beginDate = CAST(#month AS VARCHAR(10)) + '/01/' + CAST(#year AS VARCHAR(10))
SELECT endDate = DATEADD(d, -DAY(DATEADD(mm, 1, #beginDate)), DATEADD(m, 1, #BeginDate))
source

How can i find the particular days

I have the date value like this - 12/2011 or 11/2011 (MM/yyyy)
I want to find the sundays on the particular month....
For Example, If i select the month 01/2012, The query should give the result like this
01
08
15
22
29
The above date are sunday.
Expected Output for 01/2012 Month
01
08
15
22
29
How to make a query
Need Query Help
With a little help of a number table (master..spt_values)
declare #M varchar(7)
set #M = '01/2012'
declare #D datetime
set #D = convert(datetime, '01/'+#M, 103)
set datefirst 7
select dateadd(day, N.Number, #D)
from master..spt_values as N
where N.type = 'P' and
dateadd(day, N.Number, #D) >= #D and
dateadd(day, N.Number, #D) < dateadd(month, 1, #D) and
datepart(weekday, dateadd(day, N.Number, #D)) = 1
Here it comes:
SET DATEFIRST 1
DECLARE #givenMonth CHAR(7)
SET #givenMonth = '12/2011'
DECLARE #month INT
SET #month = CAST(SUBSTRING(#givenMonth, 1, 2) AS INT)
DECLARE #year INT
SET #year = CAST(SUBSTRING(#givenMonth, 4, 4) AS INT)
DECLARE #Date DATETIME
SET #Date = DATEADD(month, #month - 1, CAST(CAST(#year AS CHAR(4)) AS DATETIME))
DECLARE #nextMonth DATETIME
SET #nextMonth = DATEADD(MONTH, 1, #date)
DECLARE #firstSunday DATETIME
SET #firstSunday = DATEADD(day, 7 - DATEPART(weekday, #date), #date)
CREATE TABLE #Days(Sunday INT)
WHILE #firstSunday < #nextMonth
BEGIN
INSERT #Days
SELECT DATEPART(DAY, #firstSunday) Sunday
SET #firstSunday = DATEADD(day, 7, #firstSunday)
END
SELECT Sunday
FROM #Days
ORDER BY 1
DROP TABLE #Days
Edit: use a numbers table in place of the CTE because you are in SQL Server 2000. C'mon, upgrade and do yourself a favour
DECLARE #monthyear varchar(10) = '11/2012';
DECLARE #start smalldatetime, #end smalldatetime;
-- use yyyymmdd format
SET #start = CAST(RIGHT(#monthyear, 4)+ LEFT(#monthyear, 2) + '01' AS smalldatetime);
-- work backwards from start of next month
SET #end = DATEADD(day, -1, DATEADD(month, 1, #start));
-- recursive CTE. Would be easier with a numbers table
;WITH daycte AS
(
SELECT #start AS TheDay
UNION ALL
SELECT DATEADD(day, 1, TheDay)
FROM daycte
WHERE TheDay < #end
)
SELECT DATENAME(day, TheDay)
FROM daycte
-- One of many ways.
-- This is independent of ##datefirst but fails with Chinese and Japanese language settings
WHERE DATENAME(weekday, TheDay) = 'Sunday';
You can change date format and use DateName function.
SELECT DateName(dw, GETDATE())