13

我需要将 datetime2 值四舍五入到最接近的半小时。例如 '10/17/2013 12:10:00.123' 将向下舍入为 '10/17/2013 12:00:00.0' 而 '10/17/2013 12:34:17.123' 将向下舍入为 10/17 /2013 12:30:00.0'。我的第一个想法是创建一个 UDF,它将日期和时间分开并这样做。但是,我想知道这样的事情是否可以在单个 T-SQL 语句中完成?

我使用的是 SQL Server 2012,列的数据类型是 dateTime2(不能转换为浮点数!!)

4

7 回答 7

16

伊恩的回答很好,但它包含了不必要的转换。我建议

SELECT CONVERT(smalldatetime, ROUND(CAST([columnname] AS float) * 48.0,0,1)/48.0) FROM [tableName]

如果您想四舍五入到最接近的半小时而不是总是向下舍入,请使用

SELECT CONVERT(smalldatetime, ROUND(CAST([columnname] AS float) * 48.0,0)/48.0) FROM [tableName]
于 2013-10-17T13:46:32.573 回答
1

这是一种方法:

update t set
  d = dateadd(minute,datediff(minute,'19000101',d)/30*30,'19000101');
于 2013-10-17T19:59:52.283 回答
1

这个怎么样

declare @d datetime = '2013-05-06 12:29.123'
select 
case 
    when datepart(minute, @d) < 30 then cast(dateadd(minute, -datepart(minute,@d)-datepart(second,@d), @d) as smalldatetime)
    when datepart(minute, @d) >= 30 then cast(dateadd(minute, -datepart(minute,@d)-datepart(second,@d)+30, @d) as smalldatetime)
end
于 2013-10-17T13:25:33.930 回答
0
select cast(floor(cast(
    cast('10/17/2013 12:34:00' as datetime) 
as float(53)) * 48) / 48 as datetime)

编辑

如果您使用 smalldatetime 来避免额外的精度,效果会更好

select cast(floor(cast(
    cast('2012-01-02 11:33:14.097' as smalldatetime) 
as float(53)) * 48) / 48 as smalldatetime)
于 2013-10-17T13:34:25.377 回答
0

当我需要向下舍入到最接近的 5 分钟间隔时,我使用了一种稍微不同的方法。可能有一种方法可以进一步简化这一点,但至少这让我得到了我需要的东西。

DECLARE @now datetime = GETDATE()

SELECT @now as cur_datetime, DATEADD(MINUTE, -(DATEDIFF(MINUTE,DATEADD(HOUR,DATEDIFF(HOUR,0,@now), 0),DATEADD(MINUTE,DATEDIFF(MINUTE,0,@now), 0)) % 5), DATEADD(MINUTE,DATEDIFF(MINUTE,0,@now), 0)) as round_down_to_nearest_5_minute_mark
于 2016-08-18T15:41:43.820 回答
0

您可以使用它DATETIME2FROMPARTS来重建日期。要将分钟四舍五入30 分钟间隔,请使用公式minutes intdiv 30 * 30

SELECT
    dt2,
    DATETIME2FROMPARTS(
        DATEPART(year, dt2),
        DATEPART(month, dt2),
        DATEPART(day, dt2),
        DATEPART(hour, dt2),
        DATEPART(minute, dt2) / 30 * 30,
        0,
        0,
        0
    )
FROM (VALUES
    -- generic datetime2
    (SYSDATETIME()),
    -- 30 minute boundary
    ('2001-01-01 00:29:59.9999999'),
    ('2001-01-01 00:30:00.0000000'),
    ('2001-01-01 00:30:00.0000001'),
    -- min and max date
    ('0001-01-01 00:00:00.0000000'),
    ('9999-12-31 23:59:59.9999999')
) AS v(dt2)
于 2021-07-07T10:32:05.820 回答
0

@Twinkles 的答案在 SQL Server 中运行良好,可以四舍五入到最接近的半小时。

但是,在开发中,强烈建议使用 FLOOR 舍入到持续半小时

SELECT CONVERT(datetime, FLOOR(CAST([columnname] AS float) * 48.0)/48.0) FROM [tableName]

于 2018-10-25T19:13:30.817 回答