February 16, 2006 at 4:36 am
Hey, I'm looking for t-sql that can take two dates and determine how many mondays are between them?
February 16, 2006 at 4:57 am
I think this will give the number of Mondays between the two dates (both inclusive). 20060213 can be replaced by any Monday...
select (datediff(d, '20060213', @Date2) + 1)/7 - datediff(d, '20060213', @Date1)/7
February 16, 2006 at 5:17 am
This is an interesting start, but not quite what I'm looking for. In this solution you have to know the first Monday for any calculation. I'm looking to take to dates and then calculate the number of mondays between them without having to know the first Monday in T-SQL, if possible.
February 16, 2006 at 5:23 am
I don't quite understand what you're saying. As an example, to calculate the number of Mondays in the year 2000, do as follows:
select (datediff(d, '20060213', '20001231') + 1)/7 - datediff(d, '20060213', '20000101')/7
Could you give an example where my method returns something wrong?
February 16, 2006 at 5:40 am
Hey, I appreciate your feedback. I'm not saying that your solution is wrong. What I'm looking for is a formula that would be inside a stored procedure. Another stored procedure will be calling it and all this stored procedure would know would be the start date and the end date. From that, I'd like to calculate the number of Mondays between the two dates.
Taffy
February 16, 2006 at 5:47 am
Something like this?
create proc countMondays
(
@FromDate datetime,
@ToDate datetime,
@NumberOfMondays int output
)
as
select @NumberOfMondays = (datediff(d, '20060213', @ToDate) + 1)/7 - datediff(d, '20060213', @FromDate)/7
go
declare @count int
exec countMondays '20000101', '20001231', @count output
select @count
February 16, 2006 at 6:28 am
For this i have created a function in which you have to pass two date from to to date
and it will calculate the no.of mondays in the given two dates
Create Function Monday(@dt1 datetime,@dt2 datetime) returns int
as
Begin
Declare @cnt int,@dt as datetime
set @cnt=0
if @dt1 < @dt2
Begin
set @dt=@dt1
Begin
if Datepart(dw,@dt)=1
Begin
set @cnt=@cnt+1
set @dt=dateadd(dd,1,@dt)
End
set @dt=dateadd(dd,1,@dt)
End
End
if @cnt=0
Begin
return 0
End
Return @cnt
End
select dbo.Monday('2005-01-01','2005-02-28')
ok bye??
February 16, 2006 at 6:43 am
Note that the output of your function depends on the value of @@DATEFIRST:
declare @DateFirst int
select @DateFirst = @@DATEFIRST
set datefirst 1
select dbo.Monday('2006-02-13','2006-02-20') --Returns 2
set datefirst 7
select dbo.Monday('2006-02-13','2006-02-20') -- Returns 1 (incorrect)
set datefirst @DateFirst -- Resets @@DATEFIRST to original value
February 16, 2006 at 10:34 am
This could be wrapped in either a function or stored procedure. As noted above this also depends on the value of @@DATEFIRST.
--using a standard seq table
SELECT TOP 9999
IDENTITY(INT,0,1) AS N
INTO #Seq
FROM Master.dbo.SysComments sc1,
Master.dbo.SysComments sc2
declare @startdate datetime
declare @enddate datetime
select @startdate = '13 Feb 2006',
@enddate = '20 Feb 2006'
select sum(case when datepart(dw, dateadd(dd, s.n, @startdate)) = 1 then 1 else 0 end)
from #seq s
where s.n <= datediff(dd, @startdate, @enddate)
drop table #SEQ
February 16, 2006 at 12:51 pm
Amit,
Nice function - I think one small change could also speed it up - since weeks are a predictable format, when you encounter a Monday skip ahead the next 6 days - the second dateadd will then add one more day - once you find a Monday, you only need to check the Mondays....
Create Function Monday(@dt1 datetime,@dt2 datetime) returns int
as
Begin
Declare @cnt int,@dt as datetime
set @cnt=0
if @dt1 < @dt2
Begin
set @dt=@dt1
Begin
if Datepart(dw,@dt)=1
Begin
set @cnt=@cnt+1
set @dt=dateadd(dd,6,@dt)
End
set @dt=dateadd(dd,1,@dt)
End
End
if @cnt=0
Begin
return 0
End
Return @cnt
End
select dbo.Monday('2005-01-01','2005-02-28')
Regards,
Harley
February 16, 2006 at 4:37 pm
Run
select (@@Datefirst + Datepart(dw, YourDateField) - 2) %7 +1
FROM ..
with different Datefirst settings and see what you can get from it.
_____________
Code for TallyGenerator
February 16, 2006 at 10:03 pm
Jesper... I don't believe your formula works correctly...
I think the following works (finds inclusive Mondays)... I tested it some but I might have missed something...
DECLARE @StartDate DATETIME
DECLARE @EndDate DATETIME
SET @StartDate = '02/01/2006'
SET @EndDate = '02/27/2006'
SELECT
DATEDIFF(wk,@StartDate,@EndDate)
-CASE WHEN DATENAME(dw,@EndDate)='Sunday' THEN 1 ELSE 0 END
+CASE WHEN DATENAME(dw,@StartDate)='Monday' THEN 1 ELSE 0 END
...lemme know, eh?
The "numbers" table and WHILE loop solutions are great but compared to a direct formula, I've found them to be a bit slow.
--Jeff Moden
Change is inevitable... Change for the better is not.
February 17, 2006 at 3:01 am
Jeff, your formula doesn't work if the start date is a Sunday - e.g if @startdate = @enddate which is a Sunday, it will return -1.
I believe the following works (but then again, I also believed this last time ). This time, I have tested it against Amit's function (although JeffB's solution must be faster) for all days in January 2006 (Amit's function can easily be fixed to work in the case startsate=enddate which is a Monday). Here it goes:
datediff(d, '19000101', @dateTo)/7 - datediff(d, '19000102', @dateFrom)/7
February 17, 2006 at 4:09 am
OK.
@EndDate - (@@Datefirst+Datepart(dw,@EndDate)-2) %7
gives you last Monday before @EndDate.
Datediff(dd, @StartDate, @EndDate - (@@Datefirst+Datepart(dw,@EndDate)-2) %7) / 7
gives you result.
The only thing you need to adjust is number of Mondays between 2 Mondays. Is it 0, 1 or 2? Add +1 or -1 to dates depending on you answer.
_____________
Code for TallyGenerator
February 17, 2006 at 4:23 am
Sergiy, I don't believe your formula is correct if @StartDate=@EndDate='20051231'.
Jeff, I think this modification of your formula works:
DATEDIFF(wk,@startDate,@endDate)
-CASE WHEN DATENAME(dw,@endDate)='Sunday' THEN 1 ELSE 0 END
+CASE WHEN DATENAME(dw,@startDate)='Monday' THEN 1 ELSE 0 END
+CASE WHEN DATENAME(dw,@startDate)='Sunday' THEN 1 ELSE 0 END
Viewing 15 posts - 1 through 15 (of 35 total)
You must be logged in to reply to this topic. Login to reply