Data do Excel para carimbo de data / hora Unix

85

Alguém sabe como converter uma data do Excel em um timestamp correto do Unix?

Hagbard
fonte
O que você quer dizer com "data do excel"? Você quer dizer texto formatado como uma string de data e hora legível, como "11/09/2009 3:23:24 PM"?
Matt Ball
4
Não se esqueça de que em 19 de janeiro de 2038 o Unix Time Stamp deixará de funcionar devido a um estouro de 32 bits. Antes deste momento, milhões de aplicativos precisarão adotar uma nova convenção para carimbos de data / hora ou migrar para sistemas de 64 bits, que comprarão o carimbo de data / hora um "pouco" mais tempo.
13
mais como 32 bits mais tempo.
user606723

Respostas:

107

Nenhum desses funcionou para mim ... quando eu converti o carimbo de data / hora de volta, faltam 4 anos.

Funcionou perfeitamente: =(A2-DATE(1970,1,1))*86400

O crédito vai para: Filip Czaja http://fczaja.blogspot.ca

Postagem original: http://fczaja.blogspot.ca/2011/06/convert-excel-date-into-timestamp.html

Cybercampbell
fonte
6
Não se esqueça do seu fuso horário (a menos que você esteja no UTC e não observe o horário de verão). A época do UNIX é agnóstica em relação ao fuso horário, enquanto as planilhas não. Aqui está um guia com exemplos.
Adam Katz
GMT + 8:=((A1+28800)/86400)+25569
Ivan Chau
hora atual para CDT (horário de verão central):=(NOW()-DATE(1970,1,1))*86400 + 5*3600
hBrent
As versões modernas do Excel reclamarão da fórmula acima, a menos que você substitua as vírgulas por ponto e vírgula:(1970;1;1)
Jose Luis Blanco
1
@tonygil Funcionará se as células que você está almejando forem realmente datas no Excel. Se for um texto que deveria representar uma data, todas as apostas estão canceladas.
Casey
76

Windows e 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

Para referência:

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
fonte
3
O Office 2011 no Mac parece funcionar bem com a versão "Windows" dessas fórmulas. As versões "Mac" estão bem distantes.
radicand
1
Acho que você reverteu os carimbos de data / hora do Excel e Unix nessas fórmulas. O carimbo de data / hora Unix tem um número de segundos e, portanto, precisa ser dividido por 86400, em vez do carimbo de data / hora do Excel, que é o que dizem as fórmulas. Veja a resposta de @radicand.
Mike Houston
Obrigado pelos comentários, testei isso no Mac Excel 2011 e parece que eles são iguais à versão do Windows.
Jeff Wu
Existe uma maneira de transformar um carimbo de data / hora unix em milissegundos em data e hora, preservando os milissegundos?
Lorenzo Belli
diz o homem no stackoverflow. sim, que tal segundos bissextos, professor.
catanfetamina
11

Se assumirmos que a data no Excel está na célula A1 formatada como Data e o carimbo de data / hora Unix deve estar em uma célula A2 formatada como número, a fórmula em A2 deve ser:

= (A1 * 86400) - 2209075200

Onde:

86400 é o número de segundos no dia 2209075200 é o número de segundos entre 1900-01-01 e 1970-01-01, que são as datas base para os carimbos de data / hora do Excel e Unix.

O acima é verdadeiro para o Windows. No Mac, a data base no Excel é 01/01/1904 e o número dos segundos deve ser corrigido para: 2082844800

Grendler
fonte
Não funciona exatamente no Windows, pelo menos. Ele está desligado por 19 horas.
LLBBL de
4
Portanto, deve ser assim: = (A1 * 86400) - 2209143600
LLBBL
2
A base de data padrão do Mac Excel é 1904 enquanto no Windows Excel é 1900, mas você pode alterar a base de data no Mac Excel desmarcando "usar o sistema de data 1904" em preferências / cálculo, então funciona como o Windows Excel.
Cloudranger
7

Aqui está um mapeamento para referência, assumindo UTC para sistemas de planilhas como o 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

*   “Janeiro Zero, 1900” é 1899/12/31; veja a seção Bug abaixo. Excel 2011 para Mac (e anteriores) usa o sistema de data 1904 .

 

Como costumo usar awkpara processar CSV e conteúdo delimitado por espaço, desenvolvi uma maneira de converter a época do UNIX em formato de data do Excel adequado para fuso horário / horário de verão :

Usei echopara este exemplo, mas você pode canalizar um arquivo em que a primeira coluna (para a primeira célula no formato .csv, chame-o de awk -F,) é uma época UNIX. Altere $1para representar o número da coluna / célula desejada ou use uma variável.

Isso faz uma chamada de sistema para date. Se você tiver a versão GNU confiável, pode remover o 2>/dev/null || date … +%%ze o segundo , $1. Dado o quão comum o GNU é, eu não recomendaria assumir a versão do BSD.

O getlinelê o deslocamento de fuso horário gerado por date +%zem tz, que é então convertido em hours. O formato será como -0700( PDT ) ou +0530( IST ), então a primeira substring extraída é 07ou 05, a segunda é 00ou 30(então dividido por 60 para ser expresso em horas), e o terceiro uso de tzvê se nosso deslocamento é negativo e altera hoursse necessário.

A fórmula fornecida em todas as outras respostas nesta página é usada para definir excel, com a adição do ajuste de fuso horário em função do horário de verão como hours/24.

Se você estiver em uma versão mais antiga do Excel para Mac, precisará usar 24107no lugar de 25569(consulte o mapeamento acima).

Para converter qualquer hora arbitrária fora da época em horas compatíveis com o Excel com data GNU:

Este é basicamente o mesmo código, mas date -dnão tem mais um @para representar a época unix (dada a capacidade do analisador de strings, estou realmente surpreso que @seja obrigatório; que outro formato de data tem de 9 a 10 dígitos?) E agora é perguntado para duas saídas: a época e o deslocamento de fuso horário. Portanto, você pode usar, por exemplo, @1234567890como uma entrada.

Erro

O Lotus 1-2-3 (o software de planilha original) tratou intencionalmente 1900 como um ano bissexto, apesar do fato de que não foi (isso reduziu a base de código no momento em que cada byte era contado). O Microsoft Excel manteve esse bug para compatibilidade, ignorando o dia 60 (o fictício 1900/02/29), mantendo o mapeamento do Lotus 1-2-3 do dia 59 para 1900/02/28. Em vez disso, o LibreOffice atribuiu o dia 60 a 1900/02/28 e adiou todos os dias anteriores um.

Qualquer data antes de 1900/03/01 pode significar até um dia de folga:

O Excel não reconhece datas negativas e tem uma definição especial do Zeroth de janeiro (1899/12/31) para o dia zero. Internamente, o Excel realmente lida com datas negativas (afinal, são apenas números), mas os exibe como números, pois não sabe como exibi-los como datas (nem pode converter datas mais antigas em números negativos). 29 de fevereiro de 1900, um dia que nunca aconteceu, é reconhecido pelo Excel, mas não pelo LibreOffice.

Adam Katz
fonte
4

Como minhas edições acima foram rejeitadas (algum de vocês realmente tentou?), Aqui está o que você realmente precisa para fazer isso funcionar:

Windows (e Mac Office 2011+):

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

MAC OS X (antes do Office 2011):

  • Unix Timestamp = (Excel Timestamp - 24107) * 86400
  • Excel Timestamp = (Unix Timestamp / 86400) + 24107
Radicand
fonte
2

Você está aparentemente errado por um dia, exatamente 86400 segundos. Use o número 2209161600 Não o número 2209075200 Se você pesquisar os dois números no Google, encontrará suporte para os anteriores. Tentei sua fórmula mas sempre aparecia 1 dia diferente do meu servidor. Não é óbvio a partir do carimbo de data / hora do Unix, a menos que você pense no Unix ao invés do tempo humano ;-) mas se você verificar novamente, verá que pode estar correto.

Marca
fonte
Correto, porque o Excel calculou o primeiro ano como um ano bissexto, embora não seja.
ANisus
Posso confirmar que o número mágico é de fato 2209161600, sendo 01/01/1970 - 01/01/1900 + 1 dia * 86400. Se você inserir 01/01/1900 no excel, salve no formato sylk e observe o arquivo em um editor de texto, você verá que ele salva essa data como 1 em vez de zero como deveria, e é por isso que você deve adicionar 1 dia
Cloudranger
1

Eu tinha um banco de dados Excel antigo com datas "legíveis por humanos", como 2010.03.28 20:12:30 Essas datas estavam em UTC + 1 (CET) e precisava convertê-las para o tempo de época.

I utilizado o = (A4-DATA (1970; 1; 1)) * 86400-3600 fórmula para converter as datas de tempo época a partir da coluna A para os valores da coluna B. Verifique a diferença de fuso horário e faça contas com ela. 1 hora equivale a 3600 segundos.

A única coisa que eu escrevo aqui uma resposta, você pode ver que este tópico tem mais de 5 anos é que eu uso as novas versões do Excel e também posts vermelhos neste tópico, mas eles estão incorretos. A DATE (1970; 1; 1). Aqui, o 1970 e o janeiro precisam ser separados com; e não com,

Se você também estiver enfrentando esse problema, espero que ajude. Tenha um bom dia :)

Sorbán Béla
fonte
0

Nenhuma das respostas atuais funcionou para mim porque meus dados estavam neste formato no lado unix:

2016-02-02 19:21:42 UTC

Eu precisei converter isso para Epoch para permitir a referência de outros dados que tinham timestamps de época.

  1. Crie uma nova coluna para a parte da data e analise com esta fórmula

    =DATEVALUE(MID(A2,6,2) & "/" & MID(A2,9,2) & "/" & MID(A2,1,4)) 
    
  2. Como outro Grendler já afirmou aqui, crie outra coluna

    =(B2-DATE(1970,1,1))*86400 
    
  3. Crie outra coluna apenas com o tempo adicionado para obter o total de segundos:

    =(VALUE(MID(A2,12,2))*60*60+VALUE(MID(A2,15,2))*60+VALUE(MID(A2,18,2)))
    
  4. Crie uma última coluna que apenas adiciona as duas últimas colunas:

    =C2+D2
    
Dranyar
fonte
0

Aqui está minha resposta final para isso.

Aparentemente, o new Date(year, month, day)construtor do JavaScript também não leva em conta os segundos bissextos.

// 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);
};
catanfetamina
fonte
0

Para compensar o horário de verão (começando no último domingo de março até o último domingo de outubro), tive que usar a seguinte fórmula:

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

Explicação rápida:

Se a data ["A2"] for entre o último domingo de março e o último domingo de outubro [terceira e quarta linhas de código], então estarei subtraindo uma hora [-TIME (1; 0; 0)] da data.

João
fonte