转换SQL日期格式不会相同

时间:2013-09-24 17:15:36

标签: sql tsql sql-server-2008-r2

我正在尝试从我的日期值中删除时间戳,所以我最终会得到像mm / dd / yy或mm / dd / yyyy这样的东西。我引用了许多technet,stackoverflow和w3schools文章,但仍然无法正确显示日期。表中的所有列都定义为日期时间,它们来自同一个表。

我正在使用这样的转换语句:CONVERT(VARCHAR(10),E.PD_DT,101)AS'付费日期'

代替101我使用了10和11,仍然有相同的数据问题(如下)。发生的事情是当日期值(不包括时间)是8个字符时,我从时间获得了一个额外的字符,如索赔调整日期-10和索赔调整日期-11列中所示。这是我的数据:

Claim Paid Date-101     Claim Paid Date     Claim Adjustment Date-10    Claim Adjustment Date-11    Claim Adjustment Date
10/23/2012              10/23/12 12:00 AM   9/4/2012 1                  9/4/2012 1                      9/4/12 12:00 AM
10/23/2012              10/23/12 12:00 AM   9/4/2012 1                  9/4/2012 1                      9/4/12 12:00 AM
10/23/2012              10/23/12 12:00 AM   9/4/2012 1                  9/4/2012 1                      9/4/12 12:00 AM
09/06/2011              09/06/11 12:00 AM   9/4/2012 1                  9/4/2012 1                      9/4/12 12:00 AM
10/23/2012              10/23/12 12:00 AM   8/21/2012                   8/21/2012                       8/21/12 12:00 AM
09/06/2011              09/06/11 12:00 AM   8/21/2012                   8/21/2012                       8/21/12 12:00 AM

奇怪的是,如果月份或日期是<1,则“索赔付款日期”列中的所有日期都有零填充。 10.这使得转换结果很好但是月或日是<1。 10并且没有零是我遇到问题的地方。

2 个答案:

答案 0 :(得分:2)

您有一个字符串来源,而不是DATETIME来源。

DATETIME会发生什么:

SELECT GETDATE() -- DATETIME
      ,CAST(GETDATE() AS DATE) --DATE
      ,CONVERT(VARCHAR(10),GETDATE(),101) --101 format

结果:

DateTime                Date       101 Format
----------------------- ---------- ----------
2013-09-24 13:58:48.880 2013-09-24 09/24/2013

字符串游行为DATETIME会发生什么:

DECLARE @fake_date VARCHAR(25) = '10/23/12 12:00 AM'
SELECT CAST(@fake_date AS DATETIME) --DATETIME
      ,CAST(@fake_date AS DATE) --DATE
      ,CONVERT(VARCHAR(10),@fake_date,101) --101 format

结果:

DateTime                Date       101 Format
----------------------- ---------- ----------
2012-10-23 00:00:00.000 2012-10-23 10/23/12 1

所以也许你想要:

CONVERT(VARCHAR(10),CAST(@fake_date AS DATE),101) 

答案 1 :(得分:2)

执行此操作的正确方法是首先将数据存储为DATETIME。目前,您将数据存储为字符串,由于各种原因,您不应该这样做:

  • 您将失去排序功能(9/1/2012将在12/12/2012之后排序)而不先进行转换。转换很昂贵。
  • 您无法在不先转换的情况下执行有意义的范围查询(同样,9/1/2012&gt; 12/12/2012
  • 您失去了所有内置验证功能 - 任何人都可以输入13/33/299902/32/2099或仅foo作为“日期”
  • 您无法在不事先转换的情况下对这些列执行与DATEADDDATEPARTDATEDIFF等日期相关的功能
  • 您需要首先转换为其他类型才能执行转换,以便您可以执行修剪时间或以特定格式显示日期

如果您无法修复表格设计并希望使用错误的数据类型继续存储日期,那么下一个最好的方法就是在客户端中简单地格式化字符串。如果客户知道它是日期/时间,那么使用.Format().ToString()应该允许您以任何您想要的格式提供没有时间的日期。

应该以明确的格式向用户展示日期,因为你永远不知道你的某些读者何时会看到6/12/2012并且不确定那是6月12日或12月6日(加拿大人)例如,美国人会看到不同的东西。所以你可以使用,例如:

DateVariable.Format('yyyy-MM-dd')

这将呈现一个明确的日期,如2012-06-12,只能在一些非常偏僻的地区和法国的年龄组中被误解(其中y-d-m似乎仍然流行)。

但是,如果您绝对想要呈现模糊格式,可以使用:

DateVariable.Format('MM/dd/yyyy')

...没有理由改变你的SQL查询。如果出于某种原因,您绝对想要或需要在查询级别执行此操作,则可以使用:

SELECT CONVERT(CHAR(10), CONVERT(DATE, col), 101) -- mm/dd/yyyy

如果您想使用不太模糊的表单,例如yyyymmddyyyy-mm-dd,您可以使用:

SELECT CONVERT(CHAR(8),  CONVERT(DATE, col), 112) -- yyyymmdd
SELECT CONVERT(CHAR(10), CONVERT(DATE, col), 120) -- yyyy-mm-dd

但同样,数据库层的转换是昂贵的,而客户端层的字符串格式化(在最后一步你已经将这些东西作为字符串处理)相对便宜。您应该尽可能长时间地保留这些日期值,无论是在数据库的出路还是出路。在SQL Server的任何地方将它们视为字符串都没有任何优势。

所以,摘要

  1. 修复表格
  2. 在客户端上执行转换(最好是明确的格式)
  3. 如果您无法在客户端上执行转换,请使用双嵌套CONVERT(再次,最好是明确的格式)