{"id":967,"date":"2012-02-14T17:07:10","date_gmt":"2012-02-14T20:07:10","guid":{"rendered":"http:\/\/eriberto.pro.br\/blog\/?p=967"},"modified":"2012-02-15T14:10:15","modified_gmt":"2012-02-15T17:10:15","slug":"calculo-de-datas-com-o-comando-date-no-gnulinux","status":"publish","type":"post","link":"https:\/\/eriberto.pro.br\/blog\/2012\/02\/14\/calculo-de-datas-com-o-comando-date-no-gnulinux\/","title":{"rendered":"C\u00e1lculo de datas com o comando date no GNU\/Linux"},"content":{"rendered":"<p>De vez em quando necessitamos fazer c\u00e1lculos com datas para n\u00f3s mesmos ou dentro de scripts. O comando <strong>date<\/strong> possui \u00f3timos recursos para nos auxiliar nisso. Este post ir\u00e1 mostrar algumas das possibilidades de c\u00e1lculo utilizando o date. Mas, antes de tudo, falarei um pouco sobre formata\u00e7\u00e3o.<\/p>\n<h2>Formata\u00e7\u00e3o de datas e hora<\/h2>\n<p>O comando date permite a formata\u00e7\u00e3o de datas e hora. Basta utilizar uma express\u00e3o de formata\u00e7\u00e3o iniciada com o caractere &#8220;soma&#8221;. Exemplos:<\/p>\n<pre>$ date\r\nTer Fev 14 16:15:48 BRST 2012\r\n\r\n$ date \"+%d de %B de %Y\"\r\n14 de fevereiro de 2012<\/pre>\n<p>No caso acima, %d refere-se ao dia, %b ao m\u00eas e %Y ao ano. Para saber mais sobre os par\u00e2metros poss\u00edveis, consulte o manual on-line do comando date ($ man date) e procure por FORMAT.<\/p>\n<p>Observa\u00e7\u00e3o: BRST significa Brazilian Summer Time. Fora da \u00e9poca de hor\u00e1rio de ver\u00e3o teremos BRT (Brazilian Time).<\/p>\n<h2>C\u00e1lculos elementares<\/h2>\n<p>Agora veremos alguns exemplos de c\u00e1lculos com datas. Ser\u00e1 necess\u00e1rio utilizar a chave -d. Apenas ressalto que o resultado final pode utilizar formata\u00e7\u00e3o, como descrito antes.<\/p>\n<h3>Datas e horas passadas e futuras<\/h3>\n<p>Alguns exemplos:<\/p>\n<pre>$ date\r\nTer Fev 14 16:35:46 BRST 2012\r\n\r\n$ date -d \"+10 days\"\r\nSex Fev 24 16:38:00 BRST 2012\r\n\r\n$ date -d \"-10 days\"\r\nS\u00e1b Fev\u00a0 4 16:38:17 BRST 2012\r\n\r\n$ date -d \"+10 min\"\r\nTer Fev 14 16:49:09 BRST 2012\r\n\r\n$ date -d \"-10 min\"\r\nTer Fev 14 16:29:27 BRST 2012\r\n\r\n$ date -d \"+10 days -2 hours +10 min -50 secs\"\r\nSex Fev 24 14:49:51 BRST 2012<\/pre>\n<p>Agora com formata\u00e7\u00e3o:<\/p>\n<pre>$ date -d \"+10 days -2 hours +10 min -50 secs\" '+%d %b %y, %H:%Mh'\r\n24 Fev 12, 14:50h\r\n\r\n$ date -d \"+2 years +1 month -1 week\" '+%d %b %y, %H:%Mh'\r\n07 Mar 14, 15:47h<\/pre>\n<p>Exemplo em script:<\/p>\n<pre>#!\/bin\/bash\r\nDATA=$(LANG=C date -d \"-1 day\" '+%b %e')\r\ncat \/var\/log\/syslog | grep \"$DATA\" | grep login<\/pre>\n<p>Na verdade, voc\u00ea tem que ser intuitivo para lidar com o date. Olha que exemplo louco:<\/p>\n<pre>$ date -d \"next fri\"\r\nSex Fev 17 00:00:00 BRST 2012<\/pre>\n<p>Ele mostrou a data da pr\u00f3xima sexta-feira (fri de friday). Outra sa\u00edda, caso voc\u00ea n\u00e3o seja intuitivo, \u00e9 ler o c\u00f3digo fonte do comando. O manual on-line n\u00e3o cita as possibilidades. Ent\u00e3o, tais possibilidades s\u00e3o (algumas aceitam plural, como hours): <strong>ago<\/strong>, <strong>day<\/strong>, <strong>fortnight<\/strong>, <strong>hour<\/strong>, <strong>last<\/strong>, <strong>min<\/strong>, <strong>month<\/strong>, <strong>next<\/strong>, <strong>now<\/strong>, <strong>sec<\/strong>, <strong>this<\/strong>, <strong>today<\/strong>, <strong>tomorrow<\/strong>, <strong>week<\/strong>, <strong>year<\/strong> e <strong>yesterday<\/strong>.<\/p>\n<p>Outro exemplo:<\/p>\n<pre>$ date -d \"last fri\"\r\nSex Fev 10 00:00:00 BRST 2012<\/pre>\n<p>Agora preste aten\u00e7\u00e3o: day, fortnight, hour, min, month, sec, week e year s\u00e3o conhecidos como unidades e PODEM ser combinados com ago, last, next, now, this, today, tomorrow e yesterday, que s\u00e3o os modificadores. Exemplo:<\/p>\n<pre>$ date -d \"last-week +1 day\"\r\nQua Fev\u00a0 8 17:55:00 BRST 2012<\/pre>\n<h2>Unix Epoch<\/h2>\n<p>Para quem n\u00e3o sabe, o Unix Epoch \u00e9 uma data de refer\u00eancia do Unix, ou seja, 01 de janeiro de 1970, \u00e0s 00:00h. Os Unix utilizam bastante essa data. Por exemplo: quando voc\u00ea inclui um usu\u00e1rio no sistema com o comando adduser, uma linha \u00e9 gerada no arquivo \/etc\/shadow. O terceiro campo dessa linha \u00e9 a quantidade de dias decorridos desde o Unix Epoch. Ent\u00e3o, \u00e9 poss\u00edvel saber quando o usu\u00e1rio foi cadastrado ou quando a sua conta foi alterada pela \u00faltima vez. Veja:<\/p>\n<pre>eriberto:$6$8wFWksz9$cGv03Q0y9B3bKVvao168QueUhv7ViMkS3SdXGOYOyqDaaUmjIit3m\/0F6\/98jTaglalgfatWGpVL4mp\/x7oag\/:15134:0:99999:7:::<\/pre>\n<p>No caso, 15134 \u00e9 o n\u00famero de dias desde o Epoch.<\/p>\n<p>\u00c9 importante dizer que a unidade do Epoch pode variar de aplica\u00e7\u00e3o para aplica\u00e7\u00e3o. Alguns logs, por exemplo utilizam a quantidade de segundos e n\u00e3o o de dias. \u00c9 o caso do log do Squid. Veja o exemplo de uma linha desse log:<\/p>\n<pre>1294013828.588 \u00a0 \u00a0 \u00a00 84.63.123.123 TCP_MEM_HIT\/200 943 GET http:\/\/www.debianet.com.br NONE\/- text\/css<\/pre>\n<p>No caso, 1294013828 \u00e9 a quantidade de segundos. O 588 representa fra\u00e7\u00e3o de segundos.<\/p>\n<h2>C\u00e1lculos com Epoch<\/h2>\n<p>Para saber o Epoch em segundos da data atual, utilize o comando:<\/p>\n<pre>$ date +%s\r\n1329246450<\/pre>\n<p>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\u00e1lculo inverso, utilize a op\u00e7\u00e3o -d com o caractere &#8220;@&#8221; antes do n\u00famero. Exemplo:<\/p>\n<pre>$ date -d @1329246450\r\nTer Fev 14 17:07:30 BRST 2012<\/pre>\n<p>Para saber o Epoch de uma data qualquer, com a hora, basta especific\u00e1-las. O detalhe \u00e9 que tem que ser em ingl\u00eas. Exemplo:<\/p>\n<pre>$ date +\"%s\" -d \"Feb 14 17:07:30 BRST 2012\"\r\n1329246450<\/pre>\n<p>Tamb\u00e9m \u00e9 poss\u00edvel remover a hora:<\/p>\n<pre>$ date +\"%s\" -d \"Feb 14 2012\"\r\n1329184800<\/pre>\n<p>Assim, fazer c\u00e1lculos com datas e Epoch ficou f\u00e1cil. Basta utilizar os conceitos anteriores. Darei alguns exemplos. Comecemos calculando qual data representa o Epoch 15134 em dias.<\/p>\n<pre>$ date -d \"1970-01-01 +15134 days\"\r\nQui Jun\u00a0 9 00:00:00 BRT 2011<\/pre>\n<p>Agora, veremos o que representa o Epoch 1329246450 em segundos. J\u00e1 vimos uma forma f\u00e1cil de fazer isso. Mas uma outra forma seria:<\/p>\n<pre>$ date -d \"1970-01-01 +1329246450 secs\"\r\nTer Fev 14 20:07:30 BRST 2012<\/pre>\n<p>Note que houve uma diferen\u00e7a de 3 horas entre a resposta anterior e esta, considerando ainda o hor\u00e1rio de ver\u00e3o (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\u00e7\u00e3o -u, o resultado ser\u00e1 igual. Veja:<\/p>\n<pre>$ date -d @1329246450 -u\r\nTer Fev 14 19:07:30 UTC 2012\r\n\r\n$ date -d \"1970-01-01 +1329246450 secs\" -u\r\nTer Fev 14 19:07:30 UTC 2012<\/pre>\n<p>Como no hor\u00e1rio de ver\u00e3o estamos a menos de 2 horas de Greenwitch, o resultado correto brasileiro deveria ser 17:07h. Ent\u00e3o, o c\u00e1lculo com o comando &#8220;date -d @1329246450&#8221; foi mais preciso. Mas, digamos que o outro comando quebra o galho.<\/p>\n<h2>Comando cal<\/h2>\n<p>J\u00e1 que estamos falando de datas, o comando cal tamb\u00e9m pode ser \u00fatil. Ele nos fornece um calend\u00e1rio on-line sempre que precisamos. Exemplos:<\/p>\n<pre>$ cal\r\n\u00a0\u00a0 Fevereiro 2012\r\nDo Se Te Qu Qu Se S\u00e1\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 1\u00a0 2\u00a0 3\u00a0 4\r\n\u00a05\u00a0 6\u00a0 7\u00a0 8\u00a0 9 10 11\r\n12 13 14 15 16 17 18\r\n19 20 21 22 23 24 25\r\n26 27 28 29<\/pre>\n<p>H\u00e1 outras op\u00e7\u00f5es interessantes:<\/p>\n<p>$ cal -3 &#8212;&gt; fornece o calend\u00e1rio do m\u00eas anterior, do atual e do pr\u00f3ximo.<\/p>\n<p>$ cal 2012 &#8212;&gt; mostra o calend\u00e1rio de 2012.<\/p>\n<p>$ cal 9 1971 &#8212;&gt; mostra o calend\u00e1rio de setembro de 1971.<\/p>\n<p>$ cal -j &#8212;&gt; mostra o calend\u00e1rio juliano.<\/p>\n<p>Este post \u00e9 particularmente \u00fatil para administradores de sistemas.<\/p>\n<p>[]s!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>De vez em quando necessitamos fazer c\u00e1lculos com datas para n\u00f3s mesmos ou dentro de scripts. O comando date possui \u00f3timos recursos para nos auxiliar nisso. Este post ir\u00e1 mostrar algumas das possibilidades de c\u00e1lculo utilizando o date. Mas, antes de tudo, falarei um pouco sobre formata\u00e7\u00e3o. Formata\u00e7\u00e3o de datas e hora O comando date&hellip;&nbsp;<a href=\"https:\/\/eriberto.pro.br\/blog\/2012\/02\/14\/calculo-de-datas-com-o-comando-date-no-gnulinux\/\" rel=\"bookmark\">Continue a ler &raquo;<span class=\"screen-reader-text\">C\u00e1lculo de datas com o comando date no GNU\/Linux<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","footnotes":""},"categories":[16,54,3,11],"tags":[430,431,429,624,427,105,626,621,226,283,426,49,428],"class_list":["post-967","post","type-post","status-publish","format-standard","hentry","category-debian","category-forense-computacional","category-linux","category-sistema-operacional","tag-430","tag-bash","tag-date","tag-debian","tag-epoch","tag-forense","tag-forense-computacional","tag-linux","tag-shell-2","tag-shell-script","tag-timestamp","tag-unix","tag-unix-epoch"],"_links":{"self":[{"href":"https:\/\/eriberto.pro.br\/blog\/wp-json\/wp\/v2\/posts\/967","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/eriberto.pro.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/eriberto.pro.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/eriberto.pro.br\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/eriberto.pro.br\/blog\/wp-json\/wp\/v2\/comments?post=967"}],"version-history":[{"count":0,"href":"https:\/\/eriberto.pro.br\/blog\/wp-json\/wp\/v2\/posts\/967\/revisions"}],"wp:attachment":[{"href":"https:\/\/eriberto.pro.br\/blog\/wp-json\/wp\/v2\/media?parent=967"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/eriberto.pro.br\/blog\/wp-json\/wp\/v2\/categories?post=967"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/eriberto.pro.br\/blog\/wp-json\/wp\/v2\/tags?post=967"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}