我需要一个算法来计算当月的星期几。像本月的第一个星期五,本月的第3个星期一等)。
任何想法都表示赞赏。
以下是最终结果:
declare @dt date = GetDate()
declare @DayOfWeek tinyint = datepart(weekday,@dt)
declare @DayOfMonth smallint = day(@dt)
declare @FirstDayOfMonth date = dateadd(month,datediff(month,0,@dt),0)
declare @DayOfWeekInMonth tinyint = @DayOfMonth / 7 + 1 -
(case when day(@FirstDayOfMonth) > day(@dt) then 1 else 0 end)
declare @Suffix varchar(2) =
case
when @DayOfWeekInMonth = 1 then 'st'
when @DayOfWeekInMonth = 2 then 'nd'
when @DayOfWeekInMonth = 3 then 'rd'
when @DayOfWeekInMonth > 3 then 'th'
end
select
cast(@DayOfWeekInMonth as varchar(2))
+ @Suffix
+ ' '
+ datename(weekday,@Dt)
+ ' of '
+ datename(month,@dt)
+ ', '
+ datename(year,@Dt)
PS:如果你能想出一个更好的方式来陈述问题,请做。
答案 0 :(得分:1)
Followint代码今天会为您提供1st Wednesday of April 2014
:
SELECT cast((DATEPART(d, GETDATE() - 1) / 7) + 1 as varchar(12))
+ 'st ' + DATENAME(WEEKDAY, getdate()) + ' of ' +
DATENAME(month, getdate()) + ' ' + DATENAME(year, getdate());
对于任何日期,请使用以下代码。它为示例中的5th Tuesday of April 2014
提供了@mydate = '2014-04-29'
:
DECLARE @mydate DATETIME;
SET @mydate = '2014-04-29';
SELECT
case
when DATEPART(d, @mydate) = 1 then cast((DATEPART(d, @mydate ) / 7) + 1 as varchar(12))
else cast((DATEPART(d, @mydate - 1) / 7) + 1 as varchar(12))
end
+
case
when (DATEPART(d, @mydate - 1) / 7) + 1 = 1 then 'st '
when (DATEPART(d, @mydate - 1) / 7) + 1 = 2 then 'nd '
when (DATEPART(d, @mydate - 1) / 7) + 1 = 3 then 'rd '
else 'th '
end
+ DATENAME(WEEKDAY, @mydate) + ' of ' +
DATENAME(month, @mydate) + ' ' + DATENAME(year, @mydate) as [Long Date Name]
答案 1 :(得分:1)
Okeeeey我的tuuuurn,
请评价我的答案隐喻嗯,这是乔德:
declare @v_month nvarchar(2) = '04'
,@v_annee nvarchar(4) = '2014'
declare @v_date date = convert(date,@v_annee+'-'+@v_month+'-01')
declare @v_date_2 date = dateadd(M,1,@v_date)
if OBJECT_ID('temp') is not null
drop table temp
create table temp(_date date, _DayOfMonth nvarchar(20), _order int)
while (@v_date<@v_date_2)
begin
set @v_date =@v_date;
WITH _DayOfWeek AS (
SELECT 1 id, 'monday' Name UNION ALL
SELECT 2 id, 'tuesday' Name UNION ALL
SELECT 3 id, 'wednesday' Name UNION ALL
SELECT 4 id, 'thursday' Name UNION ALL
SELECT 5 id, 'friday' Name UNION ALL
SELECT 6 id, 'saturday' Name UNION ALL
SELECT 7 id, 'sunday' Name)
insert into temp(_date,_DayOfMonth)
SELECT
@v_date
,(select Name from _DayOfWeek where id = DATEPART(WEEKDAY,@v_date))
SET @v_date = DATEADD(DAY,1,@v_date)
END
UPDATE tmp1
SET _order = _order_2
FROM temp tmp1
INNER JOIN
(SELECT *, ROW_NUMBER() OVER(PARTITION BY _DayOfMonth ORDER BY _date ASC) AS _order_2 FROM temp) tmp2
ON tmp1._date = tmp2._date
SELECT * FROM temp
SELECT *
FROM temp
WHERE _DayOfMonth = 'thursday'
AND _order = 3
我希望这会对你有所帮助:) 祝你好运
答案 2 :(得分:0)
好的,这就是我提出的问题,我会给所有回答的人+1:
declare @dt date = GetDate()
declare @DayOfWeek tinyint = datepart(weekday,@dt)
declare @DayOfMonth smallint = day(@dt)
declare @FirstDayOfMonth date = dateadd(month,datediff(month,0,@dt),0)
declare @DayOfWeekInMonth tinyint =
@DayOfMonth / 7 + 1
- (case when day(@FirstDayOfMonth) > day(@dt) then 1 else 0 end)
declare @Suffix varchar(2) =
case
when @DayOfWeekInMonth = 1 then 'st'
when @DayOfWeekInMonth = 2 then 'nd'
when @DayOfWeekInMonth = 3 then 'rd'
when @DayOfWeekInMonth > 3 then 'th'
end
select
cast(@DayOfWeekInMonth as varchar(2))
+ @Suffix
+ ' '
+ datename(weekday,@Dt)
+ ' of '
+ datename(month,@dt)
+ ', '
+ datename(year,@Dt)
答案 3 :(得分:0)
declare @dt date = getdate()
declare @DayOfMonth smallint = datepart(d, @dt)
declare @Suffix varchar(2) =
case
when floor((@DayOfMonth - 1) / 7.0) = 0 then 'st' -- implies there were no such days previously in the month
when floor((@DayOfMonth - 1) / 7.0) = 1 then 'nd'
when floor((@DayOfMonth - 1) / 7.0) = 2 then 'rd'
else 'th'
end
select cast(floor((@DayOfMonth - 1) / 7.0) + 1 as varchar(1)) + @Suffix +
' ' + datename(weekday, @dt) + ' of ' + datename(month, @dt) +
', ' + datename(year, @dt)
答案 4 :(得分:0)
DECLARE @dt DATETIME
SET @dt = DATEADD(d, 6, GETDATE())
SELECT @dt,
CAST((DAY(@dt) / 7) + CASE WHEN DATEPART(weekday, @dt) >= DATEPART(weekday, CAST(MONTH(@dt) AS NVARCHAR) + '/01/' + CAST(YEAR(@dt) AS NVARCHAR)) THEN 1 ELSE 0 END AS NVARCHAR)
+ '' + CASE (DAY(@dt) / 7) + CASE WHEN DATEPART(weekday, @dt) >= DATEPART(weekday, CAST(MONTH(@dt) AS NVARCHAR) + '/01/' + CAST(YEAR(@dt) AS NVARCHAR)) THEN 1 ELSE 0 END
WHEN 1 THEN N'st'
WHEN 2 THEN N'nd'
WHEN 3 THEN N'rd'
ELSE N'th'
END
+ ' ' + DATENAME(dw, @dt)
+ ' of ' + DATENAME(M, @dt)
+ ', ' + CAST(YEAR(@dt) AS NVARCHAR)
结果是一个SELECT(如果@dt的赋值发生在前面),但基本上与你的逻辑相同。
答案 5 :(得分:0)
以下代码将为您指定的任何月份或年份中的任何一天提供DATE
。我所拥有的所有变量都是为了减少重复逻辑以提高代码速度。
此代码为您提供1st Monday in February in 2013
DECLARE @DayNumber INT = 1
,@DayWeekNumber INT = 2
,@MonthNumber INT = 2
,@YearNumber INT = 2013
,@FoM DATE
,@FoMWD INT;
SET @FoM = DATEFROMPARTS(@YearNumber,@MonthNumber,1)
SET @fomwd = DATEPART(WEEKDAY, @FoM);
SELECT CASE WHEN @fomwd = @DayWeekNumber THEN DATEADD(WEEK, @DayNumber - 1, @FoM)
WHEN @fomwd < @DayWeekNumber THEN DATEADD(DAY, @DayWeekNumber - @fomwd, DATEADD(WEEK, @DayNumber - 1, @FoM))
WHEN @fomwd > @DayWeekNumber THEN DATEADD(DAY, @DayWeekNumber - @fomwd, DATEADD(WEEK, @DayNumber, @FoM))
END AS DateOfDay;