【问题标题】:Convert time float to format HH:mm sql server将时间浮点数转换为格式 HH:mm sql server
【发布时间】:2023-03-20 01:40:01
【问题描述】:

我需要将浮点十进制数格式化为时间格式小时:分钟。

我用输入浮点和输出 varchar(6) 编写了这个标量值函数:

CREATE FUNCTIONE formatOre ( @input float )
returns varchar(6) 
as
begin
declare @n float;
declare @hour int = floor(@input);
declare @minutes int = (select (@input - floor(@input)) * 60);
declare @val varchar(6)

set @val = right('00' + convert(varchar(2), @hour), 2) + ':' + right('00' + convert(varchar(2), @minutes), 2);

return @val

end

它看起来很棒,但不是所有记录。这是我的输出:

select formatOre (0)    ---> 00:00
select formatOre (0.17) ---> 00:10
select formatOre (0.25) ---> 00:15
select formatOre (0.33) ---> 00:19
select formatOre (0.42) ---> 00:25
select formatOre (0.5)  ---> 00:30
select formatOre (0.58) ---> 00:34
select formatOre (0.67) ---> 00:40
select formatOre (0.75) ---> 00:45
select formatOre (0.83) ---> 00:49
select formatOre (0.92) ---> 00:55

从结果可以看出,有3个错误转换:0.33 = 00:19 // 0.58 = 00:34 // 0.83 = 00:49.

如何设置正确的输出?

【问题讨论】:

  • “错误”是什么意思?您预期的正确输出是什么?对我来说,它看起来只是正确的
  • 你为什么用浮点数或小数存储时间?
  • 对于 input=.17 你得到 select (@input - floor(@input))*60 = 0.17*60 = 10.2 并且由于它被声明为 int 你得到 10 作为结果。
  • 我猜你在抱怨是因为你希望 0.33 是 00:20,0.58 是 00:35 和 0.83 = 00:50。如果您真的热衷于使用笨重的函数而不是简单的 FORMAT 命令来获取它,那么您可以使用 ROUND(, 0) 包装分钟计算,即“声明@minutes int = ROUND((select (@input - floor(@input)) * 60), 0);”。这会给你想要的结果,但有更好的方法来做到这一点。
  • 正如理查德所说,我希望 0.33 是 00:20 和其他。您写道,有“更好的方法”。那么,这些方法是什么?

标签: sql sql-server time type-conversion sql-convert


【解决方案1】:

使用函数 FORMAT SQL 2012+ https://docs.microsoft.com/en-us/sql/t-sql/functions/format-transact-sql

DECLARE  @input float = 4.92    
SELECT FORMAT(FLOOR(@input)*100 + (@input-FLOOR(@input))*60,'00:00')

【讨论】:

  • 不适用于任何其他小时值,请尝试:SELECT FORMAT(03.92*60,'00:00')
【解决方案2】:

不是解决问题的方法,但也许您可以利用一些东西。标量函数的性能很糟糕。但内联表值函数不是。您发布的函数可以很容易地转换为内联表值函数。请记住,这些必须只是一个选择语句。如果你有变量等它变成一个多语句表值函数,性能会比标量函数更差。

您可以通过以下方式将该标量转换为内联表值函数。

CREATE FUNCTION formatOre 
(
    @input float 
)
returns table as return

select right('00' + convert(varchar(2), floor(@input)), 2) + ':' + right('00' + convert(varchar(2), floor((@input - floor(@input)) * 60)), 2)

【讨论】:

  • 算术溢出。 Round/FLOOR第二部分
  • 不工作..如果你设置@input = 0.83,结果将是00:49,我需要结果是00:50
【解决方案3】:

你可以试试这个

 SELECT FORMAT(FLOOR(ColumnNAme) + (ColumnNAme -FLOOR(ColumnNAme)),'00.00') from TableName

【讨论】:

    【解决方案4】:

    将 4.92 渲染为 '04:55':

    SELECT FORMAT(DATEADD(minute, 4.92 * 60, '2000-01-01'), 'HH:mm')
    

    【讨论】:

      【解决方案5】:
      INSERT INTO t_att_inout(MM  ,YYYY   ,   DATE,EmpCode    ,Type   ,InTime,    OutTime)
      select 10 as MM,2020 as YYYY, CONVERT(DATE,LEFT([Att Date],2)+'-OCT-2020',106),
      emp_code,'fboth'as type,  
      CONVERT(TIME(7),CONVERT(VARCHAR,FLOOR([in time]))+':'+RIGHT('00'+CONVERT(VARCHAR,CONVERT(INT,([In Time]-FLOOR([In Time]))*100)),2)),  
      CONVERT(TIME(7),CONVERT(VARCHAR,FLOOR([out time]))+':'+RIGHT('00'+CONVERT(VARCHAR,CONVERT(INT,([Out time]-FLOOR([Out time]))*100)),2)) --,[IN time],[out time]
      from CGAttend10$    
      

      【讨论】:

        猜你喜欢
        • 2023-03-21
        • 1970-01-01
        • 2018-05-03
        • 2016-05-28
        • 2013-11-11
        • 2022-01-17
        • 1970-01-01
        • 1970-01-01
        • 2019-06-20
        相关资源
        最近更新 更多