将Excel日期序列号转换为常规日期

时间:2012-12-12 23:40:30

标签: sql sql-server tsql ssis etl

我的csv文件中有一个名为DateOfBirth的列,其中包含Excel Date Serial Number Date

示例:

      36464
      37104
      35412

当我在Excel中格式化单元格时,这些单元格将转换为

      36464 => 1/11/1999
      37104 => 1/08/2001
      35412 => 13/12/1996

我需要在SSIS或SQL中进行此转换。如何实现这一目标?

15 个答案:

答案 0 :(得分:31)

在SQL中:

select dateadd(d,36464,'1899-12-30')
-- or thanks to rcdmk
select CAST(36464 - 2 as SmallDateTime)

在SSIS中,请参阅此处

http://msdn.microsoft.com/en-us/library/ms141719.aspx

答案 1 :(得分:12)

标记的答案不正常,请将日期更改为" 1899-12-30"而不是" 1899-12-31"。

select dateadd(d,36464,'1899-12-30')

答案 2 :(得分:8)

您可以将其强制转换为SQL smalldatetime:

cast(41869 - 2 as smalldatetime)

SQL Server计算其日期从01/01/1900开始,Excel从12/30/1899开始计算= 2天。

答案 3 :(得分:5)

这实际上对我有用

dateadd(mi,CONVERT(numeric(17,5),41869.166666666664)*1440,'1899-12-30') 

(日期减去1天)

指的是负面评论帖子

答案 4 :(得分:1)

发现此主题非常有用,因此为它创建了一个快速的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

答案 5 :(得分:1)

SSIS解决方案

“DT_DATE数据类型使用8字节浮点数实现。天数以整数增量表示,从1899年12月30日开始,午夜表示为时间零。小时值表示为绝对值数字的小数部分的值。但是,浮点值不能代表所有实际值;因此,DT_DATE中可以显示的日期范围有限制。“ Read more

从上面的描述中可以看出在将它们转换为8字节浮点数DT_DATE后将它们映射到DT_R8列时,可以隐式转换这些值。 /强>

使用派生列转换将此列转换为8字节浮点数:

(DT_R8)[dateColumn]

然后将其映射到DT_DATE

或投两次:

(DT_DATE)(DT_R8)[dateColumn]

您可以在此处查看我的完整答案:

答案 6 :(得分:1)

我不得不把它带到一个新的水平,因为我的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

(另外,为了使其复杂化,我的十进制数值被保存为NVARCHAR)

我以前用于进行此转换的SQL是:

SELECT DATEADD(SECOND, (
                        CONVERT(FLOAT, t.ColumnName) - 
                        FLOOR(CONVERT(FLOAT, t.ColumnName))
                       ) * 86400,
               DATEADD(DAY, CONVERT(FLOAT, t.ColumnName), '1899-12-30')
              )

答案 7 :(得分:1)

tldr:

select cast(@Input - 2e as datetime)

说明:

Excel stores datetimes as a floating point number代表20世纪初以来经过的时间,SQL Server可以以相同的方式在floats和日期时间之间轻松转换。 Excel和SQL Server将此数字转换为日期时间之间的差异为2天(as of 1900-03-01, that is)。为这种差异使用文字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

答案 8 :(得分:0)

除了@ Nick.McDermaid回答我想发布这个解决方案,它不仅可以转换日期,还可以转换小时,分钟和秒:

SELECT DATEADD(s, (42948.123 - FLOOR(42948.123))*3600*24, dateadd(d, FLOOR(42948.123),'1899-12-30'))

例如

  • 42948.1232017-08-01 02:57:07.000
  • 42818.71666666672017-03-24 17:12:00.000

答案 9 :(得分:0)

如果您只需要在视图中显示日期,则可以执行此操作:

如果你有大量数据,

CAST将比CONVERT快,还记得从excel日期中减去(2):

CAST(CAST(CAST([Column_With_Date]-2 AS INT)AS smalldatetime) AS DATE)

如果您需要更新列以显示日期,您可以通过加入进行更新(如有必要,可以自行加入),或者只需尝试以下操作:

您可能不需要将excel日期转换为INT,但由于我正在使用的表是varchar,因此我必须首先执行该操作。我也不想要"时间"因此我需要将最终演员阵容删除为" date。"

UPDATE [Table_with_Date]
SET [Column_With_Excel_Date] = CAST(CAST(CAST([Column_With_Excel_Date]-2 AS INT)AS smalldatetime) AS DATE)

如果您不确定您希望对此测试做什么并重新测试!如果需要,请复制您的表格。您始终可以创建视图!

答案 10 :(得分:0)

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
 )

答案 11 :(得分:0)

在postgresql中,您可以使用以下语法:

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

答案 12 :(得分:0)

对于那些希望在excel中完成此操作的人(除格式化为日期字段外),您可以使用文本功能https://exceljet.net/excel-functions/excel-text-function

A1 = 132134
=Text(A1,"MM-DD-YYYY") will result in a date

答案 13 :(得分:-2)

尝试以下链接中讨论的方法,该方法涉及创建一个执行转换并在SQL中应用该函数的函数。

http://www.ehow.com/how_12073756_convert-julian-date-sql.html

答案 14 :(得分:-3)

这对我有用,因为有时字段是获取时间部分的数字。

命令:

 dateadd(mi,CONVERT(numeric(17,5),41869.166666666664)*1440,'1899-12-31')