日期转换和文化:DATE和DATETIME之间的差异

时间:2017-08-21 08:44:33

标签: sql-server tsql date datetime casting

我已经从字符串中写了很多关于datedatetime次转化的答案。我住在一个讲德语的国家,我曾经处理过非us_english 日期格式,而且我曾经习惯使用安全文字(我更喜欢ODBC格式)如果没有第三个参数,我永远不会使用CONVERT。这不是问题,请不要在这方面提供答案......

通常人们可以阅读,格式yyyy-mm-dd是标准的(ISO8601,ANSI,无论如何),因此文化独立。

今天我必须编辑one of these older answers,正如我在那里所说的那样,观察到的行为取决于其他内容。

问题是:

为什么(如果有原因)DATEDATETIME之间存在差异?

...至少在我的环境中,目前是SQL Server 2014(12.0.4237.0)。

我希望,之前没有问过......

试试这个:

此处没有问题,DATE按预期工作

SET LANGUAGE ENGLISH;
DECLARE @dt DATE='2017-01-13'; 
SELECT @dt;
SELECT CAST('2017-01-13' AS DATE);
SELECT CONVERT(DATE,'2017-01-13'); --no culture / format specified
GO
SET LANGUAGE GERMAN;
DECLARE @dt DATE='2017-01-13';
SELECT @dt;
SELECT CAST('2017-01-13' AS DATE);
SELECT CONVERT(DATE,'2017-01-13'); 

但是现在用DATETIME

检查一下
--No problem here:
SET LANGUAGE ENGLISH;
DECLARE @dt DATETIME='2017-01-13'; 
SELECT @dt;
SELECT CAST('2017-01-13' AS DATETIME);
SELECT CONVERT(DATETIME,'2017-01-13'); 
GO

--breaks, due to the "13" and would deliver a wrong result (even worse), if the "day" was not more than "12":
SET LANGUAGE GERMAN;
DECLARE @dt DATETIME='2017-01-13'; 
SELECT @dt;
SELECT CAST('2017-01-13' AS DATETIME);
SELECT CONVERT(DATETIME,'2017-01-13'); 

这是一个错误,目的还是只是粗暴?

2 个答案:

答案 0 :(得分:6)

DATETIME(旧版本)的ISO-8601以某种方式“破坏”或“改编”(取决于您是将其视为错误还是功能) - 您需要使用{{1 ( 不带 任何破折号)使其无论语言设置如何都能正常工作。

对于YYYYMMDDDATE数据类型,此问题已修复,并且“正确”的ISO-8601格式DATETIME2(n)将始终正确解释。

YYYY-MM-DD

这是-- OK because of "adapted" ISO-8601 SET LANGUAGE GERMAN; DECLARE @dt DATETIME='20170113'; SELECT @dt; SELECT CAST('20170113' AS DATETIME); SELECT CONVERT(DATETIME, '20170113'); -- OK because of DATETIME2(n) SET LANGUAGE GERMAN; DECLARE @dt2 DATETIME2(0) = '2017-01-13'; SELECT @dt2; SELECT CAST('2017-01-13' AS DATETIME2(0)); SELECT CONVERT(DATETIME2(0), '2017-01-13'); 类型的怪癖(而不是唯一的......) - 只需注册,了解它 - 然后继续(意思是:不要再使用DATETIME了 - 使用DATETIMEDATE代替 - 使用起来更好!): - )

答案 1 :(得分:3)

(作为评论开始,但是......)要向marc_s的答案添加更多数据,datetime也会因yyyy-mm-dd HH:MM:ss而失败 - 所以

SET LANGUAGE GERMAN;
DECLARE @dateTimeFailes DATETIME ='2017-01-13 00:00:00';

会导致同样的错误。但是,使用T替换日期和时间部分之间的空格后,SQL Server将突然理解格式 -

SET LANGUAGE GERMAN;
DECLARE @dateTime DATETIME ='2017-01-13T00:00:00';

将按预期工作。

以下是可接受和不可接受格式的快速列表:

SET LANGUAGE GERMAN;
-- Correct 
DECLARE @date DATE ='2017-01-13';
DECLARE @dateTime DATETIME ='2017-01-13T00:00:00'; 
DECLARE @dateTimeDateOnly DATETIME ='20170113';

-- Incorrect
DECLARE @WrongFormatDateTime DATETIME ='2017-01-13 00:00:00'; 
DECLARE @WrongFormatDate DATETIME ='2017-01-13';