在SQL Server 2005中格式化日期/时间

时间:2012-04-27 15:18:37

标签: sql vb.net sql-server-2005 datetime

我在SQL Server 2005表中有一个datetime字段,其值如下所示:

2012-04-23 09:00:00.000
2012-04-23 14:00:00.000

分钟,秒和微秒始终为零。

我需要显示一个“时间段”(基本上,时间加上一小时),如下所示:

2012/04/23  09:00 AM - 10:00 AM
2012/04/23  02:00 PM - 03:00 PM

我得到了我需要的东西:

SELECT SUBSTRING(CONVERT(VARCHAR, TimeSlot, 20), 1, 10) + '  ' +
       RIGHT('00000' + LTRIM(SUBSTRING(CONVERT(VARCHAR(24), TimeSlot, 109), 13, 5)), 5) + ' ' +
       SUBSTRING(CONVERT(VARCHAR(19), TimeSlot, 100),18,2) + ' - ' +
       RIGHT('00000' + LTRIM(SUBSTRING(CONVERT(VARCHAR(24), DATEADD(hh, 1, TimeSlot), 109), 13, 5)), 5) + ' ' +
       SUBSTRING(CONVERT(VARCHAR(19), DATEADD(hh, 1, TimeSlot), 100), 18, 2) AS TimeSlot
FROM MyTable

它有效,但我觉得很脏。

我知道我可以在代码(VB .NET)中更容易地做到这一点,但我想我必须在SQL中这样做。

有没有更干净的方法呢?

3 个答案:

答案 0 :(得分:1)

采用内置的conversions,我会使用类似的东西:

SELECT 
    convert(varchar, [TimeSlot], 111) + ' ' +
    RIGHT(convert(varchar, [TimeSlot], 0), 7) + ' - ' +
    RIGHT(convert(varchar, dateadd(hour, 1, [TimeSlot]), 0), 7)
FROM
    [MyTable];

这为您提供了想要的行

2012/04/23  9:00AM - 10:00AM

详细说明:

  • convert(varchar, @dt, 111)datetime转换为日语格式yy/mm/dd
  • convert(varchar, @dt, 0)datetime转换为Apr 23 2012 9:00AM,以便我们可以使用时间部分
  • dateadd(hour, 1, @dt)将当前datetime值增加一小时

您可以使用以下表格进行测试:

DECLARE @dt DATETIME
SET @dt = '2012-04-23 09:00:00'

PRINT convert(varchar, @dt, 111) + ' ' +
      RIGHT(convert(varchar, @dt, 0), 7) + ' - ' +
      RIGHT(convert(varchar, dateadd(hour, 1, @dt), 0), 7);

答案 1 :(得分:1)

SQL Server中的内置日期/时间格式只会格式化为实际的日期格式,因此无论如何都要进行自定义格式化。如果您正在使用此方法提供SSRS,那么您可以使用表达式在SSRS中对其进行格式化。否则,您可以使用类似于您所描述的技术的方式对查询进行格式化。

如果你实际上是用VB应用程序显示它,那么你可以做那个客户端。

如果您的日期/时间值始终是小时或某个一致的间隔,您还可以使用格式化间隔存储为varchar列的时间键入参考表并使用它。这样可以节省您将格式化表达式内嵌到生成间隔描述所需的每个查询中。

答案 2 :(得分:0)

FollowConcernedOfTunbridgeW的建议,如果你维护一个带有主键的列的双列表[hr]从0到23,并且char(20)列[rng]包含每小时的空格前缀范围字符串< / p>

' 12:00 AM - 01:00 AM'  (in the row where hr = 0)
...

' 11:00 PM - 12:00 AM'  (in the row where hr = 23)

这个简单的查询应该产生你想要的东西:

  select
    convert(char(10),TimeSlot, 111) + rng as TimeRange
  from T join RangesByHr
  on datepart(hour,TimeSlot) = hr;