Wie bestimme ich die Anzahl der Tage in einem Monat in SQL Server?

95

Ich muss die Anzahl der Tage in einem Monat für ein bestimmtes Datum in SQL Server bestimmen.

Gibt es eine eingebaute Funktion? Wenn nicht, was soll ich als benutzerdefinierte Funktion verwenden?

Sogar Mien
quelle

Antworten:

115

Mit dem ersten Tag des angegebenen Monats können Sie Folgendes verwenden:

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

Damit es für jedes Datum funktioniert:

datediff(day, dateadd(day, 1-day(@date), @date),
              dateadd(month, 1, dateadd(day, 1-day(@date), @date)))
Mehrdad Afshari
quelle
2
Wie Stan sagt, führt dies in einigen Fällen zu ungenauen Ergebnissen
DJ.
3
meinst du nicht: datiert (tag, dateadd (tag, 1 tag (@date), @date), dateadd (monat, 1, dateadd (tag, 1 tag (@date), @date))
feihtthief
3
Es ist ein seltener Eckfall, aber ich bin gerade darauf gestoßen: Dies wird einen Fehler für Dezember 9999 auslösen.
Heinzi
1
Dies funktioniert für kein Datum im Dezember 9999. Der Datumstyp wird überlaufen. Dies funktionierte für mich 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
Alle hier genannten Lösungen verblassen im Vergleich zur Eleganz der Antwort von @Mikael Eriksson . Dies funktioniert immer dann, wenn ein gültiges Datum ohne verrückte Problemumgehungen für Nischenfälle bereitgestellt wird und der Code viel einfacher ist. Ich würde jedem auf T-SQL-Stick empfehlen, die dayKomponente der eomonthAusgabe zu erhalten.
bsplosion
148

In SQL Server 2012 können Sie EOMONTH (Transact-SQL) verwenden , um den letzten Tag des Monats abzurufen, und dann können Sie DAY (Transact-SQL) verwenden , um die Anzahl der Tage im Monat abzurufen .

DECLARE @ADate DATETIME

SET @ADate = GETDATE()

SELECT DAY(EOMONTH(@ADate)) AS DaysInMonth
Mikael Eriksson
quelle
1
Und wenn Sie die Anzahl der Tage in einem bestimmten Zeitraum benötigen, können Sie auch die DATEFROMPARTS-Methode verwenden. Der obige Code würde SELECT DAY (EOMONTH (DATEFROMPARTS (@year, @month, 1))) AS DaysInMonth
nmariot
Die Schönheit dieser Lösung kommt ins Spiel, wenn @ADate ein komplexer berechneter Wert ist! +1
Stefan Steiger
Vielen vielen Dank!
Rejwanul Reja
27

Die eleganteste Lösung: funktioniert für jedes @DATE

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

Wirf es in eine Funktion oder verwende es einfach inline. Dies beantwortet die ursprüngliche Frage ohne all den zusätzlichen Müll in den anderen Antworten.

Beispiele für Daten aus anderen Antworten:

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

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

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

Daniel Davis
quelle
22

Viel einfacher ... versuchen day(eomonth(@Date))

Javier
quelle
1
Ich denke, deine Antwort ist die beste, so einfach. Vielen Dank!
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)))

Persönlich würde ich eine UDF dafür erstellen, wenn es keine eingebaute Funktion gibt ...

Brimstedt
quelle
5

Ich würde vorschlagen:

SELECT DAY(EOMONTH(GETDATE()))
gvschijndel
quelle
datepart gibt nicht die Anzahl der Tage zurück und Ihre Antwort ist auch falsch
TheGameiswar
Hat für mich funktioniert, aber sicher wäre die Verwendung der
Tagesfunktion
2
Diese Antwort ist fast identisch mit der unten stehenden mit 75. Stimmen.
Hila DG
3

Mit diesem Code erhalten Sie die Anzahl der Tage im aktuellen Monat:

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

Wechseln Sie getdate()zu dem Datum, für das Sie Tage zählen müssen.

Prashant
quelle
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
quelle
1

Lösung 1: Ermitteln Sie die Anzahl der Tage in dem Monat, in dem wir uns gerade befinden

DECLARE @dt datetime
SET     @dt = getdate()

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

Lösung 2: Ermitteln Sie die Anzahl der Tage in einer bestimmten Monat-Jahr-Kombination

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
quelle
1

Sie müssen eine Funktion hinzufügen, aber es ist eine einfache. Ich benutze das:

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
quelle
1
Die Kombination von DATEDIFF und DATEADD funktioniert übrigens nicht immer. Wenn Sie ein Datum vom 31.01.2009 eingeben, gibt der DATEADD den 28.02.2009 zurück und der DATEDIFF gibt Ihnen 28 statt 31.
Wie überprüfe ich, was ich ausführen soll, um die Tage in einem Monat zu überprüfen?
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
quelle
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))
        )

Schön Einfach und erfordert keine Erstellung von Funktionen

pradeep
quelle
1

Sie müssen eine Funktion erstellen, dies dient jedoch Ihrer eigenen Bequemlichkeit. Es funktioniert perfekt und ich habe mit dieser Funktion keine fehlerhaften Berechnungen festgestellt.

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

So funktioniert es: Wenn Sie die Tagesnummer des Datums vom Datum selbst abziehen, erhalten Sie den letzten Tag des Vormonats. Sie müssen also einen Monat zum angegebenen Datum hinzufügen, die Tageszahl subtrahieren und die Tageskomponente des Ergebnisses erhalten.

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

Ich habe Mehrdad positiv bewertet, aber das funktioniert auch. :) :)

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

Zu testen

declare @testDT datetime;

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

select dbo.GetDaysInMonth(@testDT)
Feihtthief
quelle
0

hier ist ein anderes...

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

Ich weiß, dass diese Frage alt ist, aber ich dachte, ich würde teilen, was ich benutze.

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

und

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

Diese können kombiniert werden, um eine einzelne Funktion zu erstellen, mit der bei Bedarf die Anzahl der Tage in einem Monat abgerufen werden kann.

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

Nice 'n' Simple und erfordert keine Erstellung von Funktionen

Paul
quelle
Dies ist für SQL Server. Ich habe noch nie von einer subdateFunktion gehört.
LittleBobbyTables - Au Revoir
0

Die Antwort von Mehrdad Afshari ist am genauesten. Abgesehen von der üblichen Antwort basiert diese Antwort auf einem formalen mathematischen Ansatz, den Curtis McEnroe in seinem Blog https://cmcenroe.me/2014/12/05/days-in-month-formula.html angegeben hat

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
quelle
0

Um die Nr. Zu bekommen. von Tagen in einem Monat können wir Day () direkt verwenden, das in SQL verfügbar ist.

Folgen Sie dem Link am Ende meiner Antwort für SQL Server 2005/2008.

Das folgende Beispiel und das Ergebnis stammen aus 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')

Ergebnis in SQL Server SSMS

  (no column name)
1 31

Prozess:

Wenn EOMONTH verwendet wird, wird das von uns verwendete Datumsformat in das DateTime-Format von SQL-Server konvertiert. Dann ist die Datumsausgabe von EOMONTH () der 31.12.2016 mit 2016 als Jahr, 12 als Monat und 31 als Tagen. Wenn diese Ausgabe an Day () übergeben wird, erhalten Sie die Gesamtzahl der Tage im Monat.

Wenn wir das sofortige Ergebnis für die Überprüfung erhalten möchten, können wir den folgenden Code direkt ausführen:

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

oder

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

Um auf die Arbeit in SQL Server 2005/2008/2012 zu verweisen, folgen Sie bitte dem folgenden externen Link ...

Finden Sie die Anzahl der Tage in einem Monat in SQL

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

Ergebnis: Diesen Monat 31

Nächster Monat 30

ardem
quelle
Dies gibt nicht die Anzahl der Tage im Monat zurück
ashleedawg
Ja tut es. Aber nur für SQL Server 2012 und höher
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
quelle
0
RETURN day(dateadd(month, 12 * @year + @month - 22800, -1)) 
select day(dateadd(month, 12 * year(date) + month(date) - 22800, -1)) 
Milan Hettner
quelle
-1

Für jedes Datum

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

einfache Abfrage in SQLServer2012:

Tag auswählen (('20-05-1951 22:00:00'))

Ich habe für viele Daten getestet und es wird immer ein korrektes Ergebnis zurückgegeben

zied zelfani
quelle
2
SELECT DAY (CAST ('1951-05-20' AS DATE)) gibt 20 zurück, was der Tagesteil des Datums ist. Die Anzahl der Tage im Monat Mai wird nicht zurückgegeben.
Sogar Mien
-1

Wählen Sie 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 + dateiff (dd, dateadd (dd, -1 * datepart (dd, getdate ()) + 1, getdate ()), dateadd (dd, -1 * Datumsteil (dd, dateadd (mm, 1, getdate ())), dateadd (mm, 1, getdate ()))

Ersetzen Sie ein Datum durch getdate, um die Anzahl der Monate in diesem bestimmten Datum zu erhalten

Matricks
quelle
-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
Teufel
quelle
1
Hallo und willkommen bei SO! Obwohl der Code möglicherweise für sich selbst spricht und einige Details enthält, würde dies die Qualität Ihrer Antwort verbessern!
Mrun