Muitas vezes, quero fazer alguns cálculos rápidos de data, como:
- Qual é a diferença entre essas duas datas?
- Qual é a data n semanas após esta outra data?
Normalmente, abro um calendário e conto os dias, mas acho que deve haver um programa / script que eu possa usar para fazer esse tipo de cálculo. Alguma sugestão?
Respostas:
As "n semanas após uma data" são fáceis com a data GNU (1):
Não conheço uma maneira simples de calcular a diferença entre duas datas, mas você pode envolver um pouco de lógica em torno do date (1) com uma função shell.
Troque
d1
ed2
se você quiser o cálculo da data de outra maneira, ou fique um pouco mais sofisticado para que isso não importe. Além disso, no caso de uma transição não DST para DST no intervalo, um dos dias terá apenas 23 horas; você pode compensar adicionando ½ dia à soma.fonte
Para um conjunto de ferramentas portáteis, tente meus próprios dateutils . Seus dois exemplos se resumem a one-liners:
ou em semanas e dias:
e
fonte
dateadd -i '%m%d%Y' 01012015 +1d
não parecer funcionar, ele fica suspenso indefinidamente ... funciona se as especificações de data forem separadas por um caractere, qualquer caractere ... alguma idéia do que há de errado?)Um exemplo de python para calcular o número de dias em que andei no planeta:
fonte
ychaouche@ychaouche-PC ~ $ python -c "from datetime import date as d; print (d.today() - d(1980, 6, 14)).days"
12813
ychaouche@ychaouche-PC ~ $
Eu geralmente prefiro ter a hora / data no formato unix utime (número de segundos desde a época, quando os anos setenta começaram, UTC). Dessa forma, sempre se resume a subtração simples ou adição de segundos.
O problema geralmente é transformar uma data / hora nesse formato.
Em um ambiente / script de shell, você pode obtê-lo
date '+%s'
No momento da escrita, a hora atual é1321358027
.Para comparar com 2011-11-04 (meu aniversário)
date '+%s' -d 2011-11-04
,, produzindo1320361200
. Subtrair:expr 1321358027 - 1320361200
fornece996827
segundos, ou seja, háexpr 996827 / 86400
11 dias.A conversão do utime (formato 1320361200) para uma data é muito simples, por exemplo, C, PHP ou perl, usando bibliotecas padrão. Com o GNU
date
, o-d
argumento pode ser anexado@
para indicar o formato "Segundos desde a época".fonte
date -d @1234567890
converte de segundos desde a época para qualquer formato de data que você especificar.info date
, especialmente os segundos desde a época nó: “Se você preceder um número com '@', representa um selo de tempo interna como uma contagem de segundos.”Se uma ferramenta gráfica é boa para você, eu recomendo
qalculate
(uma calculadora com ênfase em conversões de unidades, ela vem com uma interface GTK e KDE, IIRC). Lá você pode dizer, por exemplopara obter o número de dias (140, desde 1900 não foi um ano bissexto) entre as datas, mas é claro que você também pode fazer o mesmo por vezes:
gera
8.4591667
horas ou, se você definir a saída para formatar a hora8:27:33
,.fonte
qalc
entãohelp days
.qcalc
exemplo:qalc -t 'days(1900-05-21, 1900-01-01)'
-> 140Isso surgiu ao usar
date -d "$death_date - $y years - $m months - $d days"
para obter uma data de nascimento (para genealogia). Esse comando está errado. Meses não têm a mesma duração, então(date + offset) - offset != date
. As idades, em ano / mês / dia, são medidas que avançam a partir da data de nascimento.A data fornece a saída correta nos dois casos, mas no segundo caso, você estava fazendo a pergunta errada. É importante QUAIS 11 meses do ano a cobertura +/- 11, antes de adicionar / subtrair dias. Por exemplo:
Para subtrair a operação inversa da adição, a ordem das operações teria que ser revertida. Adicionar adiciona anos, ENTÃO meses, ENTÃO dias. Se subtrair usasse a ordem oposta, você retornaria ao seu ponto de partida. Não, se não, se o deslocamento dos dias ultrapassar o limite do mês em um mês diferente.
Se você precisar trabalhar de trás para frente a partir de uma data e idade de término, poderá fazê-lo com várias invocações de
date
. Primeiro subtraia os dias, depois os meses e depois os anos. (Não acho seguro combinar os anos e os meses em uma únicadate
invocação, por causa dos anos bissextos que alteram a duração de fevereiro.)fonte
Eu freqüentemente uso SQL para cálculos de datas. Por exemplo , MySQL , PostgreSQL ou SQLite :
Outras vezes, sinto vontade de usar o JavaScript. Por exemplo , SpiderMonkey , WebKit , Seed ou Node.js :
(Cuidado ao passar o mês para o
Date
construtor do objeto JavaScript . Começa com 0.)fonte
Outra maneira de calcular a diferença entre duas datas do mesmo ano civil, você pode usar isso:
date
à variável DATEfirstnum. O-d
sinalizador exibe a sequência em um formato de hora, neste caso, em 14 de maio de 2014 e+"%j"
informadate
para formatar a saída apenas para o dia do ano (1-365).DAYSdif
à diferença dos dois dias.DAYSdif
.Isso funciona com a versão GNU
date
, mas não na versão PC-BSD / FreeBSD. Eu instalei acoreutils
partir da árvore de portas e usei o comando/usr/local/bin/gdate
.fonte
DATEfirstnum=$(date -d "$1" +%s)
DATElastnum=$(date -d "$2" +%s)
Além disso, este script não poderá calcular a diferença entre dois anos diferentes.+%j
refere-se ao dia do ano (001..366), portanto./date_difference.sh 12/31/2001 12/30/2014
gera -1. Como outras respostas observaram, você precisa converter as duas datas em segundos desde 1970-01-01 00:00:00 UTC.$
expressão aritmética interna:$((DATElastnum - DATEfirstnum))
também funcionará.Com a ajuda das soluções dannas, isso pode ser feito em uma linha com o seguinte código:
(Funciona no Python 2.xe no Python 3.)
fonte
date
e o bash podem fazer diferenças de data (opções do OS X mostradas). Coloque a última data primeiro.fonte
Há também cálculos de tempo da unidade GNU combinados com a data GNU:
(gunits são unidades no Linux, gdate é data)
fonte
datediff.sh no github: gist
fonte
A resposta de camh cuida da maior parte, mas podemos melhorar para lidar com arredondamentos, fusos horários etc., além de obtermos uma precisão extra e a capacidade de escolher nossas unidades:
-d
informadate
que estamos fornecendo uma data e hora para a conversão.+%s.%N
altera a data e hora para seconds.nanosegundos desde 1970-01-01 00:00:00 UTC.bc
calcula a diferença entre os dois números e o fator de divisão nos leva a diferentes unidades.printf
adiciona um 0 antes da casa decimal, se necessário (bc
não) e garante que o arredondamento vá para o mais próximo (bc
apenas trunca). Você também pode usarawk
.Agora vamos executar isso com um caso de teste descolado,
Observe que, como a duração de um mês ou ano nem sempre é a mesma, não existe uma única resposta "correta", embora se possa usar 365,24 dias como uma aproximação razoável atualmente.
fonte
Você pode usar a biblioteca awk Velour :
Ou:
Resultado:
fonte