Sql Server字符串到日期的转换

我想转换一个像这样的字符串:

'10/15/2008 10:06:32 PM'

转换为Sql Server中的DATETIME值。

在甲骨文,我会这样说:

TO_DATE('10/15/2008 10:06:32 PM','MM/DD/YYYY HH:MI:SS AM')

这个问题意味着我必须将字符串解析为标准格式之一,然后使用这些代码之一进行转换。对于这样一个平凡的行动来说,这似乎很荒谬。有没有更简单的方法?

1085249 次浏览

对于这个问题,我使用的最好的解决方案是在Sql Server 2005中有一个使用DateTime的CLR函数。Parse或ParseExact函数返回指定格式的DateTime值。

通过您的查询处理器运行它。它格式化日期和/或时间,其中一个应该会给你你要找的东西。适应并不难:

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试着找出它,只需要使用CAST CAST('whatever' AS datetime) 然而,总的来说,这是个坏主意。国际日期也会出现问题。因此,如您所发现的,为了避免这些问题,您希望使用日期的ODBC规范格式。这是120格式,20是两位数年份的格式。 我不认为SQL Server有允许你提供用户给定格式的内置函数。

.你可以写自己的,甚至可以在网上搜索到

页面有一些对CONVERT函数可用的所有指定日期时间转换的引用。如果您的值不属于可接受的模式之一,那么我认为最好的方法是采用ParseExact路线。

SQL Server(2005, 2000, 7.0)没有任何灵活的,甚至是不灵活的方法来获取任意结构的字符串格式的datetime并将其转换为datetime数据类型。

所谓“随意”,我指的是“一种写作者(虽然可能不是你、我或地球另一边的人)认为是直观和完全明显的形式。”坦率地说,我不确定是否有这样的算法。

简短的回答:

SELECT convert(date, '10/15/2011 00:00:00', 101) as [MM/dd/YYYY]

其他日期格式可以在SQL Server Helper;SQL Server日期格式中找到

试试这个

Cast('7/7/2011' as datetime)

而且

Convert(DATETIME, '7/7/2011', 101)

更多细节参见转换和转换(Transact-SQL)

在SQL Server Denali中,您将能够做一些接近您正在寻找的东西。但是你仍然不能仅仅传递任意定义的古怪日期字符串,并期望SQL Server能够适应。这里有一个例子,使用你在自己的回答中发布的内容。FORMAT()函数,也可以接受locale作为可选参数——它基于。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);

我强烈建议你更多地控制和净化你的约会输入。让人们用任何他们想要的格式在自由文本表单字段中输入日期的日子现在应该远远落后于我们了。如果有人进入8/9/2011,那是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日。

就个人而言,如果您正在处理任意的或完全不符合要求的格式,只要您事先知道它们是什么或将要是什么,那么只需使用regexp来提取您想要的日期部分,并形成有效的date/datetime组件。

用这个:

SELECT convert(datetime, '2018-10-25 20:44:11.500', 121) -- yyyy-mm-dd hh:mm:ss.mmm

并参考官方文档中的表以获取转换代码。

我花了一分钟才弄明白,所以在这里它可能会帮助到别人:

在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
dateadd(day,0,'10/15/2008 10:06:32 PM')

在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






您可以通过使用这段代码轻松实现这一点。

SELECT Convert(datetime, Convert(varchar(30),'10/15/2008 10:06:32 PM',102),102)

这段代码解决了我的问题:

convert(date,YOUR_DATE,104)

如果你正在使用timestamp,你可以修改下面的代码:

convert(datetime,YOUR_DATE,104)

被点赞最多的答案是guravg的Taptronic的。然而,有一件事我想做。

它们显示的从0到131的具体格式编号可能会根据你的用例而有所不同(参见完整的数字列表在这里), 输入的数字可以是不确定的,这意味着预期的结果日期从一个SQL SERVER实例到另一个不一致,出于同样的原因避免使用字符串强制转换方法

从SQL Server 2005开始,其兼容性级别为90, 隐式日期转换变得不确定。日期转换 开始依赖于SET LANGUAGE和SET DATEFORMAT 高度90。< / p >

非确定性值为0-100106107109113130。这可能会导致错误。


最好的选择是坚持一个确定性的设置,我目前的首选是ISO格式(1211223126),因为它们似乎是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)