示例:
36464
37104
35412
当我在 Excel 中格式化单元格时,它们会被转换为
36464 => 1/11/1999
37104 => 1/08/2001
35412 => 13/12/1996
我需要在SSIS或SQL中执行这个转换操作。如何实现?
36464
37104
35412
当我在 Excel 中格式化单元格时,它们会被转换为
36464 => 1/11/1999
37104 => 1/08/2001
35412 => 13/12/1996
我需要在SSIS或SQL中执行这个转换操作。如何实现?
在 SQL 中:
select dateadd(d,36464,'1899-12-30')
-- or thanks to rcdmk
select CAST(36464 - 2 as SmallDateTime)
在SSIS中,请参见此处:
这个标记的答案不能正常工作,请将日期更改为 "1899-12-30" 而不是 "1899-12-31"。
select dateadd(d,36464,'1899-12-30')
您可以将其转换为 SQL SMALLDATETIME
:
CAST(36464 - 2 as SMALLDATETIME)
MS SQL Server将其日期从1900年1月1日开始计算,而Excel则从1899年12月30日开始计算,因此Excel比SQL Server少2天。
tldr:
select cast(@Input - 2e as datetime)
解释:
Excel将日期时间存储为浮点数,表示自20世纪初以来经过的时间,而SQL Server可以轻松地在浮点数和日期时间之间进行转换。 Excel和SQL服务器将此数字转换为日期时间的差异为2天(截至1900年3月1日)。使用2e
来表示这个差异,可以让SQL Server隐式地将其他数据类型转换为浮点数,从而使查询变得非常简单易懂:
select
cast('43861.875433912' - 2e as datetime) as ExcelToSql, -- even varchar works!
cast(cast('2020-01-31 21:00:37.490' as datetime) + 2e as float) as SqlToExcel
-- Results:
-- ExcelToSql SqlToExcel
-- 2020-01-31 21:00:37.490 43861.875433912
这对我真的有用。
dateadd(mi,CONVERT(numeric(17,5),41869.166666666664)*1440,'1899-12-30')
(日期减少一天)
指的是负面评论帖子
DT_DATE数据类型是使用8字节浮点数实现的。天数由整数增量表示,从1899年12月30日开始,午夜为时间零点。小时值表示为数字的小数部分的绝对值。然而,浮点值无法表示所有实数值;因此,对于可以在DT_DATE中呈现的日期范围存在限制。阅读更多
从上述描述中可以看出,在将其转换为8字节浮点数DT_R8后,您可以在将这些值映射到DT_DATE列时隐式地进行转换。
使用派生列转换将此列转换为8字节浮点数:
(DT_R8)[dateColumn]
将其映射到一个DT_DATE
列中
或者进行两次转换:
(DT_DATE)(DT_R8)[dateColumn]
您可以在此处查看我的完整答案:
我需要将翻译提升到更高的水平,因为我的Excel日期也包含时间,所以我有类似于这样的数值:
42039.46406 --> 02/04/2015 11:08 AM
42002.37709 --> 12/29/2014 09:03 AM
42032.61869 --> 01/28/2015 02:50 PM
SELECT DATEADD(SECOND, (
CONVERT(FLOAT, t.ColumnName) -
FLOOR(CONVERT(FLOAT, t.ColumnName))
) * 86400,
DATEADD(DAY, CONVERT(FLOAT, t.ColumnName), '1899-12-30')
)
发现这个主题非常有帮助,因此为其创建了一个快速的 SQL UDF。
CREATE FUNCTION dbo.ConvertExcelSerialDateToSQL
(
@serial INT
)
RETURNS DATETIME
AS
BEGIN
DECLARE @dt AS DATETIME
SELECT @dt =
CASE
WHEN @serial is not null THEN CAST(@serial - 2 AS DATETIME)
ELSE NULL
END
RETURN @dt
END
GO
SELECT ((DATE('1899-12-30') + INTERVAL '1 day' * FLOOR(38242.7711805556)) + (INTERVAL '1 sec' * (38242.7711805556 - FLOOR(38242.7711805556)) * 3600 * 24)) as date
38242.7711805556
表示 Excel 格式中的 2004-09-12 18:30:30
。Google BigQuery 解决方案
标准 SQL
Select Date, DATETIME_ADD(DATETIME(xy, xm, xd, 0, 0, 0), INTERVAL xonlyseconds SECOND) xaxsa
from (
Select Date, EXTRACT(YEAR FROM xonlydate) xy, EXTRACT(MONTH FROM xonlydate) xm, EXTRACT(DAY FROM xonlydate) xd, xonlyseconds
From (
Select Date
, DATE_ADD(DATE '1899-12-30', INTERVAL cast(FLOOR(cast(Date as FLOAT64)) as INT64) DAY ) xonlydate
, cast(FLOOR( ( cast(Date as FLOAT64) - cast(FLOOR( cast(Date as FLOAT64)) as INT64) ) * 86400 ) as INT64) xonlyseconds
FROM (Select '43168.682974537034' Date) -- 09.03.2018 16:23:28
) xx1
)
SELECT DATETIME_ADD("1899-12-30",INTERVAL CAST(43909.91492 * 86400 AS INT64) SECOND)
(另外,上面的答案似乎差了一秒;无论是 Excel 还是我的代码都将该序列日期定在 2018年9月3日16:23:29
)。 - justbeez