web-dev-qa-db-ja.com

Excelの日付シリアル番号を通常の日付に変換します

Excel Date Serial Number DateのcsvファイルにDateOfBirthという列があります

例:

      36464
      37104
      35412

Excelでセルをフォーマットすると、これらは次のように変換されます

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

SSISまたはSQLでこの変換を行う必要があります。どうすればこれを達成できますか?

21
Sreedhar

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

33
Nick.McDermaid

マークされた回答は正常に機能していません。日付を「1899-12-31」ではなく「1899-12-30」に変更してください。

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

SQL smalldatetimeにキャストできます。

cast(41869 - 2 as smalldatetime)

SQL Serverは1900年1月1日からの日付をカウントし、1899年12月30日からのExcelは2日少ない。

9
Ricardo Souza

これは実際に私のために働いた

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

(日付でさらに1日を差し引く)

否定的なコメント投稿を参照

5
drinky

このトピックは非常に役立つことがわかったため、簡単な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
1
Lankymart

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

(また、少し複雑にするために、10進数の数値はNVARCHARとして保存されました)

この変換に使用したSQLは次のとおりです。

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

SSISソリューション

」DT_DATEデータ型は、8バイトの浮動小数点数を使用して実装されます。日は、1899年12月30日から始まり、0時として真夜中の整数の増分で表されます。時間値は、数値の小数部の絶対値。ただし、浮動小数点値はすべての実際の値を表すことはできません。したがって、DT_DATEで表示できる日付の範囲には制限があります。」 続きを読む

上記の説明から、これらの値を8バイト浮動小数点数DT_DATEに変換した後、DT_R8列にマッピングするときに暗黙的に変換できることがわかります。

派生列変換を使用して、この列を8バイトの浮動小数点数に変換します。

(DT_R8)[dateColumn]

次に、それをDT_DATE列にマップします

または、2回キャストします。

(DT_DATE)(DT_R8)[dateColumn]

ここで私の完全な答えを確認できます:

1
Hadi

@ Nick.McDermaidの答えに加えて、このソリューションを投稿したいと思います。これは、日だけでなく、時間、分、秒も変換します。

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

例えば

  • 42948.123から2017-08-01 02:57:07.000
  • 42818.7166666667から2017-03-24 17:12:00.000
0
Nicolaesse

ビューに日付を表​​示するだけの場合、これを実行できます。

大量のデータがある場合、CASTCONVERTよりも高速になります。Excelの日付から(2)を引くことも忘れないでください。

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

列を更新して日付を表示する必要がある場合は、結合(必要に応じて自己結合)を介して更新するか、単に次のことを試してください。

Excelの日付をINTとしてキャストする必要はないかもしれませんが、私が作業していたテーブルはvarcharであったため、最初にその操作を行う必要がありました。 「time」要素も必要ないため、最終キャストを「date」としてその要素を削除する必要がありました。

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

このテストでやりたいことがわからない場合は、再テストしてください!必要に応じて、テーブルのコピーを作成します。いつでもビューを作成できます!

0
Turkish

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を表します

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
 )
0
Selcuk Akbas