Làm thế nào để xác định số ngày trong một tháng trong SQL Server?


95

Tôi cần xác định số ngày trong tháng cho một ngày nhất định trong SQL Server.

Có chức năng tích hợp sẵn không? Nếu không, tôi nên sử dụng hàm do người dùng định nghĩa là gì?

Câu trả lời:


115

Bạn có thể sử dụng như sau với ngày đầu tiên của tháng được chỉ định:

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

Để làm cho nó hoạt động cho mọi ngày:

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

2
Giống như Stan nói, điều này sẽ cho kết quả không chính xác trong một số trường hợp
DJ.

3
ý bạn không phải là: dateiff (day, dateadd (day, 1-day (@date), @date), dateadd (month, 1, dateadd (day, 1-day (@date), @date)))
feihtthief

3
Đó là một trường hợp góc hiếm, nhưng tôi chỉ vấp vào nó: Điều này sẽ ném ra một lỗi for December 9999.
Heinzi

1
Điều này không hoạt động cho bất kỳ ngày nào trong tháng 12 năm 9999. Bạn nhận được thông tin thừa về loại ngày. Điều này làm việc cho tôi trong 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
Tất cả các giải pháp được đề cập ở đây đều nhạt so với sự sang trọng trong câu trả lời của @Mikael Eriksson . Điều đó hoạt động bất cứ khi nào một ngày hợp lệ được cung cấp mà không có các giải pháp thay thế điên rồ cho các trường hợp thích hợp và là mã đơn giản hơn nhiều - tôi thực sự khuyên mọi người trên T-SQL nên lấy daythành phần của eomonthđầu ra.
nổ

148

Trong SQL Server 2012, bạn có thể sử dụng EOMONTH (Transact-SQL) để lấy ngày cuối cùng của tháng và sau đó, bạn có thể sử dụng DAY (Transact-SQL) để lấy số ngày trong tháng.

DECLARE @ADate DATETIME

SET @ADate = GETDATE()

SELECT DAY(EOMONTH(@ADate)) AS DaysInMonth

1
Và nếu bạn cần số ngày nhất định, bạn cũng có thể sử dụng phương pháp DATEFROMPARTS. Đoạn mã trên sẽ trở thành CHỌN NGÀY (EOMONTH (DATEFROMPARTS (@year, @month, 1))) AS DaysInMonth
nmariot

Vẻ đẹp của giải pháp này phát huy tác dụng nếu @ADate là một giá trị được tính toán phức tạp! +1
Stefan Steiger

Cảm ơn bạn rất nhiều!
Rejwanul Reja

27

Giải pháp thanh lịch nhất: hoạt động cho bất kỳ @DATE nào

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

Ném nó vào một hàm hoặc chỉ sử dụng nó nội tuyến. Câu trả lời này trả lời câu hỏi ban đầu mà không có tất cả những thứ thừa trong các câu trả lời khác.

ví dụ cho ngày tháng từ các câu trả lời khác:

SELECT DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,'1/31/2009'),0))) Trả về 31

SELECT DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,'2404-feb-15'),0))) Trả về 29

SELECT DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,'2011-12-22'),0))) Trả về 31


22

Đơn giản hơn nhiều ... hãy thử day(eomonth(@Date))


1
Tôi nghĩ câu trả lời của bạn là câu trả lời hay nhất, rất đơn giản. Cảm ơn!
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)))

Cá nhân tôi mặc dù vậy, tôi sẽ tạo một UDF cho nó nếu không có chức năng tích hợp sẵn ...


5

Tôi sẽ đề nghị:

SELECT DAY(EOMONTH(GETDATE()))

datepart không trả về số ngày và câu trả lời của bạn cũng sai
TheGameiswar

Làm việc cho tôi, nhưng chắc chắn sử dụng chức năng ngày sẽ là một câu trả lời sạch hơn
gvschijndel

2
câu trả lời này gần giống với câu trả lời bên dưới với số phiếu bầu là 75.
Hila DG

3

Mã này cung cấp cho bạn số ngày trong tháng hiện tại:

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

Thay đổi getdate()ngày bạn cần đếm ngày.


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

Giải pháp 1: Tìm số ngày trong tháng mà chúng ta hiện đang ở

DECLARE @dt datetime
SET     @dt = getdate()

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

Giải pháp 2: Tìm số ngày trong một tổ hợp tháng-năm nhất định

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

Bạn cần thêm một hàm, nhưng đó là một hàm đơn giản. Tôi sử dụng cái này:

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
Nhân tiện, sự kết hợp giữa DATEDIFF và DATEADD không phải lúc nào cũng hoạt động. Nếu bạn đặt ngày là 1/31/2009 vào đó, DATEADD sẽ trả về 28/2/2009 và DATEDIFF cho bạn là 28, thay vì 31.

làm thế nào để kiểm tra, tôi có nghĩa là những gì để thực hiện để kiểm tra các ngày trong một tháng ??
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))
        )

Đẹp Đơn giản và không yêu cầu tạo bất kỳ chức năng nào Hoạt động tốt


1

Bạn cần tạo một hàm, nhưng nó là vì sự thuận tiện của riêng bạn. Nó hoạt động hoàn hảo và tôi chưa bao giờ gặp phải bất kỳ tính toán bị lỗi nào khi sử dụng chức năng này.

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ách hoạt động: trừ số ngày của ngày cho chính ngày đó sẽ cho bạn ngày cuối cùng của tháng trước. Vì vậy, bạn cần thêm một tháng vào ngày đã cho, trừ số ngày và nhận thành phần ngày của kết quả.


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

0

Tôi đã ủng hộ Mehrdad, nhưng điều này cũng hoạt động. :)

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

Để kiểm tra

declare @testDT datetime;

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

select dbo.GetDaysInMonth(@testDT)

0

đây là một số khác...

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

0

Tôi biết câu hỏi này đã cũ nhưng tôi nghĩ tôi sẽ chia sẻ những gì tôi đang sử dụng.

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

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

Chúng có thể được kết hợp để tạo ra một hàm duy nhất để truy xuất số ngày trong tháng nếu cần.


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

Đẹp 'n' Đơn giản và không yêu cầu tạo bất kỳ chức năng nào


Điều này dành cho SQL Server; Tôi chưa bao giờ nghe nói về một subdatechức năng.
LittleBobbyTables - Au Revoir

0

Câu trả lời của Mehrdad Afshari là câu trả lời chính xác nhất, ngoài thông thường, câu trả lời này dựa trên phương pháp toán học chính thức do Curtis McEnroe đưa ra trong blog của anh ấy 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

Để có được không. ngày trong tháng, chúng ta có thể sử dụng trực tiếp Day () có sẵn trong SQL.

Làm theo liên kết được đăng ở cuối câu trả lời của tôi cho SQL Server 2005/2008.

Ví dụ sau và kết quả là từ 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')

Kết quả trong SQL Server SSMS

  (no column name)
1 31

Quá trình:

Khi sử dụng EOMONTH, bất kỳ định dạng ngày tháng nào chúng tôi sử dụng đều được chuyển đổi thành định dạng DateTime của SQL-server. Sau đó, đầu ra ngày của EOMONTH () sẽ là 2016-12-31 với 2016 là Năm, 12 là Tháng và 31 là Ngày. Kết quả này khi được chuyển vào Day (), nó sẽ cho bạn tổng số ngày trong tháng.

Nếu chúng tôi muốn nhận được kết quả tức thì để kiểm tra, chúng tôi có thể chạy trực tiếp đoạn mã dưới đây,

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

hoặc là

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

để tham khảo cách làm việc trong SQL Server 2005/2008/2012, vui lòng theo liên kết bên ngoài sau ...

Tìm số ngày trong tháng trong 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';

kết quả: Tháng này 31

Tháng tới 30


điều này không trả lại số ngày trong tháng
ashleedawg

Đúng vậy. Nhưng chỉ dành cho SQL Server 2012 trở lên
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

Cho bất kỳ ngày nào

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

truy vấn đơn giản trong SQLServer2012:

chọn ngày (('20-05-1951 22:00:00'))

tôi đã kiểm tra nhiều ngày và nó luôn trả về một kết quả chính xác


2
SELECT DAY (CAST ('1951-05-20' AS DATE)) trả về 20 là phần ngày của ngày. Nó không trả về số ngày trong tháng.
Even Mien 19:16

-1

select 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 * datepart (dd, dateadd (mm, 1, getdate ())), dateadd (mm, 1, getdate ())))

thay thế bất kỳ ngày nào bằng getdate để lấy số tháng trong ngày cụ thể đó


-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
Xin chào và chào mừng đến với SO! Mặc dù mã có thể tự nói, nhưng việc cung cấp một số chi tiết sẽ giúp cải thiện chất lượng câu trả lời của bạn!
mrun
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.