¿Cómo determinar la cantidad de días en un mes en SQL Server?

95

Necesito determinar la cantidad de días en un mes para una fecha determinada en SQL Server.

¿Hay una función incorporada? Si no es así, ¿qué debo usar como función definida por el usuario?

Incluso Mien
fuente

Respuestas:

115

Puede utilizar lo siguiente con el primer día del mes especificado:

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

Para que funcione en todas las fechas:

datediff(day, dateadd(day, 1-day(@date), @date),
              dateadd(month, 1, dateadd(day, 1-day(@date), @date)))
Mehrdad Afshari
fuente
2
Como dice Stan, esto dará resultados inexactos en algunos casos
DJ.
3
¿no te refieres a: dateiff (día, dateadd (día, 1 día (@fecha), @fecha), dateadd (mes, 1, dateadd (día, 1 día (@fecha), @fecha)))
feihtthief
3
Es un caso de esquina poco común, pero me encontré con él: esto arrojará un error para diciembre de 9999.
Heinzi
1
Esto no funciona para ninguna fecha en diciembre de 9999. Obtiene un desbordamiento en el tipo de fecha. Esto funcionó para mí en SQL Server 2014: case when datediff(m, dateadd(day, 1-day(@date), @date), convert(date, convert(datetime, 2958463))) > 0 then datediff(day, dateadd(day, 1-day(@date), @date), dateadd(month, 1, dateadd(day, 1-day(@date), @date))) else 31 end
bradwilder31415
2
Todas las soluciones mencionadas aquí palidecen en comparación con la elegancia de la respuesta de @Mikael Eriksson . Eso funciona siempre que se proporciona una fecha válida sin soluciones locas para casos de nicho y es un código mucho más simple: recomiendo encarecidamente a cualquier persona en T-SQL que obtenga el daycomponente de la eomonthsalida.
bsplosion
148

En SQL Server 2012, puede usar EOMONTH (Transact-SQL) para obtener el último día del mes y luego puede usar DAY (Transact-SQL) para obtener el número de días del mes.

DECLARE @ADate DATETIME

SET @ADate = GETDATE()

SELECT DAY(EOMONTH(@ADate)) AS DaysInMonth
Mikael Eriksson
fuente
1
Y si necesita la cantidad de días en un determinado, también puede usar el método DATEFROMPARTS. El código anterior se convertiría en SELECT DAY (EOMONTH (DATEFROMPARTS (@year, @month, 1))) AS DaysInMonth
nmariot
¡La belleza de esta solución entra en juego si @ADate es un valor calculado complejo! +1
Stefan Steiger
¡Muchas gracias!
Rejwanul Reja
27

La solución más elegante: funciona para cualquier @DATE

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

Tíralo en una función o simplemente úsalo en línea. Esto responde a la pregunta original sin toda la basura adicional en las otras respuestas.

ejemplos de fechas de otras respuestas:

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

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

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

Daniel Davis
fuente
22

Mucho más simple ... prueba day(eomonth(@Date))

Javier
fuente
1
Creo que tu respuesta es la mejor, tan simple. ¡Gracias!
Ofear
12
--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)))

Sin embargo, personalmente, haría un UDF para él si no hay una función incorporada ...

Brimstedt
fuente
5

Yo sugeriría:

SELECT DAY(EOMONTH(GETDATE()))
gvschijndel
fuente
datepart no devuelve el número de días y su respuesta también es incorrecta
TheGameiswar
Funcionó para mí, pero seguro que usar la función de día sería una respuesta más limpia
gvschijndel
2
esta respuesta es casi idéntica a la siguiente con votos de 75.
Hila DG
3

Este código le da la cantidad de días en el mes actual:

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

Cambie getdate()a la fecha para la que necesita contar los días.

Prashant
fuente
2
   --- 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()))
Saikh Rakif
fuente
1

Solución 1: Encuentre la cantidad de días en cualquier mes en el que estemos actualmente

DECLARE @dt datetime
SET     @dt = getdate()

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

Solución 2: Encuentre la cantidad de días en una combinación de mes-año dada

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]
Phillip Copley
fuente
1

Necesita agregar una función, pero es simple. Yo uso esto:

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
hims056
fuente
1
La combinación de DATEDIFF y DATEADD, por cierto, no siempre funciona. Si pone una fecha de 1/31/2009, DATEADD devolverá el 2/28/2009 y DATEDIFF le dará 28, en lugar de 31.
cómo comprobar, me refiero a qué ejecutar para comprobar los días en un mes ??
hud
1
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]
Vignesh Anandaraj
fuente
1
select  datediff(day, 
        dateadd(day, 0, dateadd(month, ((2013 - 1900) * 12) + 3 - 1, 0)),
        dateadd(day, 0, dateadd(month, ((2013  - 1900) * 12) + 3, 0))
        )

Agradable Simple y no requiere la creación de funciones Funciona bien

pradeep
fuente
1

Necesita crear una función, pero es para su propia conveniencia. Funciona perfectamente y nunca encontré ningún cálculo defectuoso al usar esta función.

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

Cómo funciona: restar el número de día de la fecha de la fecha en sí le da el último día del mes anterior. Por lo tanto, debe agregar un mes a la fecha dada, restar el número de día y obtener el componente de día del resultado.

an40us
fuente
1
select add_months(trunc(sysdate,'MM'),1) -  trunc(sysdate,'MM') from dual;
kritika
fuente
0

Yo voté a favor de Mehrdad, pero esto también funciona. :)

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

Probar

declare @testDT datetime;

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

select dbo.GetDaysInMonth(@testDT)
feihtief
fuente
0

aqui hay otro más...

Select Day(DateAdd(day, -Day(DateAdd(month, 1, getdate())), 
                         DateAdd(month, 1, getdate())))
Charles Bretana
fuente
0

Sé que esta pregunta es antigua, pero pensé en compartir lo que estoy usando.

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

y

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

Esos podrían combinarse para crear una única función para recuperar la cantidad de días en un mes si es necesario.

DanielM
fuente
0
SELECT DAY(SUBDATE(ADDDATE(CONCAT(YEAR(NOW()), '-', MONTH(NOW()), '-1'), INTERVAL 1 MONTH), INTERVAL 1 DAY))

Nice 'n' Simple y no requiere la creación de funciones

Pablo
fuente
Esto es para SQL Server; Nunca he oído hablar de una subdatefunción.
LittleBobbyTables - Au Revoir
0

La respuesta de Mehrdad Afshari es la más precisa, aparte de lo habitual, esta respuesta se basa en un enfoque matemático formal dado por Curtis McEnroe en su 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
AbhishekT
fuente
0

Para conseguir el no. de días en un mes podemos usar directamente Day () disponible en SQL.

Siga el enlace publicado al final de mi respuesta para SQL Server 2005/2008.

El siguiente ejemplo y el resultado son de 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')

Resultado en SQL Server SSMS

  (no column name)
1 31

Proceso:

Cuando se usa EOMONTH, cualquiera que sea el formato de fecha que usemos, se convierte al formato de fecha y hora del servidor SQL. Entonces, la salida de fecha de EOMONTH () será 2016-12-31 teniendo 2016 como año, 12 como mes y 31 como días. Esta salida cuando se pasa a Day () le da el recuento total de días en el mes.

Si queremos obtener el resultado instantáneo para verificar, podemos ejecutar directamente el siguiente código,

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

o

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

como referencia para trabajar en SQL Server 2005/2008/2012, siga el siguiente enlace externo ...

Encuentre el número de días en un mes en SQL

VSV AdityaSarma
fuente
0
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';

resultado: este mes 31

Próximo mes 30

ardem
fuente
esto no devuelve el número de días del mes
ashleedawg
Si lo hace. Pero solo para SQL Server 2012 y superior
Alberto Cláudio Mandlate
0
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]
Danyil Vlasov
fuente
0
RETURN day(dateadd(month, 12 * @year + @month - 22800, -1)) 
select day(dateadd(month, 12 * year(date) + month(date) - 22800, -1)) 
Milán Hettner
fuente
-1

Para cualquier fecha

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

consulta simple en SQLServer2012:

seleccionar día (('20-05-1951 22:00:00'))

Probé durante muchas fechas y siempre devuelve un resultado correcto

zied zelfani
fuente
2
SELECT DAY (CAST ('1951-05-20' AS DATE)) devuelve 20, que es la parte del día de la fecha. No devuelve el número de días del mes de mayo.
Even Mien
-1

seleccione primer_día = 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 + dateiff (dd, dateadd (dd, -1 * datepart (dd, getdate ()) + 1, getdate ()), dateadd (dd, -1 * datepart (dd, dateadd (mm, 1, getdate ())), dateadd (mm, 1, getdate ())))

reemplace cualquier fecha con getdate para obtener el número de meses en esa fecha en particular

Matricks
fuente
-1
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
Devilal
fuente
1
Hola y bienvenido a SO! Aunque el código puede hablar por sí mismo, proporcionar algunos detalles ayudaría a mejorar la calidad de su respuesta.
2018