Date Excel à horodatage Unix

85

Est-ce que quelqu'un sait comment convertir une date Excel en un horodatage Unix correct?

Hagbard
la source
Qu'entendez-vous par "excel date"? Voulez-vous dire du texte formaté comme une chaîne de date-heure lisible par l'homme "11/09/2009 3:23:24 PM"?
Matt Ball
4
N'oubliez pas que le 19 janvier 2038, l'horodatage Unix cessera de fonctionner en raison d'un dépassement de 32 bits. Avant ce moment, des millions d'applications devront soit adopter une nouvelle convention pour les horodatages, soit migrer vers des systèmes 64 bits, ce qui fera gagner un «peu» plus de temps à l'horodatage.
13
plus comme 32 bits plus de temps.
user606723

Réponses:

107

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

Cybercampbell
la source
6
N'oubliez pas votre fuseau horaire (sauf si vous êtes en UTC et que vous n'observez pas l'heure d'été). L'époque UNIX est indépendante du fuseau horaire, contrairement aux feuilles de calcul. Voici un guide avec des exemples.
Adam Katz
GMT + 8:=((A1+28800)/86400)+25569
Ivan Chau
heure actuelle pour CDT (heure =(NOW()-DATE(1970,1,1))*86400 + 5*3600
avancée du
Les versions modernes d'Excel se plaindront de la formule ci-dessus, sauf si vous remplacez les virgules par des points-virgules:(1970;1;1)
Jose Luis Blanco
1
@tonygil Cela fonctionnera si les cellules que vous ciblez sont en fait des dates dans Excel. Si c'est du texte censé représenter une date, tous les paris sont ouverts.
Casey
75

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)
Jeff Wu
la source
3
Office 2011 sur Mac semble fonctionner correctement avec la version «Windows» de ces formules. Les versions "Mac" sont bien loin.
radicand
1
Je pense que vous avez inversé les horodatages Excel et Unix dans ces formules. L'horodatage Unix est un nombre de secondes, et doit donc être divisé par 86400, plutôt que par l'horodatage Excel, ce que disent les formules. Voir la réponse de @ radicand.
Mike Houston
Merci pour les commentaires, testé ceci sur Mac Excel 2011 et il semble qu'ils soient identiques à la version Windows.
Jeff Wu
Existe-t-il un moyen de transformer un horodatage Unix en millisecondes en datetime, en préservant les millisecondes?
Lorenzo Belli
dit l'homme sur stackoverflow. ouais, qu'en est-il des secondes intercalaires, professeur.
catamphétamine
11

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

Grendler
la source
Cela ne fonctionne pas exactement sur Windows au moins. Il est éteint à 19 heures.
LLBBL
4
Donc ça devrait être ça: = (A1 * 86400) - 2209143600
LLBBL
2
La base de date par défaut de Mac Excel est 1904 alors que dans Windows Excel, elle est de 1900, mais vous pouvez modifier la base de date dans Mac Excel en décochant «utiliser le système de date 1904» sous préférences / calcul, puis cela fonctionne comme Windows Excel.
Cloudranger
6

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 awkpour 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é echopour 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 $1pour 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 … +%%zet le second , $1. Étant donné la fréquence de GNU, je ne recommanderais pas de supposer la version de BSD.

Le getlinelit le décalage de fuseau horaire produit par date +%zen 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 07ou 05, la seconde est 00ou 30(puis divisée par 60 pour être exprimée en heures), et la troisième utilisation de tzvoit 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 -dn'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 @1234567890comme entrée.

Punaise

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/0159    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.

Adam Katz
la source
3

É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+):

  • Horodatage Unix = (Excel Timestamp - 25569) * 86400
  • Horodatage Excel = (Unix Timestamp / 86400) + 25569

MAC OS X (avant Office 2011):

  • Horodatage Unix = (Excel Timestamp - 24107) * 86400
  • Horodatage Excel = (Unix Timestamp / 86400) + 24107
radicand
la source
2

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.

marque
la source
C'est correct, car Excel calcule la première année comme une année bissextile même si ce n'est pas le cas.
ANisus le
Je peux confirmer que le nombre magique est bien 2209161600, ceci étant 1970-01-01 - 1900-01-01 + 1 jour * 86400. Si vous entrez 1900-01-01 dans Excel et enregistrez au format sylk et regardez le fichier dans un éditeur de texte vous verrez qu'il enregistre cette date comme 1 au lieu de zéro comme il se doit, c'est pourquoi vous devez ajouter 1 jour
Cloudranger
1

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 :)

Sorbán Béla
la source
0

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.

  1. 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)) 
    
  2. Comme d'autres Grendler l'ont déjà indiqué ici, créez une autre colonne

    =(B2-DATE(1970,1,1))*86400 
    
  3. 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)))
    
  4. Créez une dernière colonne qui ajoute simplement les deux dernières colonnes ensemble:

    =C2+D2
    
Dranyar
la source
0

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);
};
catamphétamine
la source
0

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.

João
la source