【问题标题】:Roof a DateTime to next value of a specific minute interval将 DateTime 设置为特定分钟间隔的下一个值
【发布时间】:2014-03-05 14:04:41
【问题描述】:

我想以特定时间间隔显示信息,例如 5、10、15 分钟等。

但对于给定的 DateTime,我想“向上取整”到此间隔的下一个值

例如

declare @dateTime datetime = '2014-03-05 18:37';

select getNextDateTimeForInterval(@dateTime, 60); --> 2014-03-05 19:00
select getNextDateTimeForInterval(@dateTime, 30); --> 2014-03-05 19:00
select getNextDateTimeForInterval(@dateTime, 20); --> 2014-03-05 18:40
select getNextDateTimeForInterval(@dateTime, 15); --> 2014-03-05 18:45
select getNextDateTimeForInterval(@dateTime, 10); --> 2014-03-05 18:40
select getNextDateTimeForInterval(@dateTime, 5);  --> 2014-03-05 18:40
select getNextDateTimeForInterval(@dateTime, 1);  --> 2014-03-05 18:38

有没有聪明的方法来做到这一点?我只提出了仅适用于其中一些情况的解决方案。

【问题讨论】:

    标签: sql sql-server tsql datetime


    【解决方案1】:

    似乎有效:

    create function dbo.getNextDateTimeForInterval (@dt datetime, @unit int)
    returns datetime
    as
    begin
        return DATEADD(minute,(DATEDIFF(minute,0,@dt)/@unit+1)*@unit,0)
    end
    go
    declare @dateTime datetime = '2014-03-05T18:37:00';
    
    select dbo.getNextDateTimeForInterval(@dateTime, 60); --> 2014-03-05 19:00
    select dbo.getNextDateTimeForInterval(@dateTime, 30); --> 2014-03-05 19:00
    select dbo.getNextDateTimeForInterval(@dateTime, 20); --> 2014-03-05 18:40
    select dbo.getNextDateTimeForInterval(@dateTime, 15); --> 2014-03-05 18:45
    select dbo.getNextDateTimeForInterval(@dateTime, 10); --> 2014-03-05 18:40
    select dbo.getNextDateTimeForInterval(@dateTime, 5);  --> 2014-03-05 18:40
    select dbo.getNextDateTimeForInterval(@dateTime, 1);  --> 2014-03-05 18:38
    

    没有什么特别棘手的需要。虽然如果你使用的间隔不是 60 等分,我不能保证它会符合你的期望,因为我不知道你对这种情况的期望是什么。


    解释:DATEDIFF(minute,0,@dt) 计算从1900-01-01(您通过将0 解释为日期获得的值)和@dt 开始的午夜之间经过的分钟数。然后,我们将该值除以@unit 进行整数除法(向 0 舍入),加 1,然后将其乘以 @unit - 这就是我们获得向上舍入效果的方式。然后我们使用DATEADD 将新的分钟数添加回1900-01-01

    【讨论】:

    • 感谢大家的回答,但你的回答是最详细的,所以我会给你功劳。
    【解决方案2】:

    另一种为您的测试用例返回正确值的方法:

    CREATE FUNCTION getNextDateTimeForInterval(@param datetime, @roundValue int)
    RETURNS datetime
    AS
    BEGIN
        DECLARE @totalMinutes int;
        SET @totalMinutes = DATEDIFF(
                minute
                , CONVERT(date, @param)
                , @param);
    
        RETURN DATEADD(minute
            , @totalMinutes + (@roundValue - (@totalMinutes % @roundValue))
            , CONVERT(DateTime, CONVERT(date, @param))
        );
    END
    

    但请注意,如果您想要18:37, 1 -->18:38,那么它也将是19:00, 60 -->20:00。这可能很奇怪。

    【讨论】:

      【解决方案3】:

      试试

      CREATE FUNCTION getNextDateTimeForInterval(@dateTime datetime, @val int)
      RETURNS datetime
      AS
      BEGIN
      
      DECLARE @date DATETIME
      SET @date = CONVERT(varchar(16),@dateTime,121) 
      RETURN DATEADD(MINUTE,((DATEPART(MINUTE,@date) % @val)*-1)+@val, @date)
      
      END
      
      
      select getNextDateTimeForInterval(@dateTime, 60); --> 2014-03-05 19:00
      select getNextDateTimeForInterval(@dateTime, 30); --> 2014-03-05 19:00
      select getNextDateTimeForInterval(@dateTime, 20); --> 2014-03-05 18:40
      select getNextDateTimeForInterval(@dateTime, 15); --> 2014-03-05 18:45
      select getNextDateTimeForInterval(@dateTime, 10); --> 2014-03-05 18:40
      select getNextDateTimeForInterval(@dateTime, 5);  --> 2014-03-05 18:40
      select getNextDateTimeForInterval(@dateTime, 1);  --> 2014-03-05 18:38
      

      【讨论】:

        猜你喜欢
        • 2021-06-19
        • 2022-01-25
        • 1970-01-01
        • 2012-04-06
        • 2019-04-12
        • 2021-10-03
        • 1970-01-01
        • 2020-07-31
        • 1970-01-01
        相关资源
        最近更新 更多