以固定的最后一天计算月份开始/结束

时间:2014-01-10 11:18:37

标签: sql datetime sql-server-2012

我需要在一个月内循环每一天,但固定的数字是一个月的最后一天。

E.g。如果该月的最后一天固定为30, 一月将成为:

月初:2012年12月31日12:00 AM 月末:2013年1月30日12:00 AM

我已经实施了以下功能,除了2月份之外,它的功能完美。我似乎无法找到一种解决方案,无论月末日期是什么,都能确保每个月都能使用。 任何建议都非常感谢。

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 个答案:

答案 0 :(得分: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的选择是任意的,永远不需要改变。 1

我们在最后的表达式中做的是计算2001年1月到你的@dt变量之间经过了多少个月。如果我们在我们的两个“魔术”日期添加相同数量的月份,那么我们最终会在同一个月的第N天@dt和上个月的第N天@dt(或者如果月份少于N天,则为任何一个月的最后一天。

最后,我们通过向其添加1来调整我们发现的上个月的第N天 - 这应该是当月的“第一天”。


1 唯一重要的是选择两个月,这两个月都有31天,并且在日历中是连续的。这一年是任意的。

答案 1 :(得分: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'的设置,但上面应该是一个很好的起点。