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

Типичные примитивные типы .NET не имеют общего интерфейса, который позволяет использовать их для вычислений. Можно было бы определить ваши собственные интерфейсы (например, ISignedWholeNumber), которые будут выполнять такие операции, определять структуры, которые содержат один Int16, Int32 и т. Д., И реализовывать эти интерфейсы, а затем использовать методы, которые принимают общие типы ограничено ISignedWholeNumber, но для преобразования числовых значений в типы структуры, вероятно, будет неприятность.

Альтернативным подходом было бы определить статический класс Int64Converter<T> со статическим свойством bool Available {get;}; и статическим делегаты для Int64 GetInt64(T value), T FromInt64(Int64 value), bool TryStoreInt64(Int64 value, ref T dest). Конструктор класса может быть жестко закодирован для загрузки делегатов для известных типов и, возможно, использовать Reflection для проверки того, реализует ли тип T методы с собственными именами и сигнатурами (в случае, если это что-то вроде структуры, которая содержит Int64 и представляет собой число, но имеет собственный метод ToString()). Такой подход потеряет преимущества, связанные с проверкой типа времени компиляции, но все равно удастся избежать операций в боксе, и каждый тип нужно будет только «проверять» один раз. После этого операции, связанные с этим типом, будут заменены диспетчером делегатов.

86
задан Even Mien 27 March 2009 в 19:13
поделиться

6 ответов

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

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

Заставить его работать на каждую дату:

datediff(day, dateadd(day, 1-day(@date), @date),
              dateadd(month, 1, dateadd(day, 1-day(@date), @date)))
113
ответ дан Mehrdad Afshari 24 November 2019 в 07:53
поделиться

Я upvoted 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)
0
ответ дан feihtthief 24 November 2019 в 07:53
поделиться

вот другой...

Select Day(DateAdd(day, -Day(DateAdd(month, 1, getdate())), 
                         DateAdd(month, 1, getdate())))
0
ответ дан Charles Bretana 24 November 2019 в 07:53
поделиться
--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 для него, если нет созданного в функции...

11
ответ дан Brian Webster 24 November 2019 в 07:53
поделиться

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

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
1
ответ дан hims056 24 November 2019 в 07:53
поделиться
RETURN day(dateadd(month, 12 * @year + @month - 22800, -1)) 
select day(dateadd(month, 12 * year(date) + month(date) - 22800, -1)) 
0
ответ дан 24 November 2019 в 07:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: