Est-ce que quelqu'un sait comment convertir une date Excel en un horodatage Unix correct?
Est-ce que quelqu'un sait comment convertir une date Excel en un horodatage Unix correct?
Réponses:
Aucun de ceux-ci n'a fonctionné pour moi ... quand j'ai converti l'horodatage en arrière, c'est 4 ans.
Cela a parfaitement fonctionné: =(A2-DATE(1970,1,1))*86400
Le crédit revient à: Filip Czaja http://fczaja.blogspot.ca
Message original: http://fczaja.blogspot.ca/2011/06/convert-excel-date-into-timestamp.html
=((A1+28800)/86400)+25569
=(NOW()-DATE(1970,1,1))*86400 + 5*3600
(1970;1;1)
Windows et Mac Excel (2011):
Unix Timestamp = (Excel Timestamp - 25569) * 86400
Excel Timestamp = (Unix Timestamp / 86400) + 25569
MAC OS X (2007):
Unix Timestamp = (Excel Timestamp - 24107) * 86400
Excel Timestamp = (Unix Timestamp / 86400) + 24107
Pour référence:
86400 = Seconds in a day
25569 = Days between 1970/01/01 and 1900/01/01 (min date in Windows Excel)
24107 = Days between 1970/01/01 and 1904/01/02 (min date in Mac Excel 2007)
Si nous supposons que la date dans Excel est dans une cellule A1 au format Date et que l'horodatage Unix doit être dans une cellule A2 formatée en nombre, la formule en A2 doit être:
= (A1 * 86400) - 2209075200
où:
86400 est le nombre de secondes dans la journée. 2209075200 est le nombre de secondes entre le 01/01/1900 et le 01/01/1970, qui sont les dates de base des horodatages Excel et Unix.
Ce qui précède est vrai pour Windows. Sur Mac, la date de base dans Excel est 1904-01-01 et le nombre de secondes doit être corrigé à: 2082844800
Voici un mappage pour référence, en supposant UTC pour les systèmes de feuilles de calcul comme Microsoft Excel:
Unix Excel Mac Excel Human Date Human Time
Excel Epoch -2209075200 -1462 0 1900/01/00* 00:00:00 (local)
Excel ≤ 2011 Mac† -2082758400 0 1462 1904/12/31 00:00:00 (local)
Unix Epoch 0 24107 25569 1970/01/01 00:00:00 UTC
Example Below 1234567890 38395.6 39857.6 2009/02/13 23:31:30 UTC
Signed Int Max 2147483648 51886 50424 2038/01/19 03:14:08 UTC
One Second 1 0.0000115740… — 00:00:01
One Hour 3600 0.0416666666… ― 01:00:00
One Day 86400 1 1 ― 24:00:00
* «Jan Zero, 1900» correspond au 31/12/1899; voir la section Bug ci-dessous. † Excel 2011 pour Mac (et versions antérieures) utilise le système de date 1904 .
Comme j'utilise souvent awk
pour traiter le contenu CSV et délimité par des espaces, j'ai développé un moyen de convertir l'époque UNIX en un format de date Excel approprié au fuseau horaire / heure d' été :
echo 1234567890 |awk '{
# tries GNU date, tries BSD date on failure
cmd = sprintf("date -d@%d +%%z 2>/dev/null || date -jf %%s %d +%%z", $1, $1)
cmd |getline tz # read in time-specific offset
hours = substr(tz, 2, 2) + substr(tz, 4) / 60 # hours + minutes (hi, India)
if (tz ~ /^-/) hours *= -1 # offset direction (east/west)
excel = $1/86400 + hours/24 + 25569 # as days, plus offset
printf "%.9f\n", excel
}'
J'ai utilisé echo
pour cet exemple, mais vous pouvez diriger un fichier où la première colonne (pour la première cellule au format .csv, appelez-la comme awk -F,
) est une époque UNIX. Modifiez $1
pour représenter le numéro de colonne / cellule souhaité ou utilisez une variable à la place.
Cela fait un appel système à date
. Si vous disposez de manière fiable de la version GNU, vous pouvez supprimer le 2>/dev/null || date … +%%z
et le second , $1
. Étant donné la fréquence de GNU, je ne recommanderais pas de supposer la version de BSD.
Le getline
lit le décalage de fuseau horaire produit par date +%z
en tz
, qui est ensuite traduit en hours
. Le format sera comme -0700
( PDT ) ou +0530
( IST ), donc la première sous-chaîne extraite est 07
ou 05
, la seconde est 00
ou 30
(puis divisée par 60 pour être exprimée en heures), et la troisième utilisation de tz
voit si notre décalage est négatif et modifiehours
si besoin.
La formule donnée dans toutes les autres réponses de cette page est utilisée pour définir excel
, avec l'ajout de l'ajustement du fuseau horaire en fonction de l'heure d'été commehours/24
.
Si vous utilisez une ancienne version d'Excel pour Mac, vous devrez utiliser 24107
à la place de25569
(voir le mappage ci-dessus).
Pour convertir toute heure arbitraire non d'époque en heures compatibles Excel avec la date GNU:
echo "last thursday" |awk '{
cmd = sprintf("date -d \"%s\" +\"%%s %%z\"", $0)
cmd |getline
hours = substr($2, 2, 2) + substr($2, 4) / 60
if ($2 ~ /^-/) hours *= -1
excel = $1/86400 + hours/24 + 25569
printf "%.9f\n", excel
}'
C'est fondamentalement le même code, mais le date -d
n'a plus de @
pour représenter l'époque Unix (étant donné la capacité de l'analyseur de chaînes, je suis en fait surpris que le @
soit obligatoire; quel autre format de date a 9-10 chiffres?) Et il est maintenant demandé pour deux sorties: l'époque et le décalage du fuseau horaire. Vous pouvez donc utiliser par exemple @1234567890
comme entrée.
Lotus 1-2-3 (le logiciel de calcul original) a intentionnellement traité 1900 comme une année bissextile malgré le fait que ce n'était pas le cas (cela réduisait la base de code à un moment où chaque octet comptait). Microsoft Excel conservé ce bogue pour des raisons de compatibilité, sautant le jour 60 (le 29/02/1900 fictif), conservant le mappage de Lotus 1-2-3 du jour 59 au 28/02/1900. LibreOffice a plutôt attribué le jour 60 au 28/02/1900 et repoussé tous les jours précédents en arrière.
Toute date antérieure au 01/03/1900 peut représenter autant qu'un jour de congé:
Day Excel LibreOffice
-1 -1 1899/12/29
0 1900/01/00* 1899/12/30
1 1900/01/01 1899/12/31
2 1900/01/02 1900/01/01
…
59 1900/02/28 1900/02/27
60 1900/02/29(!) 1900/02/28
61 1900/03/01 1900/03/01
Excel ne reconnaît pas les dates négatives et a une définition spéciale du Zeroth de janvier (1899/12/31) pour le jour zéro. En interne, Excel gère en effet les dates négatives (ce ne sont que des nombres après tout), mais il les affiche sous forme de nombres car il ne sait pas comment les afficher sous forme de dates (et ne peut pas non plus convertir des dates plus anciennes en nombres négatifs). Le 29 février 1900, un jour qui ne s'est jamais produit, est reconnu par Excel mais pas par LibreOffice.
Étant donné que mes modifications apportées à ce qui précède ont été rejetées (est-ce que l'un de vous a essayé?), Voici ce dont vous avez vraiment besoin pour que cela fonctionne:
Windows (et Mac Office 2011+):
(Excel Timestamp - 25569) * 86400
(Unix Timestamp / 86400) + 25569
MAC OS X (avant Office 2011):
(Excel Timestamp - 24107) * 86400
(Unix Timestamp / 86400) + 24107
Vous avez apparemment perdu un jour, exactement 86 400 secondes. Utilisez le numéro 2209161600 Pas le numéro 2209075200 Si vous recherchez les deux numéros sur Google, vous trouverez une assistance pour ce qui précède. J'ai essayé votre formule mais j'arrivais toujours 1 jour différent de mon serveur. Ce n'est pas évident à partir de l'horodatage Unix à moins que vous ne pensiez en unix au lieu du temps humain ;-) mais si vous revérifiez, vous verrez que cela pourrait être correct.
J'avais une vieille base de données Excel avec des dates "lisibles par l'homme", comme 2010.03.28 20:12:30 Ces dates étaient en UTC + 1 (CET) et avaient besoin de la convertir en heure d'époque.
J'ai utilisé la formule = (A4-DATE (1970; 1; 1)) * 86400-3600 pour convertir les dates en heure d'époque de la colonne A en valeurs de colonne B. Vérifiez le décalage de votre fuseau horaire et faites un calcul avec. 1 heure équivaut à 3600 secondes.
La seule chose pour laquelle j'écris ici une réponse, vous pouvez voir que ce sujet a plus de 5 ans, c'est que j'utilise les nouvelles versions d'Excel et aussi les messages rouges dans ce sujet, mais ils sont incorrects. La DATE (1970; 1; 1). Ici, le 1970 et le janvier doivent être séparés avec; et pas avec,
Si vous rencontrez également ce problème, espérons que cela vous aidera. Bonne journée :)
Aucune des réponses actuelles n'a fonctionné pour moi car mes données étaient dans ce format du côté Unix:
02/02/2016 19:21:42 UTC
J'avais besoin de le convertir en Epoch pour permettre de référencer d'autres données qui avaient des horodatages d'époque.
Créez une nouvelle colonne pour la partie date et analysez-la avec cette formule
=DATEVALUE(MID(A2,6,2) & "/" & MID(A2,9,2) & "/" & MID(A2,1,4))
Comme d'autres Grendler l'ont déjà indiqué ici, créez une autre colonne
=(B2-DATE(1970,1,1))*86400
Créez une autre colonne avec juste le temps additionné pour obtenir le nombre total de secondes:
=(VALUE(MID(A2,12,2))*60*60+VALUE(MID(A2,15,2))*60+VALUE(MID(A2,18,2)))
Créez une dernière colonne qui ajoute simplement les deux dernières colonnes ensemble:
=C2+D2
Voici ma réponse ultime à cela.
Apparemment, le new Date(year, month, day)
constructeur de javascript ne tient pas compte non plus des secondes intercalaires.
// Parses an Excel Date ("serial") into a
// corresponding javascript Date in UTC+0 timezone.
//
// Doesn't account for leap seconds.
// Therefore is not 100% correct.
// But will do, I guess, since we're
// not doing rocket science here.
//
// https://www.pcworld.com/article/3063622/software/mastering-excel-date-time-serial-numbers-networkdays-datevalue-and-more.html
// "If you need to calculate dates in your spreadsheets,
// Excel uses its own unique system, which it calls Serial Numbers".
//
lib.parseExcelDate = function (excelSerialDate) {
// "Excel serial date" is just
// the count of days since `01/01/1900`
// (seems that it may be even fractional).
//
// The count of days elapsed
// since `01/01/1900` (Excel epoch)
// till `01/01/1970` (Unix epoch).
// Accounts for leap years
// (19 of them, yielding 19 extra days).
const daysBeforeUnixEpoch = 70 * 365 + 19;
// An hour, approximately, because a minute
// may be longer than 60 seconds, see "leap seconds".
const hour = 60 * 60 * 1000;
// "In the 1900 system, the serial number 1 represents January 1, 1900, 12:00:00 a.m.
// while the number 0 represents the fictitious date January 0, 1900".
// These extra 12 hours are a hack to make things
// a little bit less weird when rendering parsed dates.
// E.g. if a date `Jan 1st, 2017` gets parsed as
// `Jan 1st, 2017, 00:00 UTC` then when displayed in the US
// it would show up as `Dec 31st, 2016, 19:00 UTC-05` (Austin, Texas).
// That would be weird for a website user.
// Therefore this extra 12-hour padding is added
// to compensate for the most weird cases like this
// (doesn't solve all of them, but most of them).
// And if you ask what about -12/+12 border then
// the answer is people there are already accustomed
// to the weird time behaviour when their neighbours
// may have completely different date than they do.
//
// `Math.round()` rounds all time fractions
// smaller than a millisecond (e.g. nanoseconds)
// but it's unlikely that an Excel serial date
// is gonna contain even seconds.
//
return new Date(Math.round((excelSerialDate - daysBeforeUnixEpoch) * 24 * hour) + 12 * hour);
};
Pour compenser l' heure d'été (du dernier dimanche de mars au dernier dimanche d'octobre), j'ai dû utiliser la formule suivante:
=IF(
AND(
A2>=EOMONTH(DATE(YEAR(A2);3;1);0)-MOD(WEEKDAY(EOMONTH(DATE(YEAR(A2);3;1);0);11);7);
A2<=EOMONTH(DATE(YEAR(A2);10;1);0)-MOD(WEEKDAY(EOMONTH(DATE(YEAR(A2);10;1);0);11);7)
);
(A2-DATE(1970;1;1)-TIME(1;0;0))*24*60*60*1000;
(A2-DATE(1970;1;1))*24*60*60*1000
)
Explication rapide:
Si la date ["A2"] se situe entre le dernier dimanche de mars et le dernier dimanche d'octobre [troisième et quatrième lignes de code], alors je soustrais une heure [-TIME (1; 0; 0)] à la date.
"11/09/2009 3:23:24 PM"
?