How to determine the number of days in a month in SQL Server?

我需要确定 SQLServer 中给定日期的一个月的天数。

是否有内置函数? 如果没有,我应该使用什么作为用户定义的函数?

298977 次浏览

您可以在指定月份的第一天使用以下命令:

datediff(day, @date, dateadd(month, 1, @date))

To make it work for every date:

datediff(day, dateadd(day, 1-day(@date), @date),
dateadd(month, 1, dateadd(day, 1-day(@date), @date)))

你确实需要添加一个函数,但这个函数很简单:

CREATE FUNCTION [dbo].[ufn_GetDaysInMonth] ( @pDate    DATETIME )


RETURNS INT
AS
BEGIN


SET @pDate = CONVERT(VARCHAR(10), @pDate, 101)
SET @pDate = @pDate - DAY(@pDate) + 1


RETURN DATEDIFF(DD, @pDate, DATEADD(MM, 1, @pDate))
END


GO
--Last Day of Previous Month
SELECT DATEPART(day, DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0)))


--Last Day of Current Month
SELECT DATEPART(day, DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0)))


--Last Day of Next Month
SELECT DATEPART(day, DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+2,0)))

但就个人而言,如果没有内置的函数,我会为它制作一个 UDF..。

我投票支持梅赫达德,但这个方法也行得通。 :)

CREATE function dbo.IsLeapYear
(
@TestYear int
)
RETURNS bit
AS
BEGIN
declare @Result bit
set @Result =
cast(
case when ((@TestYear % 4 = 0) and (@testYear % 100 != 0)) or (@TestYear % 400 = 0)
then 1
else 0
end
as bit )
return @Result
END
GO


CREATE FUNCTION dbo.GetDaysInMonth
(
@TestDT datetime
)
RETURNS INT
AS
BEGIN


DECLARE @Result int
DECLARE @MonthNo int


Set @MonthNo = datepart(m,@TestDT)


Set @Result =
case @MonthNo
when  1 then 31
when  2 then
case
when dbo.IsLeapYear(datepart(yyyy,@TestDT)) = 0
then 28
else 29
end
when  3 then 31
when  4 then 30
when  5 then 31
when  6 then 30
when  7 then 31
when  8 then 31
when  9 then 30
when 10 then 31
when 11 then 30
when 12 then 31
end


RETURN @Result
END
GO

测试

declare @testDT datetime;


set @testDT = '2404-feb-15';


select dbo.GetDaysInMonth(@testDT)

还有一个。

Select Day(DateAdd(day, -Day(DateAdd(month, 1, getdate())),
DateAdd(month, 1, getdate())))

我知道这个问题很老了,但我想我应该分享一下我正在使用的东西。

DECLARE @date date = '2011-12-22'


/* FindFirstDayOfMonth - Find the first date of any month */
-- Replace the day part with -01
DECLARE @firstDayOfMonth date = CAST( CAST(YEAR(@date) AS varchar(4)) + '-' +
CAST(MONTH(@date) AS varchar(2)) + '-01' AS date)
SELECT @firstDayOfMonth

还有

DECLARE @date date = '2011-12-22'


/* FindLastDayOfMonth - Find what is the last day of a month - Leap year is handled by DATEADD */
-- Get the first day of next month and remove a day from it using DATEADD
DECLARE @lastDayOfMonth date = CAST( DATEADD(dd, -1, DATEADD(mm, 1, FindFirstDayOfMonth(@date))) AS date)


SELECT @lastDayOfMonth

如果需要的话,可以将它们组合起来创建一个单独的函数来检索一个月中的天数。

SELECT Datediff(day,
(Convert(DateTime,Convert(varchar(2),Month(getdate()))+'/01/'+Convert(varchar(4),Year(getdate())))),
(Convert(DateTime,Convert(varchar(2),Month(getdate())+1)+'/01/'+Convert(varchar(4),Year(getdate()))))) as [No.of Days in a Month]
SELECT DAY(SUBDATE(ADDDATE(CONCAT(YEAR(NOW()), '-', MONTH(NOW()), '-1'), INTERVAL 1 MONTH), INTERVAL 1 DAY))

简单且不需要创建任何函数

解决方案1: 找出当前月份的天数

DECLARE @dt datetime
SET     @dt = getdate()


SELECT @dt AS [DateTime],
DAY(DATEADD(mm, DATEDIFF(mm, -1, @dt), -1)) AS [Days in Month]

Solution 2: Find the number of days in a given month-year combo

DECLARE @y int, @m int
SET     @y = 2012
SET     @m = 2


SELECT @y AS [Year],
@m AS [Month],
DATEDIFF(DAY,
DATEADD(DAY, 0, DATEADD(m, ((@y - 1900) * 12) + @m - 1, 0)),
DATEADD(DAY, 0, DATEADD(m, ((@y - 1900) * 12) + @m, 0))
) AS [Days in Month]

在 SQLServer2012中,您可以使用 EOMONTH (Transact-SQL)获取该月的最后一天,然后您可以使用 DAY (Transact-SQL)获取该月的天数。

DECLARE @ADate DATETIME


SET @ADate = GETDATE()


SELECT DAY(EOMONTH(@ADate)) AS DaysInMonth
select  datediff(day,
dateadd(day, 0, dateadd(month, ((2013 - 1900) * 12) + 3 - 1, 0)),
dateadd(day, 0, dateadd(month, ((2013  - 1900) * 12) + 3, 0))
)

简单,不需要创建任何函数工作良好

任何约会

select DateDiff(Day,@date,DateAdd(month,1,@date))

最优雅的解决方案: 适用于任何 @ DATE

DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@DATE),0)))

将其放入函数中,或者仅仅在内联中使用它。这回答了原来的问题,而没有在其他的答案中多余的垃圾。

其他答案的日期例子:

SELECT DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,'1/31/2009'),0))) Returns 31

SELECT DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,'2404-feb-15'),0))) 申报表29

SELECT DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,'2011-12-22'),0))) 申报表31

DECLARE @date nvarchar(20)
SET @date ='2012-02-09 00:00:00'
SELECT DATEDIFF(day,cast(replace(cast(YEAR(@date) as char)+'-'+cast(MONTH(@date) as char)+'-01',' ','')+' 00:00:00' as datetime),dateadd(month,1,cast(replace(cast(YEAR(@date) as char)+'-'+cast(MONTH(@date) as char)+'-01',' ','')+' 00:00:00' as datetime)))

您需要创建一个函数,但这是为了您自己的方便。它工作完美,我从来没有遇到任何错误的计算使用这个函数。

CREATE FUNCTION [dbo].[get_days](@date datetime)
RETURNS int
AS
BEGIN
SET @date = DATEADD(MONTH, 1, @date)
DECLARE @result int = (select DAY(DATEADD(DAY, -DAY(@date), @date)))
RETURN @result
END

它的工作原理: 从日期本身中减去日期的日期号,就得到了上个月的最后一天。因此,您需要在给定的日期后面加上一个月,然后减去日期号,得到结果的日组成部分。

SQLServer2012中的简单查询:

选择日期(’20-05-195122:00:00’)

我测试了许多日期,它总是返回一个正确的结果

这段代码给你当前月份的天数:

SELECT datediff(dd,getdate(),dateadd(mm,1,getdate())) as datas

getdate()更改为需要计算天数的日期。

Mehrdad Afshari reply is most accurate one, apart from usual this answer is based on formal mathematical approach given by Curtis McEnroe in his blog https://cmcenroe.me/2014/12/05/days-in-month-formula.html

DECLARE @date  DATE= '2015-02-01'
DECLARE @monthNumber TINYINT
DECLARE @dayCount TINYINT
SET @monthNumber = DATEPART(MONTH,@date )
SET @dayCount = 28 + (@monthNumber + floor(@monthNumber/8)) % 2 + 2 %    @monthNumber + 2 * floor(1/@monthNumber)
SELECT @dayCount + CASE WHEN @dayCount = 28 AND DATEPART(YEAR,@date)%4 =0 THEN 1 ELSE 0 END -- leap year adjustment

为了得到一个月的天数,我们可以直接使用 SQL 中提供的 Day ()。

请按照我在 SQLServer2005/2008答案末尾提供的链接进行操作。

下面的示例和结果来自 SQL2012

alter function dbo.[daysinm]
(
@dates nvarchar(12)
)
returns int
as
begin
Declare @dates2 nvarchar(12)
Declare @days int
begin
select @dates2 = (select DAY(EOMONTH(convert(datetime,@dates,103))))
set @days = convert(int,@dates2)
end
return @days
end


--select dbo.daysinm('08/12/2016')

SQLServerSSMS 中的结果

  (no column name)
1 31

过程:

当使用 EOMONTH 时,无论我们使用哪种日期格式,它都会转换为 SQL-server 的 DateTime 格式。那么月()的日期输出将是2016-12-31年,2016年为年,12月为月,31天为日。 这个输出在传递到 Day ()时会给出这个月的总天数。

如果我们想得到即时的检查结果,我们可以直接运行下面的代码,

select DAY(EOMONTH(convert(datetime,'08/12/2016',103)))

or

select DAY(EOMONTH(convert(datetime,getdate(),103)))

如欲参考 SQLServer2005/2008/2012的工作,请按以下外部连结..。

Find No. of Days in a Month in SQL

Select first _ day = dateadd (dd,-1 * datepart (dd,getdate ()) + 1,getdate ()) , Last _ day = dateadd (dd,-1 * datepart (dd,dateadd (mm,1,getdate ())) ,dateadd (mm,1,getdate ())) , No _ of _ days = 1 + datediff (dd,dateadd (dd,-1 * datepart (dd,-1 * getdate ()) + 1,getdate ()) ,dateadd (dd,-1 * datepart (dd,dateadd (mm,1,getdate ())) ,dateadd (mm,1,getdate ())))

replace any date with getdate to get the no of months in that particular date

我建议:

SELECT DAY(EOMONTH(GETDATE()))
DECLARE @date DATETIME = GETDATE(); --or '12/1/2018' (month/day/year)
SELECT DAY(EOMONTH ( @date )) AS 'This Month';
SELECT DAY(EOMONTH ( @date, 1 )) AS 'Next Month';

结果: 本月 31

下个月 30

DECLARE @Month INT=2,
@Year INT=1989
DECLARE @date DateTime=null
SET @date=CAST(CAST(@Year AS nvarchar) + '-' + CAST(@Month AS nvarchar) + '-' + '1' AS DATETIME);


DECLARE @noofDays TINYINT
DECLARE @CountForDate TINYINT
SET @noofDays = DATEPART(MONTH,@date )
SET @CountForDate = 28 + (@noofDays + floor(@noofDays/8)) % 2 + 2 %    @noofDays + 2 * floor(1/@noofDays)
SET @noofDays= @CountForDate + CASE WHEN @CountForDate = 28 AND DATEPART(YEAR,@date)%4 =0 THEN 1 ELSE 0 END
PRINT @noofDays
   --- sql server below 2012---
select day( dateadd(day,-1,dateadd(month, 1, convert(date,'2019-03-01'))))
-- this for sql server 2012--
select day(EOMONTH(getdate()))
select add_months(trunc(sysdate,'MM'),1) -  trunc(sysdate,'MM') from dual;
DECLARE  @m int
SET     @m = 2


SELECT
@m AS [Month],
DATEDIFF(DAY,
DATEADD(DAY, 0, DATEADD(m, +@m -1, 0)),
DATEADD(DAY, 0, DATEADD(m,+ @m, 0))
) AS [Days in Month]
RETURN day(dateadd(month, 12 * @year + @month - 22800, -1))
select day(dateadd(month, 12 * year(date) + month(date) - 22800, -1))

一种更简洁的实现方法是使用 datefromparts函数来构造每个月的第一天,并从那里计算天数。

CREATE FUNCTION [dbo].[fn_DaysInMonth]
(
@year INT,
@month INT
)
RETURNS INT
AS
BEGIN


IF @month < 1 OR @month > 12 RETURN NULL;
IF @year < 1753 OR @year > 9998 RETURN NULL;


DECLARE @firstDay DATE = datefromparts(@year, @month, 1);
DECLARE @lastDay DATE = dateadd(month, 1, @firstDay);


RETURN datediff(day, @firstDay, @lastDay);


END
GO

类似地,你可以计算一年中的天数:

CREATE FUNCTION [dbo].[fn_DaysInYear]
(
@year INT
)
RETURNS INT
AS
BEGIN


IF @year < 1753 OR @year > 9998 RETURN NULL;


DECLARE @firstDay DATE = datefromparts(@year, 1, 1);
DECLARE @lastDay DATE = dateadd(year, 1, @firstDay);


RETURN datediff(day, @firstDay, @lastDay);


END
GO