可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I want to get the number of days in the month which the user specifies. I am using this it works for most months except for Feb and leap year. It shows 28 days and not 29. Can you solve this?
begin
declare @year int
declare @month int
select @year = 2012
select @month = DATEPART(mm,CAST('August'+ ' 2012' AS DATETIME))
select datediff(day,
dateadd(day, 0, dateadd(month, ((@year - 2012) * 12) + @month - 1, 0)),
dateadd(day, 0, dateadd(month, ((@year - 2012) * 12) + @month, 0))) as number_of_days
end
Or If not can you tell me another approach to do this. It should use @year
and @month
and the code to find the days can be any!
回答1:
If you need to do this from year and month (assuming both are integers) you could create a function as so:
CREATE FUNCTION dbo.DaysInMonth (@year INT, @Month INT)
RETURNS INT
AS
BEGIN
-- FIRST CONVERT THE YEAR AND MONTH TO A DATE BY CASTING TO CHAR
-- THEN CONCATENATING TO CREATE A STRING IN THE FORMAT yyyyMMdd
-- THIS DATEFORMAT IS CULTURE INSENSITIVE SO WILL WORK NO MATTER
-- WHAT YOUR REGIONAL SETTINGS ARE
DECLARE @Date DATE = CAST(
CAST(@Year AS CHAR(4))
+ RIGHT('0' + CAST(@Month AS VARCHAR(2)), 2)
+ '01' AS DATE);
-- USE ESTABLISHED METHODS OF GETTING 1ST OF THE MONTH AND FIRST OF
-- THE NEXT MONTH AND CALCULATE THE DIFFERENCE
RETURN DATEDIFF(DAY,
DATEADD(MONTH, DATEDIFF(MONTH, 0, @Date), 0),
DATEADD(MONTH, DATEDIFF(MONTH, 0, @Date) + 1, 0));
END
GO
-- TEST FUNCTION
SELECT DaysInMonth = dbo.DaysInMonth(2012, 2);
Example on SQL Fiddle
回答2:
This would be a good solution.
DECLARE @year INT,@month INT
SET @year = 2011
SET @month = 2
SELECT DAY(EOMONTH(DATEFROMPARTS(@year,@month,1)))
回答3:
Gareth solution modified for SQL Server 2005
CREATE FUNCTION dbo.DaysInMonth (@year INT, @Month INT)
RETURNS INT
AS
BEGIN
-- FIRST CONVERT THE YEAR AND MONTH TO A DATE BY CASTING TO CHAR
-- THEN CONCATENATING TO CREATE A STRING IN THE FORMAT yyyyMMdd
-- THIS DATEFORMAT IS CULTURE INSENSITIVE SO WILL WORK NO MATTER
-- WHAT YOUR REGIONAL SETTINGS ARE
DECLARE @Date datetime
SET @DATE = CAST(
CAST(@Year AS CHAR(4))
+ RIGHT('0' + CAST(@Month AS VARCHAR(2)), 2)
+ '01' AS DATETIME);
-- USE ESTABLISHED METHODS OF GETTING 1ST OF THE MONTH AND FIRST OF
-- THE NEXT MONTH AND CALCULATE THE DIFFERENCE
RETURN DATEDIFF(DAY,
DATEADD(MONTH, DATEDIFF(MONTH, 0, @Date), 0),
DATEADD(MONTH, DATEDIFF(MONTH, 0, @Date) + 1, 0));
END
GO
回答4:
Then all you need to do is take your desired inputs, cast them to a date stored in @date, and you can use the first example from that post without any changes. Using your code as-is, it only takes one more line of casting and then the first solution:
declare @year int
declare @month int
declare @date date
select @year = 2012
select @month = DATEPART(mm,CAST('august'+ ' 2012' AS DATETIME))
select @date = cast(cast(@month as varchar(20)) + '/1/' + cast(@year as varchar(4)) as datetime)
select @month, datediff(day, dateadd(day, 1-day(@date), @date),
dateadd(month, 1, dateadd(day, 1-day(@date), @date)))