Come determinare il numero di giorni in un mese in SQL Server?


Risposte:


115

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

2
Come dice Stan, in alcuni casi questo darà risultati imprecisi
DJ.

3
non intendi: dateadd (day, dateadd (day, 1-day (@date), @date), dateadd (month, 1, dateadd (day, 1-day (@date), @date)))
feihtthief

3
È un raro caso d'angolo, ma mi sono imbattuto in esso: questo genererà un errore per dicembre 9999.
Heinzi

1
Questo non funziona per nessuna data nel dicembre 9999. Ottieni overflow sul tipo di data. Questo ha funzionato per me in 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
Tutte le soluzioni qui menzionate impallidiscono rispetto all'eleganza della risposta di @Mikael Eriksson . Funziona ogni volta che viene fornita una data valida senza soluzioni alternative folli per casi di nicchia ed è un codice molto più semplice: consiglio vivamente a chiunque abbia una chiavetta T-SQL di ottenere il daycomponente eomonthdell'output.
esplosione

148

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

1
E se hai bisogno del numero di giorni in un dato, potresti anche usare il metodo DATEFROMPARTS. Il codice sopra diventerebbe SELECT DAY (EOMONTH (DATEFROMPARTS (@year, @month, 1))) AS DaysInMonth
nmariot

La bellezza di questa soluzione entra in gioco se @ADate è un valore calcolato complesso! +1
Stefan Steiger

Grazie mille!
Rejwanul Reja

27

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


22

Molto più semplice ... prova day(eomonth(@Date))


1
Penso che la tua risposta sia la migliore, così semplice. Grazie!
Fino al

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

Personalmente, però, creerei un UDF se non ci fosse una funzione incorporata ...


5

Io suggerirei:

SELECT DAY(EOMONTH(GETDATE()))

datepart non restituisce il numero di giorni e anche la tua risposta è sbagliata
TheGameiswar

Ha funzionato per me, ma sicuramente usare la funzione giorno sarebbe una risposta più pulita
gvschijndel

2
questa risposta è quasi identica a quella sotto con voti di 75.
Hila DG

3

Questo codice ti dà il numero di giorni nel mese corrente:

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

Passa getdate()alla data per la quale devi contare i giorni.


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

1

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]

1

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

1
La combinazione di DATEDIFF e DATEADD, comunque, non sempre funziona. Se inserisci una data del 31/1/2009, DATEADD restituirà 28/2/2009 e DATEDIFF ti darà 28, anziché 31.

come controllare, intendo cosa eseguire per controllare i giorni in un mese ??
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]

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

Bello Semplice e non richiede la creazione di alcuna funzione Funziona bene


1

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.


1
select add_months(trunc(sysdate,'MM'),1) -  trunc(sysdate,'MM') from dual;

0

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)

0

eccone un altro ...

Select Day(DateAdd(day, -Day(DateAdd(month, 1, getdate())), 
                         DateAdd(month, 1, getdate())))

0

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.


0
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


Questo è per SQL Server; Non ho mai sentito parlare di una subdatefunzione.
LittleBobbyTables - Au Revoir,

0

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

0

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

Trova il numero di giorni in un mese in SQL


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

risultato: questo mese 31

Mese prossimo 30


questo non restituisce il numero di giorni del mese
ashleedawg

Sì lo fa. Ma solo per SQL Server 2012 e versioni successive
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]

0
RETURN day(dateadd(month, 12 * @year + @month - 22800, -1)) 
select day(dateadd(month, 12 * year(date) + month(date) - 22800, -1)) 

-1

Per qualsiasi data

select DateDiff(Day,@date,DateAdd(month,1,@date))

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

-1

query semplice in SQLServer2012:

seleziona il giorno (('20-05-1951 22:00:00'))

ho provato per molte date e restituisce sempre un risultato corretto


2
SELECT DAY (CAST ('1951-05-20' AS DATE)) restituisce 20 che è la porzione del giorno della data. Non restituisce il numero di giorni nel mese di maggio.
Anche Mien

-1

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


-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

1
Ciao e benvenuto in SO! Sebbene il codice possa parlare da solo, fornire alcuni dettagli aiuterebbe a migliorare la qualità della tua risposta!
mrun
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.