我正在尝试将2007年12月1日等单独部分的日期转换为SQL Server 2005中的日期时间。我尝试过以下方法:
CAST(DATEPART(year, DATE)+'-'+ DATEPART(month, DATE) +'-'+ DATEPART(day, DATE) AS DATETIME)
但是这会导致错误的日期。将三个日期值转换为适当的datetime格式的正确方法是什么?
我正在尝试将2007年12月1日等单独部分的日期转换为SQL Server 2005中的日期时间。我尝试过以下方法:
CAST(DATEPART(year, DATE)+'-'+ DATEPART(month, DATE) +'-'+ DATEPART(day, DATE) AS DATETIME)
但是这会导致错误的日期。将三个日期值转换为适当的datetime格式的正确方法是什么?
当前回答
使用显式起点'19000101'更安全、更整洁。
create function dbo.fnDateTime2FromParts(@Year int, @Month int, @Day int, @Hour int, @Minute int, @Second int, @Nanosecond int)
returns datetime2
as
begin
-- Note! SQL Server 2012 includes datetime2fromparts() function
declare @output datetime2 = '19000101'
set @output = dateadd(year , @Year - 1900 , @output)
set @output = dateadd(month , @Month - 1 , @output)
set @output = dateadd(day , @Day - 1 , @output)
set @output = dateadd(hour , @Hour , @output)
set @output = dateadd(minute , @Minute , @output)
set @output = dateadd(second , @Second , @output)
set @output = dateadd(ns , @Nanosecond , @output)
return @output
end
其他回答
SQL Server 2012有一个令人期待已久的新DATEFROMPARTS函数(如果日期无效,它将引发错误-我对基于dateadd的解决方案的主要反对意见):
http://msdn.microsoft.com/en-us/library/hh213228.aspx
DATEFROMPARTS(ycolumn, mcolumn, dcolumn)
or
DATEFROMPARTS(@y, @m, @d)
或者只使用一个dateadd函数:
DECLARE @day int, @month int, @year int
SELECT @day = 4, @month = 3, @year = 2011
SELECT dateadd(mm, (@year - 1900) * 12 + @month - 1 , @day - 1)
对于低于12的SQL Server版本,我可以建议使用SET DATEFORMAT结合使用CAST
-- 26 February 2015
SET DATEFORMAT dmy
SELECT CAST('26-2-2015' AS DATE)
SET DATEFORMAT ymd
SELECT CAST('2015-2-26' AS DATE)
如何创建这些字符串取决于你
试试这个:
Declare @DayOfMonth TinyInt Set @DayOfMonth = 13
Declare @Month TinyInt Set @Month = 6
Declare @Year Integer Set @Year = 2006
-- ------------------------------------
Select DateAdd(day, @DayOfMonth - 1,
DateAdd(month, @Month - 1,
DateAdd(Year, @Year-1900, 0)))
It works as well, has added benefit of not doing any string conversions, so it's pure arithmetic processing (very fast) and it's not dependent on any date format This capitalizes on the fact that SQL Server's internal representation for datetime and smalldatetime values is a two part value the first part of which is an integer representing the number of days since 1 Jan 1900, and the second part is a decimal fraction representing the fractional portion of one day (for the time) --- So the integer value 0 (zero) always translates directly into Midnight morning of 1 Jan 1900...
或者,感谢@brinary的建议,
Select DateAdd(yy, @Year-1900,
DateAdd(m, @Month - 1, @DayOfMonth - 1))
2014年10月编辑。正如@cade Roux所指出的,SQL 2012现在有一个内置函数: DATEFROMPARTS(年,月,日) 这是一样的。
编辑2016年10月3日,(感谢@bambams注意到这一点,@brinary修复了它),最后的解决方案,由@brinary提出。除非先执行年份加法,否则似乎对闰年不起作用
select dateadd(month, @Month - 1,
dateadd(year, @Year-1900, @DayOfMonth - 1));
Sql Server 2012有一个函数,它将根据部件(DATEFROMPARTS)创建日期。对于我们其他人来说,这是我创建的一个db函数,它将确定部件的日期(谢谢@Charles)…
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[func_DateFromParts]'))
DROP FUNCTION [dbo].[func_DateFromParts]
GO
CREATE FUNCTION [dbo].[func_DateFromParts]
(
@Year INT,
@Month INT,
@DayOfMonth INT,
@Hour INT = 0, -- based on 24 hour clock (add 12 for PM :)
@Min INT = 0,
@Sec INT = 0
)
RETURNS DATETIME
AS
BEGIN
RETURN DATEADD(second, @Sec,
DATEADD(minute, @Min,
DATEADD(hour, @Hour,
DATEADD(day, @DayOfMonth - 1,
DATEADD(month, @Month - 1,
DATEADD(Year, @Year-1900, 0))))))
END
GO
你可以这样称呼它……
SELECT dbo.func_DateFromParts(2013, 10, 4, 15, 50, DEFAULT)
返回……
2013-10-04 15:50:00.000