Мне нужно определить количество дней в месяце для заданной даты в SQL Server.
Есть ли встроенная функция? Если нет, что я должен использовать в качестве пользовательской функции?
Мне нужно определить количество дней в месяце для заданной даты в SQL Server.
Есть ли встроенная функция? Если нет, что я должен использовать в качестве пользовательской функции?
Вы можете использовать следующее с первым днем указанного месяца:
datediff(day, @date, dateadd(month, 1, @date))
Чтобы он работал для каждой даты:
datediff(day, dateadd(day, 1-day(@date), @date),
dateadd(month, 1, dateadd(day, 1-day(@date), @date)))
В SQL Server 2012 вы можете использовать EOMONTH (Transact-SQL), чтобы получить последний день месяца, а затем вы можете использовать DAY (Transact-SQL), чтобы получить количество дней в месяце.
DECLARE @ADate DATETIME
SET @ADate = GETDATE()
SELECT DAY(EOMONTH(@ADate)) AS DaysInMonth
Самое элегантное решение: работает для любого @DATE
DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@DATE),0)))
Бросьте его в функцию или просто используйте его в строке. Это отвечает на исходный вопрос без лишнего барахла в других ответах.
примеры дат из других ответов:
SELECT DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,'1/31/2009'),0)))
Возвращает 31
SELECT DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,'2404-feb-15'),0)))
Возвращает 29
SELECT DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,'2011-12-22'),0)))
Возвращает 31
Намного проще... try day(eomonth(@Date))
--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)))
Лично, однако, я бы сделал UDF для него, если нет встроенной функции...
Я бы предложил:
SELECT DAY(EOMONTH(GETDATE()))
Этот код получает количество дней в текущем месяце:
SELECT datediff(dd,getdate(),dateadd(mm,1,getdate())) as datas
Измените 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()))
Вам нужно добавить функцию, но она простая. Я использую это:
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]
Решение 1. Найдите количество дней в любом месяце, в котором мы находимся в настоящее время
DECLARE @dt datetime
SET @dt = getdate()
SELECT @dt AS [DateTime],
DAY(DATEADD(mm, DATEDIFF(mm, -1, @dt), -1)) AS [Days in Month]
Решение 2. Найдите количество дней в данном комбинированном месяце месяца
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]
select datediff(day,
dateadd(day, 0, dateadd(month, ((2013 - 1900) * 12) + 3 - 1, 0)),
dateadd(day, 0, dateadd(month, ((2013 - 1900) * 12) + 3, 0))
)
Nice Простой и не требует создания каких-либо функций Work Fine
Вам нужно создать функцию, но она для вашего удобства. Он работает идеально, и я никогда не сталкивался с какими-либо ошибочными вычислениями, используя эту функцию.
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
Как это работает: вычитание числа дней даты с самой даты дает вам последний день предыдущего месяца. Таким образом, вам нужно добавить один месяц к указанной дате, вычесть номер дня и получить компонент дня результата.
select add_months(trunc(sysdate,'MM'),1) - trunc(sysdate,'MM') from dual;
Я поддержал Мехрдада, но это тоже работает.:)
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
Проверить
declare @testDT datetime;
set @testDT = '2404-feb-15';
select dbo.GetDaysInMonth(@testDT)
вот еще один...
Select Day(DateAdd(day, -Day(DateAdd(month, 1, getdate())),
DateAdd(month, 1, getdate())))
Я знаю, что этот вопрос старый, но я думал, что поделюсь тем, что использую.
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
Они могут быть объединены для создания одной функции для получения количества дней в месяце, если это необходимо.
SELECT DAY(SUBDATE(ADDDATE(CONCAT(YEAR(NOW()), '-', MONTH(NOW()), '-1'), INTERVAL 1 MONTH), INTERVAL 1 DAY))
Nice 'n' Simple и не требует создания каких-либо функций
Ответ Мехрдада Афшари наиболее точный, кроме обычного ответа этот вопрос основан на формальном математическом подходе, данном Кертисом МакЭнроем в его блоге 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
Чтобы получить номер. дней в месяц мы можем напрямую использовать День(), доступный в SQL.
Следуйте ссылке, опубликованной в конце моего ответа для SQL Server 2005/2008.
Следующий пример и результат из 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')
Результат в SSMS SQL Server
(no column name)
1 31
процесс:
Когда используется EOMONTH, в зависимости от формата даты, который мы используем, он преобразуется в формат DateTime SQL-сервера. Тогда выход даты EOMONTH() будет 2016-12-31, имея 2016 год как Год, 12 как Месяц и 31 как Дни. Этот выход при передаче в Day() дает вам общее количество дней в месяце.
Если мы хотим получить мгновенный результат для проверки, мы можем напрямую запустить приведенный ниже код,
select DAY(EOMONTH(convert(datetime,'08/12/2016',103)))
или
select DAY(EOMONTH(convert(datetime,getdate(),103)))
для ссылки на работу в SQL Server 2005/2008/2012, пожалуйста, следуйте следующей внешней ссылке...
DECLARE @m int
SET @m = 2
SELECT
@m AS [Month],
DATEDIFF(DAY,
DATEADD(DAY, 0, DATEADD(m, [email protected] -1, 0)),
DATEADD(DAY, 0, DATEADD(m,+ @m, 0))
) AS [Days in Month]
Для любой даты
select DateDiff(Day,@date,DateAdd(month,1,@date))
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)))
простой запрос в SQLServer2012:
выберите день (('20-05-1951 22:00:00'))
i тестировался на многие даты и всегда возвращал правильный результат
выберите first_day = dateadd (dd, -1 * datepart (dd, getdate()) + 1, getdate()), LAST_DAY = DateAdd (дд, -1 * DatePart (дд, DateAdd (мм, 1, GETDATE())), DateAdd (мм, 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 (мм, 1, GETDATE())))
заменить любую дату с помощью getdate, чтобы получить количество месяцев в эту конкретную дату
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';
результат: в этом месяце 31
Следующий месяц 30
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