如何确定SQL Server中一个月的天数?

如何确定SQL Server中一个月的天数?,sql,sql-server,datetime,date,user-defined-functions,Sql,Sql Server,Datetime,Date,User Defined Functions,我需要确定SQL Server中给定日期的月天数 有内置的功能吗?如果没有,我应该使用什么作为用户定义函数?您可以在指定月份的第一天使用以下函数: datediff(day, @date, dateadd(month, 1, @date)) 要使其适用于每个日期,请执行以下操作: datediff(day, dateadd(day, 1-day(@date), @date), dateadd(month, 1, dateadd(day, 1-day(@date),

我需要确定SQL Server中给定日期的月天数


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

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

datediff(day, @date, dateadd(month, 1, @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

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

我对Mehrdad投了更高的票,但这同样有效。:)

检验

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

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

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]

很简单,不需要创建任何函数

解决方案1:查找我们当前所在月份的天数

DECLARE @dt datetime
SET     @dt = getdate()

SELECT @dt AS [DateTime],
       DAY(DATEADD(mm, DATEDIFF(mm, -1, @dt), -1)) AS [Days in Month]
解决方案2:查找给定月-年组合中的天数

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]

在SQL Server 2012中,可以使用获取当月的最后一天,然后使用获取当月的天数

DECLARE @ADate DATETIME

SET @ADate = GETDATE()

SELECT DAY(EOMONTH(@ADate)) AS DaysInMonth
非常简单,不需要创建任何函数就可以在任何日期正常工作

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

更简单…尝试
day(eomonth(@Date))
最优雅的解决方案:适用于任何@Date

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

其他答案的日期示例:

选择日期(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,'1/31/2009'),0))
返回31

选择日期(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,'2404-feb-15'),0))
返回29


选择日期(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,'2011-12-22'),0))
返回31您需要创建一个函数,但这是为了您自己的方便。它工作完美,我从未遇到任何错误的计算使用此函数

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-1951 22:00:00'))


我测试了很多日期,结果总是正确的

这段代码可以获取当前月份的天数:

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

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

Mehrdad Afshari的回答是最准确的,除了通常的回答外,这个回答基于Curtis McEnroe在其博客中给出的正式数学方法


要获得一个月的天数,我们可以直接使用SQL中提供的Day()

请按照我对SQL Server 2005/2008的回答结尾处的链接进行操作

以下示例和结果来自SQL 2012

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')
生成SQL Server SSMS

  (no column name)
1 31
过程:

使用EOMONTH时,无论使用哪种日期格式,都会转换为SQL server的日期时间格式。那么EOMONTH()的日期输出将为2016-12-31,其中2016年为年,12年为月,31天为天。 此输出在传递到Day()时,会给出该月的总天数

DECLARE @ADate DATETIME

SET @ADate = GETDATE()

SELECT DAY(EOMONTH(@ADate)) AS DaysInMonth
如果我们想得到检查的即时结果,可以直接运行下面的代码

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

有关在SQL Server 2005/2008/2012中工作的参考,请遵循以下外部链接

选择第一天=日期添加(dd,-1*datepart(dd,getdate())+1,getdate()), last_day=dateadd(dd,-1*datepart(dd,dateadd(mm,1,getdate())),dateadd(mm,1,getdate()), 无天数=1+datediff(dd,dateadd(dd,-1*datepart(dd,getdate())+1,getdate())、dateadd(dd,-1*datepart(dd,dateadd(mm,1,getdate())、dateadd(mm,1,getdate()))


将任何日期替换为getdate以获取该特定日期的月数,我建议:

SELECT DAY(EOMONTH(GETDATE()))
结果: 这个月 三十一

下个月 30

从dual中选择add_months(trunc(sysdate,'MM'),1)-trunc(sysdate,'MM');

一种更简洁的实现方法是使用
datefromparts
函数构造月的第一天,并计算从那开始的天数

创建函数[dbo].[fn\u DaysInMonth]
(
@整年,
@月整数
)
返回整数
作为
开始
如果@month<1或@month>12返回空值;
如果@year<1753或@year>9998返回空值;
声明@firstDay DATE=datefromparts(@year,@month,1);
声明@lastDay DATE=dateadd(月,1,@firstDay);
返回日期差异(天、第一天、最后一天);
结束
去
同样,您可以计算一年中的天数:

创建函数[dbo].[fn\u DaysInYear]
(
@整年
)
返回整数
作为
开始
如果@year<1753或@year>9998返回空值;
声明@firstDay DATE=datefromparts(@year,1,1);
声明@lastDay DATE=dateadd(年份,1,@firstDay);
返回日期差异(天、第一天、最后一天);
结束
去

顺便说一句,DATEDIFF和DATEADD的组合并不总是有效的。如果你把日期改为2009年1月31日,DATEADD会返回2009年2月28日,DATEDIFF会给你28天,而不是31天。如何检查,我的意思是要执行什么来检查一个月的天数??就像Stan说的,这在某些情况下会给出不准确的结果,你不是说:DATEDIFF(day,DATEADD(day,1-day(@date),@date),DATEADD(month,1,dateadd(day,1-day(@date),@date)))这是一个罕见的极端情况,但我偶然发现:这将在9999年12月抛出一个错误。这对9999年12月的任何日期都不起作用。日期类型溢出。这在SQL Server 2014中对我有效:
当datediff(m,dateadd(day,1-day(@date),@date)转换时的情况(date,convert(datetime,2958463))>0然后datediff(day,dateadd(day,1-day(@date),@date),dateadd(month,1,dateadd(day,1-day(@date),@date)))否则31结束这里提到的所有解决方案
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
SELECT datediff(dd,getdate(),dateadd(mm,1,getdate())) as datas
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
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')
  (no column name)
1 31
select DAY(EOMONTH(convert(datetime,'08/12/2016',103)))
select DAY(EOMONTH(convert(datetime,getdate(),103)))
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';
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()))
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))