0

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

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

代替 101 我使用了 10 和 11,但数据仍然存在相同的问题(如下)。发生的情况是当日期值(不包括时间)为 8 个字符时,我从时间中得到一个额外的字符,如 Claim Adjustment Date-10 和 Claim Adjustment Date-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

奇怪的是,如果月份或日期 < 10,“Claim Paid Date”列中的所有日期都有一个零填充。这使得转换结果很好,但月份或日期 < 10 并且确实如此没有零是我遇到问题的地方。

4

2 回答 2

2

正确的方法是首先存储数据DATETIME。目前,您将数据存储为字符串,出于多种原因,您不应该这样做:

  • 你失去了排序的能力(9/1/2012将在之后排序12/12/2012)而不先转换。转换很昂贵。
  • 你失去了执行有意义的范围查询而不首先转换的能力(再次,9/1/2012> 12/12/2012
  • 您失去了所有内置验证的方式 - 任何人都可以输入13/33/299902/32/2099简单地输入foo“日期”
  • 如果没有先转换,您将无法执行日期相关的功能,例如DATEADD,DATEPARTDATEDIFF针对这些列
  • 您需要先转换为另一种类型,然后才能执行转换,以便您执行诸如修剪时间或以特定格式显示日期之类的操作

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

应该以明确的格式向用户显示日期,因为您永远不知道您的某些读者何时会看到6/12/2012,也不确定是 6 月 12 日还是 12 月 6 日(例如,加拿大人和美国人会看到不同的日期)。因此,您可以使用,例如:

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

这将显示一个明确的日期,例如 2012-06-12,只能在法国一些非常偏远的地区和年龄组(ydm 似乎仍然流行)中被误解。

但是,如果您绝对想呈现模棱两可的格式,您可以使用:

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

...根本没有理由更改您的 SQL 查询。如果出于某种原因,您绝对希望或需要在查询级别执行此操作,那么您可以使用:

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

如果您想使用较少歧义的形式,例如yyyymmddor yyyy-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(同样,最好使用明确的格式)
于 2013-09-24T18:32:53.117 回答
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) 
于 2013-09-24T18:01:18.517 回答