2014-01-10 73 views
0

我需要循環一個月內的每一天,但固定的數字作爲月份的最後一天。計算月份開始/結束時固定的月份最後一天

E.g.如果該月的最後一天被固定爲30, 月將成爲:

開始每月:2012年12月31日12:00 AM 月結束:2013年1月30日上午12:00

我已經實現了除了二月份之外,其他的工作都很完美。我似乎無法找到一個解決方案,無論月結束日期是多少,都能確保每個月都能正常工作。 任何建議,非常感謝。

DECLARE @dt DATETIME 
DECLARE @DayInstance DATETIME 
DECLARE @LastDayOfMonth DATETIME 
DECLARE @monthEndDate INT = 30 


SET @dt = '2012-01-01 00:00:00.000' 


WHILE @dt < GETDATE() 
BEGIN 
    SET @DayInstance = @dt 
    SET @LastDayOfMonth = (SELECT CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(DATEADD(mm,1,@dt))),DATEADD(mm,1,@dt)),101)) 

    IF @monthEndDate > 0 
     BEGIN 
      SET @LastDayOfMonth = DATEADD(DAY,(@monthEndDate-DATEPART(dd,@LastDayOfMonth)),@LastDayOfMonth) 
      SET @DayInstance = DATEADD(MONTH, -1, @LastDayOfMonth) 
      SET @DayInstance = DATEADD(DAY, 1, @DayInstance) 
     END 
    PRINT 'Month Start Date: ' + CAST(@DayInstance AS NVARCHAR(20)) 
    PRINT 'Month End Date: ' + CAST(@LastDayOfMonth AS NVARCHAR(20))   
    PRINT ''  

    WHILE @DayInstance <= @LastDayOfMonth 
    BEGIN 
     -- Going to do more stuff here 
     SET @DayInstance = DATEADD(DAY, 1, @DayInstance) 
    END 

    SET @dt = DATEADD(MONTH, 1, @dt)  
END 

回答

2

我認爲,這個查詢(可以進一步簡化,但我想告訴我是怎麼想)設置@StartDate@EndDate到合適的日期 - 那麼你可以做這兩個值之間的迭代:

DECLARE @dt DATETIME 
DECLARE @DayInstance DATETIME 
DECLARE @monthEndDate INT = 30 

SET @dt = '2012-01-01 00:00:00.000' 

DECLARE @MagicDate1 DATETIME 
DECLARE @MagicDate2 DATETIME 

SELECT @MagicDate1 = DATEADD(day,@monthEndDate-1,'20010101'), 
     @MagicDate2 = DATEADD(day,@monthEndDate-1,'20001201') 

DECLARE @StartDate DATETIME 
DECLARE @EndDate DATETIME 

SELECT @StartDate = DATEADD(day,1,DATEADD(month,DATEDIFF(month,'20010101',@dt), 
          @MagicDate2)), 
     @EndDate = DATEADD(month,DATEDIFF(month,'20010101',@dt),@MagicDate1) 

select @StartDate,@EndDate 

我首先構造了兩個「魔術」日期。分別是2001年1月的第N天和2000年12月的第N天,其中N是期望的月結束日期。請注意,2000/2001的選擇是任意的,並且永遠不需要改變。

我們則在最後的表達式要做的就是工作了多少個月2001年1月和你@dt變量之間經過。如果我們在兩個「魔術」日期中添加相同的月份數,那麼我們最終將在同一月份的第N天以@dt和前一個月的第N天爲結束日期以@dt(或者如果月份少於N天)。

最後,我們通過加上1來調整我們發現的上個月的第N天 - 這應該是當前月份的「第一天」。


唯一重要的是要選擇兩個個月當中都有31天的日曆中的連續。這一年是任意的。

+0

哇!謝謝你。就像你所做的那樣,當然不是我想要的路線。似乎完美地工作。 :-) 非常感謝 – JIbber4568

0

你已經稍微過分複雜的事情,我想我相信你想要做它做的事情如下:

DECLARE @dt DATETIME 
DECLARE @LastDayOfMonth DATETIME 


SET @dt = '2012-01-01 00:00:00.000' 
WHILE @dt < GETDATE() 
BEGIN 
    SET @LastDayOfMonth = DATEADD(DAY,-1,(DATEADD(MONTH,1,@dt))) 
    PRINT 'Month Start Date: ' + CAST(@dt AS NVARCHAR(20)) 
    PRINT 'Month End Date: ' + CAST(@LastDayOfMonth AS NVARCHAR(20))   
    PRINT '' 
    SET @dt = DATEADD(MONTH, 1, @dt)  
END 

這將工作,只要@dt是當月的第一天,否則你將不得不創建一個新的@FirstDayOfMonth變量,並將其設置在`@LastDayOfMonth'的設置上面,但上面應該是一個很好的起點。

+0

謝謝你。然而,本月的最後一天並不總是實際的最後一天。例如,有時候這個月的最後一天將是25號,在這種情況下,26號到31號將進入2月,1月開始將是12月26號。希望這是有道理的。 – JIbber4568

+0

可能值得用這些規則的細節更新問題。例如SQL如何知道所需的月份長度?你怎麼知道哪個月的最後一天是25號? – talegna

+0

它以「DECLARE @monthEndDate INT = 30」的形式出現在這裏,它將針對整個操作進行預設,並將適用於所有月份。但是SQL需要能夠在這裏接受任何值。它可能是31,30,29,28等 – JIbber4568