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?
En SQL:
select dateadd(d,36464,'1899-12-30')
-- or thanks to rcdmk
select CAST(36464 - 2 as SmallDateTime)
Dans SSIS, voir ici
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')
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.
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é
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
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')
)
"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:
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
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!
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
)