Devo determinare il numero di giorni in un mese per una determinata data in SQL Server.
C'è una funzione integrata? In caso contrario, cosa dovrei usare come funzione definita dall'utente?
Devo determinare il numero di giorni in un mese per una determinata data in SQL Server.
C'è una funzione integrata? In caso contrario, cosa dovrei usare come funzione definita dall'utente?
Risposte:
È possibile utilizzare quanto segue con il primo giorno del mese specificato:
datediff(day, @date, dateadd(month, 1, @date))
Per farlo funzionare per ogni data:
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 eomonth
dell'output.
In SQL Server 2012 è possibile utilizzare EOMONTH (Transact-SQL) per ottenere l'ultimo giorno del mese, quindi è possibile utilizzare DAY (Transact-SQL) per ottenere il numero di giorni del mese.
DECLARE @ADate DATETIME
SET @ADate = GETDATE()
SELECT DAY(EOMONTH(@ADate)) AS DaysInMonth
Soluzione più elegante: funziona per qualsiasi @DATE
DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@DATE),0)))
Inseriscilo in una funzione o usalo semplicemente in linea. Questo risponde alla domanda originale senza tutta la spazzatura extra nelle altre risposte.
esempi di date da altre risposte:
SELECT DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,'1/31/2009'),0)))
Restituisce 31
SELECT DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,'2404-feb-15'),0)))
Restituisce 29
SELECT DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,'2011-12-22'),0)))
Restituisce 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)))
Personalmente, però, creerei un UDF se non ci fosse una funzione incorporata ...
Io suggerirei:
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()))
Soluzione 1: trova il numero di giorni nel mese in cui ci troviamo attualmente
DECLARE @dt datetime
SET @dt = getdate()
SELECT @dt AS [DateTime],
DAY(DATEADD(mm, DATEDIFF(mm, -1, @dt), -1)) AS [Days in Month]
Soluzione 2: trova il numero di giorni in una determinata combinazione mese-anno
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]
Devi aggiungere una funzione, ma è semplice. Io uso questo:
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]
Devi creare una funzione, ma è per tua comodità. Funziona perfettamente e non ho mai riscontrato calcoli difettosi utilizzando questa funzione.
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
Come funziona: sottraendo il numero del giorno della data dalla data stessa si ottiene l'ultimo giorno del mese precedente. Quindi, è necessario aggiungere un mese alla data specificata, sottrarre il numero del giorno e ottenere il componente del giorno del risultato.
Ho votato positivamente Mehrdad, ma funziona anche questo. :)
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
Testare
declare @testDT datetime;
set @testDT = '2404-feb-15';
select dbo.GetDaysInMonth(@testDT)
eccone un altro ...
Select Day(DateAdd(day, -Day(DateAdd(month, 1, getdate())),
DateAdd(month, 1, getdate())))
So che questa domanda è vecchia ma ho pensato di condividere ciò che sto 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
e
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
Questi potrebbero essere combinati per creare una singola funzione per recuperare il numero di giorni in un mese, se necessario.
SELECT DAY(SUBDATE(ADDDATE(CONCAT(YEAR(NOW()), '-', MONTH(NOW()), '-1'), INTERVAL 1 MONTH), INTERVAL 1 DAY))
Nice 'n' Simple e non richiede la creazione di alcuna funzione
subdate
funzione.
La risposta di Mehrdad Afshari è la più accurata, a parte il solito questa risposta si basa sull'approccio matematico formale fornito da Curtis McEnroe nel suo 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
Per ottenere il no. di giorni in un mese possiamo utilizzare direttamente Day () disponibile in SQL.
Segui il link pubblicato alla fine della mia risposta per SQL Server 2005/2008.
L'esempio seguente e il risultato provengono da 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')
Risultato in SQL Server SSMS
(no column name)
1 31
Processi:
Quando viene utilizzato EOMONTH, qualunque sia il formato della data che usiamo viene convertito nel formato DateTime di SQL-server. Quindi l'output della data di EOMONTH () sarà 2016-12-31 con 2016 come anno, 12 come mese e 31 come giorni. Questo output, quando passato in Day (), fornisce il conteggio dei giorni totali nel mese.
Se vogliamo ottenere il risultato istantaneo per il controllo, possiamo eseguire direttamente il codice seguente,
select DAY(EOMONTH(convert(datetime,'08/12/2016',103)))
o
select DAY(EOMONTH(convert(datetime,getdate(),103)))
per riferimento al funzionamento in SQL Server 2005/2008/2012, seguire il seguente collegamento esterno ...
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';
risultato: questo mese 31
Mese prossimo 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)))
query semplice in SQLServer2012:
seleziona il giorno (('20-05-1951 22:00:00'))
ho provato per molte date e restituisce sempre un risultato corretto
selezionare first_day = 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 + dateadd (dd, dateadd (dd, -1 * datepart (dd, getdate ()) + 1, getdate ()), dateadd (dd, -1 * datepart (dd, dateadd (mm, 1, getdate ())), dateadd (mm, 1, getdate ())))
sostituire qualsiasi data con getdate per ottenere il numero di mesi in quella data particolare
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