将float转换为datetime

时间:2013-03-28 00:28:05

标签: sql-server

我有一个FLOAT字段,其日期如下:

+-----------+
| FloatDate |
+-----------+
| 1012013   | -- Jan 1
| 3262013   | -- Mar 26
| 11072013  | -- Nov 7
| 10012013  | -- Oct 1
+-----------+

我希望将此数据插入另一个表,其dateField的数据类型为DATETIME

所以,我正在尝试将FloatDate值转换为DATETIME,但我只是保持失败......

我试过

INSERT INTO NEWTABLE 
(DateTimeDate)
SELECT CONVERT(DATETIME, CAST(CAST(FloatDate AS INTEGER) AS CHAR), 112)
FROM OLDTABLE

但是这给了我一个错误,说

  

从字符串转换日期时间

时转换失败

如果FloatDate的日期格式为YYYYMMDD,它似乎有效。所以,如果我这样做,它就可以了。

DECLARE @test FLOAT
SET @test = 2132013                                                                                                                            
SELECT @test,  CONVERT(DATETIME, CAST(RIGHT(CAST(@test AS INTEGER), 4) AS CHAR(4)) + 
CASE WHEN LEN(CAST(@test AS INTEGER)) = 7 THEN '0' + CAST(LEFT(CAST(@test AS INTEGER), 3) AS CHAR(3))
     WHEN LEN(CAST(@test AS INTEGER)) = 8 THEN CAST(LEFT(CAST(@test AS INTEGER), 4) AS CHAR(4)) END, 1)

但是,我想知道我是不是太复杂了,只是错过了更简单的解决方案,或者这是我能实现的唯一方法?

4 个答案:

答案 0 :(得分:7)

假设您有其他值,例如:

 3092013 -- March 9th
10052013 -- October 5th
 1112013 -- January 11th
11012013 -- November 1st

然后你可以这样做:

DECLARE @x TABLE(FloatDate FLOAT);

INSERT @x VALUES
( 3092013),-- -- March 9th
(10052013),-- -- October 5th
( 1112013),-- -- January 11th
(11012013);-- -- November 1st

;WITH s(d) AS (SELECT RIGHT('0' + CONVERT(VARCHAR(32), 
  CONVERT(INT, FloatDate)), 8) FROM @x),
d(d) AS (SELECT CONVERT(DATETIME, 
  RIGHT(d,4) + LEFT(d,2) + SUBSTRING(d,3,2)) FROM s)
SELECT d FROM d;

结果:

d
-----------------------
2013-03-09 00:00:00.000
2013-10-05 00:00:00.000
2013-01-11 00:00:00.000
2013-11-01 00:00:00.000

在你的例子中,它将是:

;WITH s(d) AS (SELECT RIGHT('0' + CONVERT(VARCHAR(32), 
  CONVERT(INT, FloatDate)), 8) FROM dbo.OLDTABLE),
d(d) AS (SELECT CONVERT(DATETIME, 
  RIGHT(d,4) + LEFT(d,2) + SUBSTRING(d,3,2)) FROM s)
INSERT dbo.NEWTABLE
SELECT d FROM d;

当然,即使您获得有效值的语法,也可能会有一些不良数据。由于您使用了FLOAT,因此您无法获得任何固有的验证,因此该列可能包含-99945671213等。

你觉得这很痛苦吗?好! 应该痛苦。你应该回到那些决定在FLOAT栏中存储日期的人,然后踢他们的胫骨。询问他们是否使用地理数据类型存储工资。我很高兴您正在解决这个问题,但不应该允许这些人接近数据库设计。

最后,请不要这样做:

CAST(anything AS CHAR)

始终指定长度。原因如下:

答案 1 :(得分:4)

如果您有一个八位数字(浮点数),您可以这样做

select cast(cast(cast([invoice date] as int) as varchar(8)) as datetime)

答案 2 :(得分:2)

print (convert(float, CAST('1900-01-01 03:30' AS DATETIME)))--days 0,145833333333333
print (convert(float, CAST('1900-01-01 03:30' AS DATETIME))*24)--hours 3,5
print (convert(float, CAST('1900-01-01 03:30' AS DATETIME))*24*60)--minutes 210
print (convert(float, CAST('1900-01-01 03:30' AS DATETIME))*24*60*60)--seconds 12600

这第二种方法更干净

print (CAST(CAST('1900-01-01 03:30' AS DATETIME) AS FLOAT))--days 0,145833333333333
print (CAST(CAST('1900-01-01 03:30' AS DATETIME) AS FLOAT)*24)--hours 3,5
print (CAST(CAST('1900-01-01 03:30' AS DATETIME) AS FLOAT)*24*60)--minutes 210
print (CAST(CAST('1900-01-01 03:30' AS DATETIME) AS FLOAT)*24*60*60)--seconds 12600

答案 3 :(得分:0)

为了能够将Float日期转换为datetime格式,您需要将float数据转换为Varchar。这就是为什么@ yogesh-sharma回答有效的原因。