De vez em quando necessitamos fazer cálculos com datas para nós mesmos ou dentro de scripts. O comando date possui ótimos recursos para nos auxiliar nisso. Este post irá mostrar algumas das possibilidades de cálculo utilizando o date. Mas, antes de tudo, falarei um pouco sobre formatação.
Formatação de datas e hora
O comando date permite a formatação de datas e hora. Basta utilizar uma expressão de formatação iniciada com o caractere “soma”. Exemplos:
$ date Ter Fev 14 16:15:48 BRST 2012 $ date "+%d de %B de %Y" 14 de fevereiro de 2012
No caso acima, %d refere-se ao dia, %b ao mês e %Y ao ano. Para saber mais sobre os parâmetros possíveis, consulte o manual on-line do comando date ($ man date) e procure por FORMAT.
Observação: BRST significa Brazilian Summer Time. Fora da época de horário de verão teremos BRT (Brazilian Time).
Cálculos elementares
Agora veremos alguns exemplos de cálculos com datas. Será necessário utilizar a chave -d. Apenas ressalto que o resultado final pode utilizar formatação, como descrito antes.
Datas e horas passadas e futuras
Alguns exemplos:
$ date Ter Fev 14 16:35:46 BRST 2012 $ date -d "+10 days" Sex Fev 24 16:38:00 BRST 2012 $ date -d "-10 days" Sáb Fev 4 16:38:17 BRST 2012 $ date -d "+10 min" Ter Fev 14 16:49:09 BRST 2012 $ date -d "-10 min" Ter Fev 14 16:29:27 BRST 2012 $ date -d "+10 days -2 hours +10 min -50 secs" Sex Fev 24 14:49:51 BRST 2012
Agora com formatação:
$ date -d "+10 days -2 hours +10 min -50 secs" '+%d %b %y, %H:%Mh' 24 Fev 12, 14:50h $ date -d "+2 years +1 month -1 week" '+%d %b %y, %H:%Mh' 07 Mar 14, 15:47h
Exemplo em script:
#!/bin/bash DATA=$(LANG=C date -d "-1 day" '+%b %e') cat /var/log/syslog | grep "$DATA" | grep login
Na verdade, você tem que ser intuitivo para lidar com o date. Olha que exemplo louco:
$ date -d "next fri" Sex Fev 17 00:00:00 BRST 2012
Ele mostrou a data da próxima sexta-feira (fri de friday). Outra saída, caso você não seja intuitivo, é ler o código fonte do comando. O manual on-line não cita as possibilidades. Então, tais possibilidades são (algumas aceitam plural, como hours): ago, day, fortnight, hour, last, min, month, next, now, sec, this, today, tomorrow, week, year e yesterday.
Outro exemplo:
$ date -d "last fri" Sex Fev 10 00:00:00 BRST 2012
Agora preste atenção: day, fortnight, hour, min, month, sec, week e year são conhecidos como unidades e PODEM ser combinados com ago, last, next, now, this, today, tomorrow e yesterday, que são os modificadores. Exemplo:
$ date -d "last-week +1 day" Qua Fev 8 17:55:00 BRST 2012
Unix Epoch
Para quem não sabe, o Unix Epoch é uma data de referência do Unix, ou seja, 01 de janeiro de 1970, às 00:00h. Os Unix utilizam bastante essa data. Por exemplo: quando você inclui um usuário no sistema com o comando adduser, uma linha é gerada no arquivo /etc/shadow. O terceiro campo dessa linha é a quantidade de dias decorridos desde o Unix Epoch. Então, é possível saber quando o usuário foi cadastrado ou quando a sua conta foi alterada pela última vez. Veja:
eriberto:$6$8wFWksz9$cGv03Q0y9B3bKVvao168QueUhv7ViMkS3SdXGOYOyqDaaUmjIit3m/0F6/98jTaglalgfatWGpVL4mp/x7oag/:15134:0:99999:7:::
No caso, 15134 é o número de dias desde o Epoch.
É importante dizer que a unidade do Epoch pode variar de aplicação para aplicação. Alguns logs, por exemplo utilizam a quantidade de segundos e não o de dias. É o caso do log do Squid. Veja o exemplo de uma linha desse log:
1294013828.588 0 84.63.123.123 TCP_MEM_HIT/200 943 GET http://www.debianet.com.br NONE/- text/css
No caso, 1294013828 é a quantidade de segundos. O 588 representa fração de segundos.
Cálculos com Epoch
Para saber o Epoch em segundos da data atual, utilize o comando:
$ date +%s 1329246450
Note que %s, segundo o manual on-line do comando date, significa a quantidade segundos passados desde a 00h de 01/01/1970. Para fazer o cálculo inverso, utilize a opção -d com o caractere “@” antes do número. Exemplo:
$ date -d @1329246450 Ter Fev 14 17:07:30 BRST 2012
Para saber o Epoch de uma data qualquer, com a hora, basta especificá-las. O detalhe é que tem que ser em inglês. Exemplo:
$ date +"%s" -d "Feb 14 17:07:30 BRST 2012" 1329246450
Também é possível remover a hora:
$ date +"%s" -d "Feb 14 2012" 1329184800
Assim, fazer cálculos com datas e Epoch ficou fácil. Basta utilizar os conceitos anteriores. Darei alguns exemplos. Comecemos calculando qual data representa o Epoch 15134 em dias.
$ date -d "1970-01-01 +15134 days" Qui Jun 9 00:00:00 BRT 2011
Agora, veremos o que representa o Epoch 1329246450 em segundos. Já vimos uma forma fácil de fazer isso. Mas uma outra forma seria:
$ date -d "1970-01-01 +1329246450 secs" Ter Fev 14 20:07:30 BRST 2012
Note que houve uma diferença de 3 horas entre a resposta anterior e esta, considerando ainda o horário de verão (estamos vivendo ele hoje). Isso me parece ser um bug do comando (ou de libraries). Mas se pedirmos o resultado em UTC (hora de Greenwitch), com a opção -u, o resultado será igual. Veja:
$ date -d @1329246450 -u Ter Fev 14 19:07:30 UTC 2012 $ date -d "1970-01-01 +1329246450 secs" -u Ter Fev 14 19:07:30 UTC 2012
Como no horário de verão estamos a menos de 2 horas de Greenwitch, o resultado correto brasileiro deveria ser 17:07h. Então, o cálculo com o comando “date -d @1329246450” foi mais preciso. Mas, digamos que o outro comando quebra o galho.
Comando cal
Já que estamos falando de datas, o comando cal também pode ser útil. Ele nos fornece um calendário on-line sempre que precisamos. Exemplos:
$ cal Fevereiro 2012 Do Se Te Qu Qu Se Sá 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
Há outras opções interessantes:
$ cal -3 —> fornece o calendário do mês anterior, do atual e do próximo.
$ cal 2012 —> mostra o calendário de 2012.
$ cal 9 1971 —> mostra o calendário de setembro de 1971.
$ cal -j —> mostra o calendário juliano.
Este post é particularmente útil para administradores de sistemas.
[]s!
Muito interessante..
Sabia de alguns comandos, mais não todos!
Parabéns pelo post o/
Só o comando ‘cal’ já ajudou muito.
Obrigado pelas dicas de date, tambem. Agora consigo fazer scripts melhores.
Gostei muito, mais ainda da parte que vc sugere ler o código. Estive com um problema que me chamou atenção sobre isto.
Muito bom seus posts.
Parabéns. Blog limpo e prático.
Grato Luiz Carlos.
[]s