sql-server 将浮点数转换为日期时间

slwdgvem  于 2022-10-31  发布在  其他
关注(0)|答案(5)|浏览(240)

我有一个日期的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)

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

zu0ti5jz

zu0ti5jz1#

假设您有其他值,例如:

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;

当然,您可能会有一些错误的数据在那里,即使你得到了语法正确的 * valid* 值。因为你使用FLOAT,你没有得到任何固有的验证,所以该列可能包含-99945671213等。
你觉得这很痛苦吗?很好!它 * 应该 * 很痛苦。你应该回去找那些决定在FLOAT列中存储日期的人,踢他们的胫骨。问问他们是否使用地理数据类型存储工资。我很高兴你解决了这个问题,但是不应该允许这些人参与数据库设计。
最后,请不要这样做:

CAST(anything AS CHAR)

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

lvjbypge

lvjbypge2#

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

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

o0lyfsai3#

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
3htmauhk

3htmauhk4#

为了能够将浮点日期转换为日期时间格式,您需要将浮点数据转换为Varchar格式。这就是@yogesh-sharma answer可以工作的原因。

hwamh0ep

hwamh0ep5#

如果您的字段是FLOAT64,而您想要将它转换为TIMESTAMP,您可以执行下列动作:

TIMESTAMP_ADD(TIMESTAMP "1970-01-01 00:00:00", INTERVAL cast(field AS INT) SECOND) AS field_timestamp

然后,如果你想让你的字段在DATETIME中,则只需转换:

cast(field_timestamp AS DATETIME) AS field_datetime

cast(TIMESTAMP_ADD(TIMESTAMP "1970-01-01 00:00:00", INTERVAL cast(field AS INT) SECOND)) AS field_datetime

相关问题