Как определить количество дней в месяце в SQL Server?



Мне нужно определить количество дней в месяце для данной даты в SQL Server.



есть ли встроенная функция? Если нет, то что я должен использовать в качестве пользовательской функции?

1689   24  

24 ответов:

Вы можете использовать следующий с первого дня указанного месяца:

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

чтобы заставить его работать на каждый день:

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

в SQL Server 2012 можно использовать EOMONTH (Transact-SQL) чтобы получить последний день месяца, а затем вы можете использовать день (Transact-SQL) чтобы получить количество дней в месяце.

DECLARE @ADate DATETIME

SET @ADate = GETDATE()

SELECT DAY(EOMONTH(@ADate)) AS DaysInMonth

наиболее элегантное решение: работает для любого @дата

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)))возвращает 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

гораздо проще...попробуй day(eomonth(@Date))

--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 для него, если нет встроенной функции...

Я предлагаю:

SELECT DAY(EOMONTH(GETDATE()))

этот код возвращает количество дней в текущем месяце:

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

изменить getdate() для дату нужно считать дни.

Решение 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]

вам нужно добавить функцию,но это простой. Я использую это:

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
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  datediff(day, 
        dateadd(day, 0, dateadd(month, ((2013 - 1900) * 12) + 3 - 1, 0)),
        dateadd(day, 0, dateadd(month, ((2013  - 1900) * 12) + 3, 0))
        )

приятно просто и не требует создания каких-либо функций работают нормально

нужно создать функцию, но это для собственного удобства. Он работает идеально, и я никогда не сталкивался с ошибочными вычислениями, используя эту функцию.

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

как работает: вычитание номера дня даты из самой даты дает вам последний день предыдущего месяца. Таким образом, вам нужно добавить один месяц к заданной дате, вычесть номер дня и получить дневную составляющую результата.

Я поддержал Mehrdad, но это тоже работает. :)

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 DAY(SUBDATE(ADDDATE(CONCAT(YEAR(NOW()), '-', MONTH(NOW()), '-1'), INTERVAL 1 MONTH), INTERVAL 1 DAY))

Nice' n ' простой и не требует создания каких-либо функций

ответ Mehrdad Afshari является наиболее точным, помимо обычного этот ответ основан на формальном математическом подходе, данном Кертисом Макинроем в своем блоге 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

чтобы получить нет. дней в месяц мы можем напрямую использовать Day (), доступный в SQL.

перейдите по ссылке, опубликованной в конце моего ответа для 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

на

select DateDiff(Day,@date,DateAdd(month,1,@date))
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)))

простой запрос в SQLServer2012 :

выбрать день(('20-05-1951 22:00:00'))

Я тестировал для многих дат и он возвращает всегда правильный результат

select first_day=dateadd(dd, -1*datepart(dd, getdate ())+1, getdate()), last_day=функция dateadd(ДД,-1*функция datepart(ДД,функция dateadd(мм,1,getdate ()) для),функция dateadd(мм,1,функции getdate())), no_of_days = 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, чтобы получить нет месяцев в этой конкретной дате

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
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

Comments

    Ничего не найдено.