it-swarm.com.de

excel-Datums-Seriennummer in reguläres Datum konvertieren

Ich habe eine Spalte namens DateOfBirth in meiner CSV-Datei mit dem Datums-Seriennummer-Datum von Excel erhalten 

Beispiel: 

      36464
      37104
      35412

Wenn ich Zellen in Excel formatiert habe, werden diese als konvertiert 

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

Ich muss diese Umwandlung in SSIS oder in SQL durchführen. Wie kann das erreicht werden?

17
Sreedhar

In SQL:

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

In SSIS finden Sie hier

http://msdn.Microsoft.com/de-de/library/ms141719.aspx

29
Nick.McDermaid

Die markierte Antwort funktioniert nicht. Bitte ändern Sie das Datum in "1899-12-30" anstelle von "1899-12-31".

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

Sie können es in eine SQL-Smalldatetime umwandeln:

cast(41869 - 2 as smalldatetime)

SQL Server zählt seine Daten vom 01.01.1900 und Excel vom 30.12.1899 = 2 Tage weniger.

8
rcdmk

das hat tatsächlich für mich funktioniert 

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

(minus 1 weiteren Tag im Datum)

bezogen auf den negativ kommentierten Beitrag

4
drinky

Dieses Thema war so hilfreich, dass es eine schnelle SQL-UDF für dieses Thema erstellte.

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

Ich musste das auf die nächste Stufe bringen, da meine Excel-Daten auch Zeiten hatten, also hatte ich Werte wie diese:

42039.46406 --> 02/04/2015 11:08 AM
42002.37709 --> 12/29/2014 09:03 AM
42032.61869 --> 01/28/2015 02:50 PM

(Um es noch etwas zu komplizieren, wurde mein numerischer Wert mit Dezimalzahl als NVARCHAR gespeichert.)

Die SQL, die ich für diese Konvertierung verwendet habe, lautet:

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-Lösung

"Der Datentyp DT_DATE wird unter Verwendung einer 8-Byte-Gleitkommazahl implementiert. Tage werden durch Ganzzahlinkremente dargestellt, beginnend mit dem 30. Dezember 1899 und Mitternacht als Zeitnullpunkt.) Die Stundenwerte werden als absoluter Wert der angegeben Bruchteil der Zahl. Ein Gleitkommawert kann jedoch nicht alle reellen Werte darstellen. Daher gibt es Grenzen für den Datumsbereich, der in DT_DATE dargestellt werden kann. " Lesen Sie mehr

In der obigen Beschreibung können Sie sehen, dass Sie diese Werte implizit konvertieren können, wenn Sie sie in eine DT_DATE-Spalte abbilden, nachdem Sie sie in eine 8-Byte-Gleitkommazahl DT_R8 konvertiert haben.

Verwenden Sie eine abgeleitete Spaltenumwandlung, um diese Spalte in eine 8-Byte-Gleitkommazahl zu konvertieren:

(DT_R8)[dateColumn]

Ordnen Sie es dann einer DT_DATE-Spalte zu

Oder wirf es zweimal:

(DT_DATE)(DT_R8)[dateColumn]

Sie können meine vollständige Antwort hier überprüfen:

1
Hadi

Neben @ Nick.McDermaid Antwort möchte ich diese Lösung posten, die nicht nur den Tag, sondern auch die Stunden, Minuten und Sekunden konvertiert:

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

Zum Beispiel 

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

Sie können dies tun, wenn Sie nur das Datum in einer Ansicht anzeigen müssen:

CAST ist schneller als CONVERT, wenn Sie eine große Datenmenge haben. Denken Sie auch daran, (2) vom Excel-Datum abzuziehen:

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

Wenn Sie die Spalte aktualisieren müssen, um ein Datum anzuzeigen, können Sie entweder über einen Join aktualisieren (bei Bedarf auch selbst beitreten) oder einfach Folgendes versuchen:

Das Excel-Datum muss möglicherweise nicht als INT umgewandelt werden, aber da die Tabelle, mit der ich arbeitete, ein Varchar war, musste ich diese Manipulation zuerst durchführen. Ich wollte auch nicht das Element "time", also musste ich dieses Element mit der endgültigen Besetzung als "date" entfernen.

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

Wenn Sie sich nicht sicher sind, was Sie mit diesem Test machen möchten, und wiederholen Sie den Test! Machen Sie bei Bedarf eine Kopie Ihres Tisches. Sie können immer eine Ansicht erstellen!

0
Turkish

In postgresql können Sie die folgende Syntax verwenden:

SELECT ((DATE('1899-12-30') + INTERVAL '1 day' * FLOOR(38242.7711805556)) + (INTERVAL '1 sec' * (38242.7711805556 - FLOOR(38242.7711805556)) * 3600 * 24)) as date

In diesem Fall, 38242.7711805556 repräsentiert 2004-09-12 18:30:30 im Excel-Format

0

Google BigQuery-Lösung

Standard 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