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?
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?
Respuestas:
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)))
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
day
componente de la eomonth
salida.
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
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
--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 ...
Yo sugeriría:
SELECT DAY(EOMONTH(GETDATE()))
--- 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()))
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]
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
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]
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.
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)
aqui hay otro más...
Select Day(DateAdd(day, -Day(DateAdd(month, 1, getdate())),
DateAdd(month, 1, getdate())))
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.
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
subdate
función.
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
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 ...
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
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))
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)))
consulta simple en SQLServer2012:
seleccionar día (('20-05-1951 22:00:00'))
Probé durante muchas fechas y siempre devuelve un resultado correcto
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
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