web-dev-qa-db-fra.com

convertir le numéro de série de la date Excel en date normale

J'ai une colonne appelée DateOfBirth dans mon fichier csv avec Excel Date Numéro de série Date 

Exemple: 

      36464
      37104
      35412

Lorsque je cellules formatées dans Excel, celles-ci sont converties en 

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

J'ai besoin de faire cette transformation en SSIS ou en SQL. Comment cela peut il etre accompli?

17
Sreedhar

En SQL:

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

Dans SSIS, voir ici

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

29
Nick.McDermaid

La réponse marquée ne fonctionne pas bien, veuillez changer la date en "1899-12-30" au lieu de "1899-12-31".

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

Vous pouvez le convertir en SQL smalldatetime:

cast(41869 - 2 as smalldatetime)

SQL Server compte ses dates du 01/01/1900 et Excel du 30/12/1899 = 2 jours de moins.

8
rcdmk

cela a réellement fonctionné pour moi 

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

(moins 1 jour de plus dans la date)

faisant référence au post négatif commenté

4
drinky

Cette rubrique vous a été utile, elle a donc créé un fichier UDF SQL rapide.

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

Je devais prendre cela au niveau suivant parce que mes dates Excel avaient aussi des temps, donc j'avais des valeurs comme celle-ci:

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

(aussi, pour compliquer un peu plus, ma valeur numérique avec décimale a été enregistrée en tant que NVARCHAR)

Le SQL que j'ai utilisé pour effectuer cette conversion est:

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

Solution SSIS

"Le type de données DT_DATE est implémenté à l’aide d’un nombre à virgule flottante de 8 octets. Les jours sont représentés par des incréments de nombres entiers, commençant le 30 décembre 1899, et à minuit à l’heure zéro. partie décimale du nombre. Toutefois, une valeur à virgule flottante ne peut pas représenter toutes les valeurs réelles; par conséquent, la plage de dates pouvant être présentée dans DT_DATE est limitée. " En savoir plus _

Dans la description ci-dessus, vous pouvez voir que vous pouvez convertir ces valeurs implicitement lorsque vous les mappez à une colonne DT_DATE après l'avoir convertie en un nombre à virgule flottante de 8 octets DT_R8.

Utilisez une transformation de colonne dérivée pour convertir cette colonne en nombre à virgule flottante de 8 octets:

(DT_R8)[dateColumn]

Puis mappez-le sur une colonne DT_DATE

Ou lancez-le deux fois:

(DT_DATE)(DT_R8)[dateColumn]

Vous pouvez vérifier ma réponse complète ici:

1
Hadi

En plus de la réponse @ Nick.McDermaid, j'aimerais publier cette solution, qui convertit non seulement le jour mais également les heures, les minutes et les secondes:

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

Par exemple 

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

Vous pouvez le faire s'il vous suffit d'afficher la date dans une vue:

CAST sera plus rapide que CONVERT si vous avez une grande quantité de données, n'oubliez pas de soustraire (2) de la date Excel:

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

Si vous devez mettre à jour la colonne pour afficher une date, vous pouvez mettre à jour via une jointure (auto-rejoindre si nécessaire) ou simplement procéder comme suit:

Vous n’avez peut-être pas besoin de convertir la date Excel en INT, mais comme la table sur laquelle je travaillais était un varchar, je devais commencer par manipuler. Je ne voulais pas non plus l'élément "time", donc j'avais besoin de supprimer cet élément avec la distribution finale comme "date".

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

Si vous n'êtes pas sûr de ce que vous aimeriez faire avec ce test et testez à nouveau! Faites une copie de votre table si vous en avez besoin. Vous pouvez toujours créer une vue!

0
Turkish

Solution Google BigQuery

SQL standard

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