我想像这样转换一个字符串:
'10/15/2008 10:06:32 PM'
到 Sql Server 中的等效 DATETIME 值。
在 Oracle 中,我会这样说:
TO_DATE('10/15/2008 10:06:32 PM','MM/DD/YYYY HH:MI:SS AM')
这个问题意味着我必须将字符串解析为一种标准格式,然后使用其中一种代码进行转换。对于如此平凡的操作来说,这似乎很可笑。有没有更简单的方法?
试试这个
Cast('7/7/2011' as datetime)
和
Convert(DATETIME, '7/7/2011', 101)
有关详细信息,请参阅CAST 和 CONVERT (Transact-SQL)。
通过您的查询处理器运行它。它像这样格式化日期和/或时间,其中之一应该给你你正在寻找的东西。不难适应:
Declare @d datetime
select @d = getdate()
select @d as OriginalDate,
convert(varchar,@d,100) as ConvertedDate,
100 as FormatValue,
'mon dd yyyy hh:miAM (or PM)' as OutputFormat
union all
select @d,convert(varchar,@d,101),101,'mm/dd/yy'
union all
select @d,convert(varchar,@d,102),102,'yy.mm.dd'
union all
select @d,convert(varchar,@d,103),103,'dd/mm/yy'
union all
select @d,convert(varchar,@d,104),104,'dd.mm.yy'
union all
select @d,convert(varchar,@d,105),105,'dd-mm-yy'
union all
select @d,convert(varchar,@d,106),106,'dd mon yy'
union all
select @d,convert(varchar,@d,107),107,'Mon dd, yy'
union all
select @d,convert(varchar,@d,108),108,'hh:mm:ss'
union all
select @d,convert(varchar,@d,109),109,'mon dd yyyy hh:mi:ss:mmmAM (or PM)'
union all
select @d,convert(varchar,@d,110),110,'mm-dd-yy'
union all
select @d,convert(varchar,@d,111),111,'yy/mm/dd'
union all
select @d,convert(varchar,@d,12),12,'yymmdd'
union all
select @d,convert(varchar,@d,112),112,'yyyymmdd'
union all
select @d,convert(varchar,@d,113),113,'dd mon yyyy hh:mm:ss:mmm(24h)'
union all
select @d,convert(varchar,@d,114),114,'hh:mi:ss:mmm(24h)'
union all
select @d,convert(varchar,@d,120),120,'yyyy-mm-dd hh:mi:ss(24h)'
union all
select @d,convert(varchar,@d,121),121,'yyyy-mm-dd hh:mi:ss.mmm(24h)'
union all
select @d,convert(varchar,@d,126),126,'yyyy-mm-dd Thh:mm:ss:mmm(no spaces)'
在 SQL Server Denali 中,您将能够做一些接近您正在寻找的事情。但是您仍然不能只传递任何任意定义的古怪日期字符串并期望 SQL Server 能够适应。这是一个使用您在自己的答案中发布的内容的示例。FORMAT() 函数还可以接受语言环境作为可选参数 - 它基于 .Net 的格式,因此您希望看到的大多数(如果不是全部)标记格式都将存在。
DECLARE @d DATETIME = '2008-10-13 18:45:19';
-- returns Oct-13/2008 18:45:19:
SELECT FORMAT(@d, N'MMM-dd/yyyy HH:mm:ss');
-- returns NULL if the conversion fails:
SELECT TRY_PARSE(FORMAT(@d, N'MMM-dd/yyyy HH:mm:ss') AS DATETIME);
-- returns an error if the conversion fails:
SELECT PARSE(FORMAT(@d, N'MMM-dd/yyyy HH:mm:ss') AS DATETIME);
我强烈建议您采取更多控制措施并清理您的日期输入。让人们使用他们想要的任何格式在自由文本表单字段中键入日期的日子现在应该已经过去了。如果有人进入 2011 年 8 月 9 日是 8 月 9 日还是 9 月 8 日?如果您让他们在日历控件上选择日期,则应用程序可以控制格式。无论您如何尝试预测用户的行为,他们总是会想出一种更愚蠢的方式来输入您没有计划的日期。
不过,在 Denali 之前,我认为 @Ovidiu 提供了迄今为止最好的建议……通过实现您自己的 CLR 函数,这可以变得相当简单。然后,您可以根据需要为任意数量的古怪非标准格式编写 case/switch。
@dhergert 的更新:
SELECT TRY_PARSE('10/15/2008 10:06:32 PM' AS DATETIME USING 'en-us');
SELECT TRY_PARSE('15/10/2008 10:06:32 PM' AS DATETIME USING 'en-gb');
结果:
2008-10-15 22:06:32.000
2008-10-15 22:06:32.000
您仍然需要首先获得其他重要信息。您不能使用本机 T-SQL 来确定6/9/2012
是 6 月 9 日还是 9 月 6 日。
SQL Server (2005, 2000, 7.0) 没有任何灵活甚至不灵活的方式来获取字符串格式的任意结构化日期时间并将其转换为日期时间数据类型。
所谓“任意”,我的意思是“写它的人,虽然可能不是你或我或地球另一端的人,但会认为是直观且完全显而易见的形式。” 坦率地说,我不确定有没有这样的算法。
用这个:
SELECT convert(datetime, '2018-10-25 20:44:11.500', 121) -- yyyy-mm-dd hh:mm:ss.mmm
并参考官方文档中的表格获取转换代码。
对于这个问题,我使用的最佳解决方案是在 Sql Server 2005 中有一个 CLR 函数,它使用 DateTime.Parse 或 ParseExact 函数之一来返回具有指定格式的 DateTime 值。
简短的回答:
SELECT convert(date, '10/15/2011 00:00:00', 101) as [MM/dd/YYYY]
我花了一分钟才弄清楚这一点,所以在这里以防万一它可能对某人有所帮助:
在 SQL Server 2012 及更高版本中,您可以使用此功能:
SELECT DATEFROMPARTS(2013, 8, 19);
以下是我最终提取日期部分以放入此函数的方式:
select
DATEFROMPARTS(right(cms.projectedInstallDate,4),left(cms.ProjectedInstallDate,2),right( left(cms.ProjectedInstallDate,5),2)) as 'dateFromParts'
from MyTable
我知道这是一个邪恶的旧帖子,有很多答案,但很多人认为他们需要将它们分开并将它们重新组合在一起,或者他们坚持认为没有办法隐含地进行 OP 原始要求的转换.
为了查看并希望为其他有相同问题的人提供一个简单的答案,OP 询问如何将 '10/15/2008 10:06:32 PM' 转换为 DATETIME。现在,SQL Server 确实对时间转换有一些语言依赖性,但是如果语言是英语或类似的语言,这将成为一个简单的问题……只需进行转换,不要担心格式。例如(您可以使用 CONVERT 或 CAST)...
SELECT UsingCONVERT = CONVERT(DATETIME,'10/15/2008 10:06:32 PM')
,UsingCAST = CAST('10/15/2008 10:06:32 PM' AS DATETIME)
;
...这会产生以下答案,这两个答案都是正确的。
就像他们在电视广告中所说的那样,“但是等等!不要订购!无需额外费用,它可以做得更多!”
让我们看看使用 DATETIME 进行时间转换的真正威力,并部分检查称为 DATETIME2 的错误。查看 DATETIME 可以自动处理而 DATETIME2 不能处理的古怪格式。运行以下代码,看看...
--===== Set the language for this example.
SET LANGUAGE ENGLISH --Same a US-English
;
--===== Use a table constructor as if it were a table for this example.
SELECT *
,DateTimeCONVERT = TRY_CONVERT(DATETIME,StringDT)
,DateTimeCAST = TRY_CAST(StringDT AS DATETIME)
,DateTime2CONVERT = TRY_CONVERT(DATETIME2,StringDT)
,DateTime2CAST = TRY_CAST(StringDT AS DATETIME2)
FROM (
VALUES
('Same Format As In The OP' ,'12/16/2001 01:51:01 PM')
,('Almost Normal' ,'16 December, 2001 1:51:01 PM')
,('More Normal' ,'December 16, 2001 01:51:01 PM')
,('Time Up Front + Spaces' ,' 13:51:01 16 December 2001')
,('Totally Whacky Format #01' ,' 16 13:51:01 December 2001')
,('Totally Whacky Format #02' ,' 16 December 13:51:01 2001 ')
,('Totally Whacky Format #03' ,' 16 December 01:51:01 PM 2001 ')
,('Totally Whacky Format #04' ,' 2001 16 December 01:51:01 PM ')
,('Totally Whacky Format #05' ,' 2001 December 01:51:01 PM 16 ')
,('Totally Whacky Format #06' ,' 2001 16 December 01:51:01 PM ')
,('Totally Whacky Format #07' ,' 2001 16 December 13:51:01 PM ')
,('Totally Whacky Format #08' ,' 2001 16 13:51:01 PM December ')
,('Totally Whacky Format #09' ,' 13:51:01 PM 2001.12/16 ')
,('Totally Whacky Format #10' ,' 13:51:01 PM 2001.December/16 ')
,('Totally Whacky Format #11' ,' 13:51:01 PM 2001.Dec/16 ')
,('Totally Whacky Format #12' ,' 13:51:01 PM 2001.Dec.16 ')
,('Totally Whacky Format #13' ,' 13:51:01 PM 2001/Dec.16')
,('Totally Whacky Format #14' ,' 13:51:01 PM 2001 . 12/16 ')
,('Totally Whacky Format #15' ,' 13:51:01 PM 2001 . December / 16 ')
,('Totally Whacky Format #16' ,' 13:51:01 PM 2001 . Dec / 16 ')
,('Totally Whacky Format #17' ,' 13:51:01 PM 2001 . Dec . 16 ')
,('Totally Whacky Format #18' ,' 13:51:01 PM 2001 / Dec . 16')
,('Totally Whacky Format #19' ,' 13:51:01 PM 2001 . Dec - 16 ')
,('Totally Whacky Format #20' ,' 13:51:01 PM 2001 - Dec - 16 ')
,('Totally Whacky Format #21' ,' 13:51:01 PM 2001 - Dec . 16')
,('Totally Whacky Format #22' ,' 13:51:01 PM 2001 - Dec / 16 ')
,('Totally Whacky Format #23' ,' 13:51:01 PM 2001 / Dec - 16')
,('Just the year' ,' 2001 ')
,('YYYYMM' ,' 200112 ')
,('YYYY MMM' ,'2001 Dec')
,('YYYY-MMM' ,'2001-Dec')
,('YYYY . MMM' ,'2001 . Dec')
,('YYYY / MMM' ,'2001 / Dec')
,('YYYY - MMM' ,'2001 / Dec')
,('Forgot The Spaces #1' ,'2001December26')
,('Forgot The Spaces #2' ,'2001Dec26')
,('Forgot The Spaces #3' ,'26December2001')
,('Forgot The Spaces #4' ,'26Dec2001')
,('Forgot The Spaces #5' ,'26Dec2001 13:51:01')
,('Forgot The Spaces #6' ,'26Dec2001 13:51:01PM')
,('Oddly, this doesn''t work' ,'2001-12')
,('Oddly, this doesn''t work' ,'12-2001')
) v (Description,StringDT)
;
所以,是的……SQL Server 实际上有一种非常灵活的方法来处理各种奇怪的时间格式,并且不需要特殊处理。我们甚至不需要删除添加到 24 小时时间的“PM”。它是“PFM”(纯粹的怪诞魔法)。
事情会有所不同,具体取决于您为服务器选择的语言,但无论哪种方式都可以处理很多。
而这些“自动魔法”转换并不是什么新鲜事。他们走了很长一段路。
此页面包含对 CONVERT 函数可用的所有指定日期时间转换的一些参考。如果您的价值观不属于可接受的模式之一,那么我认为最好的办法是走 ParseExact 路线。
就个人而言,如果您处理任意或完全不符合条件的格式,只要您提前知道它们是什么或将要成为什么,那么只需使用正则表达式提取您想要的日期部分并形成一个有效的日期/日期时间组件。
这里最受好评的答案是guravg和Taptronic 的。但是,我想做一个贡献。
他们显示的从 0 到 131 的特定格式编号可能会因您的用例而异(请参阅此处的完整编号列表),输入编号可以是不确定的,这意味着预期结果日期在不同情况下不一致。此外,出于同样的原因,请避免使用强制转换字符串方法。
从 SQL Server 2005 及其兼容级别 90 开始,隐式日期转换变得不确定。从级别 90 开始,日期转换依赖于 SET LANGUAGE 和 SET DATEFORMAT。
非确定性值为0-100
, 106
, 107
, 109
, 113
, 130
. 这可能会导致错误。
最好的选择是坚持确定性设置,我目前的偏好是ISO
格式(12
、112
、23
、126
),因为它们似乎是 IT 人员用例最标准的。
Convert(varchar(30), '210510', 12) -- yymmdd
Convert(varchar(30), '20210510', 112) -- yyyymmdd
Convert(varchar(30), '2021-05-10', 23) -- yyyy-mm-dd
Convert(varchar(30), '2021-05-10T17:01:33.777', 126) -- yyyy-mm-ddThh:mi:ss.mmm (no spaces)
如果您希望 SQL Server 尝试解决它,只需使用 CAST CAST('whatever' AS datetime) 但是这通常是一个坏主意。会出现国际日期的问题。如您所见,为避免这些问题,您需要使用 ODBC 规范的日期格式。即格式号 120,20 是仅两位数年份的格式。我不认为 SQL Server 具有允许您提供用户给定格式的内置功能。你可以自己写,如果你在网上搜索,甚至可能找到一个。
在 MSSQL 中将字符串隐式转换为日期时间
create table tmp
(
ENTRYDATETIME datetime
);
insert into tmp (ENTRYDATETIME) values (getdate());
insert into tmp (ENTRYDATETIME) values ('20190101'); --convert string 'yyyymmdd' to datetime
select * from tmp where ENTRYDATETIME > '20190925' --yyyymmdd
select * from tmp where ENTRYDATETIME > '20190925 12:11:09.555'--yyyymmdd HH:MIN:SS:MS
您可以使用此代码轻松实现此目的。
选择转换(日期时间,转换(varchar(30),'10/15/2008 10:06:32 PM',102),102)
这段代码解决了我的问题:
convert(date,YOUR_DATE,104)
如果您正在使用timestamp
,您可以使用以下代码:
convert(datetime,YOUR_DATE,104)
dateadd(day,0,'10/15/2008 10:06:32 PM')