Dateutils são um conjunto de ferramentas que giram em torno de mexer com datas e horas na linha de comando, com forte foco em casos de uso que surgem ao lidar com grandes quantidades de dados financeiros.
Dateutils são hospedados principalmente no github:
página do github: https://github.com/hroptatyr/dateutils
página inicial do projeto: http://www.fresse.org/dateutils/
downloads: https://bitbucket.org/hroptatyr/dateutils/downloads
Abaixo está uma pequena lista de exemplos que demonstram o que o dateutils pode fazer. Para especificações completas, consulte as páginas info e man. Para obter instruções de instalação, consulte o arquivo INSTALL.
Os comandos Dateutils são prefixados com uma date
, mas por outro lado se assemelham aos comandos Unix conhecidos por razões de intuição. A única exceção é strptime
, que é análoga à função libc de mesmo nome.
strptime
Versão de linha de comando da função C
dateadd
Adicionar durações a datas ou horas
dateconv
Converter datas ou horas entre calendários
datediff
Calcula durações entre datas ou horas
dategrep
Grep datas ou horas em fluxos de entrada
dateround
Arredonda datas ou horas para valores "mais completos"
dateseq
Gera sequências de datas ou horas
datesort
Classifica cronologicamente.
datetest
Comparar datas ou horas
datezone
Converta datas/horas em fusos horários em massa
Adoro tudo explicado com exemplos para causar uma primeira impressão. Então aí vem.
Uma ferramenta que imita seq(1), mas cujas entradas são do domínio de datas em vez de números inteiros. Normalmente os scripts usam algo como
$ for i in $(seq 0 9); do date -d "2010-01-01 +${i} days" "+%F" done
que agora pode ser abreviado para
$ dateseq 2010-01-01 2010-01-10
com o benefício adicional de que a data final pode ser fornecida diretamente em vez de ser calculada a partir da data de início e um intervalo em dias. Além disso, ele fornece recursos específicos de data que seriam uma PITA para implementar usando a abordagem seq(1)/date(1) acima, como pular determinados dias da semana:
$ dateseq 2010-01-01 2010-01-10 --skip sat,sun => 2010-01-01 2010-01-04 2010-01-05 2010-01-06 2010-01-07 2010-01-08
dateseq também funciona nos horários:
$ dateseq 12:00:00 5m 12:17:00 => 12:00:00 12:05:00 12:10:00 12:15:00
e também data e hora:
$ dateseq --compute-from-last 2012-01-02T12:00:00 5m 2012-01-02T12:17:00 => 2012-01-02T12:02:00 2012-01-02T12:07:00 2012-01-02T12:12:00 2012-01-02T12:17:00
Uma ferramenta para converter datas entre diferentes sistemas de calendário e/ou fusos horários. Enquanto outras ferramentas geralmente se concentram na conversão de datas gregorianas para, digamos, o calendário chinês, o dconv visa apoiar sistemas de calendário que são essenciais em contextos financeiros.
Para converter uma data (gregoriana) na chamada representação ymcw:
$ dateconv 2012-03-04 -f "%Y-%m-%c-%w" => 2012-03-01-00
e vice-versa:
$ dateconv 2012-03-01-Sun -i "%Y-%m-%c-%a" -f '%F' => 2012-03-04
onde a representação ymcw significa o %c
-ésimo %w
do mês em um determinado ano. Isto é útil se as datas forem especificadas como, por exemplo, a terceira quinta-feira de maio.
dateconv também pode ser usado para converter ocorrências de datas, horas ou data-hora em um fluxo de entrada dinamicamente
$ dateconv -S -i '%b/%d %Y at %I:%M %P' <<EOF Remember we meet on Mar/03 2012 at 02:30 pm EOF => Remember we meet on 2012-03-03T14:30:00
e mais proeminentemente para converter entre fusos horários:
$ dateconv --from-zone "America/Chicago" --zone "Asia/Tokyo" 2012-01-04T09:33:00 => 2012-01-05T00:33:00 $ dateconv --zone "America/Chicago" now -f "%d %b %Y %T" => 05 Apr 2012 11:11:57
Uma ferramenta para realizar comparação de datas no shell, é modelada após test(1)
mas com opções de linha de comando adequadas.
$ if datetest today --gt 2010-01-01; then echo "yes" fi => yes
Uma ferramenta para realizar aritmética de datas (matemática de datas) no shell. Dada uma data e uma lista de durações, isso calculará novas datas. Dada uma duração e uma lista de datas, isso calculará novas datas.
$ dateadd 2010-02-02 +4d => 2010-02-06 $ dateadd 2010-02-02 +1w => 2010-02-09 $ dateadd -1d <<EOF 2001-01-05 2001-01-01 EOF => 2001-01-04 2000-12-31
Adicionando durações aos tempos:
$ dateadd 12:05:00 +10m => 12:15:00
e até mesmo datas:
$ dateadd 2012-03-12T12:05:00 -1d4h => 2012-03-11T08:05:00
Se suportado pelo banco de dados zoneinfo do sistema, cálculos ajustados em segundos bissextos são possíveis. Use a unidade rs
para denotar segundos "reais":
$ dateadd '2012-06-30 23:59:30' +30rs => 2012-06-30T23:59:60
em oposição a:
$ dateadd '2012-06-30 23:59:30' +30s => 2012-07-01T00:00:00
Uma ferramenta para calcular a diferença entre duas (ou mais) datas. Isso é um pouco o contrário do papai. Os resultados serão durações que, quando adicionadas à primeira data, resultarão na segunda data.
Obtenha o número de dias entre duas datas:
$ datediff 2001-02-08 2001-03-02 => 22
O formato da duração pode ser controlado através da opção -f
:
$ datediff 2001-02-08 2001-03-09 -f "%m month and %d day" => 1 month and 1 day
datediff também aceita carimbos de data/hora como entrada:
$ datediff 2012-03-01T12:17:00 2012-03-02T14:00:00 => 92580s
A opção -f
faz a coisa certa:
$ datediff 2012-03-01T12:17:00 2012-03-02T14:00:00 -f '%dd %Ss' => 1d 6180s
comparar com:
$ datediff 2012-03-01T12:17:00 2012-03-02T14:00:00 -f '%dd %Hh %Ss' => 1d 1h 2580s
Se suportado pelo banco de dados zoneinfo do sistema, cálculos ajustados em segundos bissextos podem ser feitos. Use o especificador de formato %rS
para obter o tempo decorrido em segundos "reais":
datediff '2012-06-30 23:59:30' '2012-07-01 00:00:30' -f '%rS' => 61
Uma ferramenta para extrair linhas de um fluxo de entrada que corresponda a determinados critérios, mostrando a linha ou a correspondência:
$ dategrep '<2012-03-01' <<EOF Feb 2012-02-28 Feb 2012-02-29 leap day Mar 2012-03-01 Mar 2012-03-02 EOF => Feb 2012-02-28 Feb 2012-02-29 leap day
Uma ferramenta para "arredondar" datas ou carimbos de hora para um ponto recorrente no tempo, como janeiro seguinte/anterior ou quinta-feira seguinte/anterior.
Arredondar (para trás) para o primeiro dia do mês atual:
$ dateround '2011-08-22' -1 => 2011-08-01
Encontre a próxima segunda-feira a partir da data atual (hoje é 08/01/2016):
$ dateround today Mon => 2015-01-11
Volte para setembro passado e arredonde para o final do mês:
$ dateround today -- -Sep +31d => 2015-09-30
Arredonde um fluxo de datas estritamente para o primeiro do mês seguinte:
$ dateround -S -n 1 <<EOF pay cable 2012-02-28 pay gas 2012-02-29 pay rent 2012-03-01 redeem loan 2012-03-02 EOF => pay cable 2012-03-01 pay gas 2012-03-01 pay rent 2012-04-01 redeem loan 2012-04-01
Arredonde uma série temporal para o próximo minuto (ou seja, a parte dos segundos é 00) e depois para o próximo tempo e meia (e converta para ISO):
$ dateround -S 0s30m -i '%d/%m/%Y %T' -f '%F %T' <<EOF 06/03/2012 14:27:12 eventA 06/03/2012 14:29:59 eventA 06/03/2012 14:30:00 eventB 06/03/2012 14:30:01 eventB EOF => 2012-03-06 14:30:00 eventA 2012-03-06 14:30:00 eventA 2012-03-06 14:30:00 eventB 2012-03-06 15:30:00 eventB
Alternativamente, se você dividir o dia em meias horas, poderá arredondar para uma delas usando a notação co-classe:
$ dateround -S /30m -i '%d/%m/%Y %T' -f '%F %T' <<EOF 06/03/2012 14:27:12 eventA 06/03/2012 14:29:59 eventA 06/03/2012 14:30:00 eventB 06/03/2012 14:30:01 eventB EOF => 2012-03-06 14:30:00 eventA 2012-03-06 14:30:00 eventA 2012-03-06 14:30:00 eventB 2012-03-06 15:00:00 eventB
Isto é praticamente idêntico ao exemplo anterior, exceto que uma hora inteira (sendo um múltiplo par de meia hora) é uma meta de arredondamento possível.
Uma ferramenta para colocar as linhas de um arquivo em ordem cronológica.
No momento a ferramenta datesort
depende do sort(1)
com suporte para campos, em particular -t
para selecionar um separador e -k
para classificar por um campo específico.
$ datesort <<EOF 2009-06-03 caev="DVCA" secu="VOD" exch="XLON" xdte="2009-06-03" nett/GBX="5.2" 2011-11-16 caev="DVCA" secu="VOD" exch="XLON" xdte="2011-11-16" nett/GBX="3.05" 2013-11-20 caev="DVCA" secu="VOD" exch="XLON" xdte="2013-11-20" nett/GBX="3.53" 2012-06-06 caev="DVCA" secu="VOD" exch="XLON" xdte="2012-06-06" nett/GBX="6.47" 2013-06-12 caev="DVCA" secu="VOD" exch="XLON" xdte="2013-06-12" nett/GBX="6.92" 2010-11-17 caev="DVCA" secu="VOD" exch="XLON" xdte="2010-11-17" nett/GBX="2.85" EOF => 2009-06-03 caev="DVCA" secu="VOD" exch="XLON" xdte="2009-06-03" nett/GBX="5.2" 2010-11-17 caev="DVCA" secu="VOD" exch="XLON" xdte="2010-11-17" nett/GBX="2.85" 2011-11-16 caev="DVCA" secu="VOD" exch="XLON" xdte="2011-11-16" nett/GBX="3.05" 2012-06-06 caev="DVCA" secu="VOD" exch="XLON" xdte="2012-06-06" nett/GBX="6.47" 2013-06-12 caev="DVCA" secu="VOD" exch="XLON" xdte="2013-06-12" nett/GBX="6.92" 2013-11-20 caev="DVCA" secu="VOD" exch="XLON" xdte="2013-11-20" nett/GBX="3.53"
Uma ferramenta para inspecionar rapidamente valores de data/hora em diferentes fusos horários. O resultado será uma matriz que mostra todos os valores de data e hora em cada fuso horário:
$ datezone Europe/Berlin Australia/Sydney now 2014-06-30T05:00:00 => 2014-01-30T17:37:13+01:00 Europe/Berlin 2014-01-31T03:37:13+11:00 Australia/Sydney 2014-06-30T07:00:00+02:00 Europe/Berlin 2014-06-30T15:00:00+10:00 Australia/Sydney
A ferramenta datezone
também pode ser usada para obter a próxima ou anterior transição de horário de verão relativa a uma determinada data/hora:
$ datezone --next Europe/Berlin Australia/Sydney 2013-02-19 => 2013-03-31T02:00:00+01:00 -> 2013-03-31T03:00:00+02:00 Europe/Berlin 2013-04-07T03:00:00+11:00 -> 2013-04-07T02:00:00+10:00 Australia/Sydney
onde o carimbo de data/hora esquerdo indica o deslocamento da zona atual e o lado direito é o deslocamento da zona após a transição. A data/hora indica o momento exato em que a transição está prestes a ocorrer.
Em essência, datezone
é um zdump(8)
melhor.
Uma ferramenta que traz a flexibilidade do strptime(3)
para a linha de comando. Embora (pelo menos GNU) date(1)
tenha suporte para formatos de saída, ele não possui qualquer tipo de suporte para ler entradas arbitrárias do domínio de datas, em particular quando o formato de entrada é especificamente conhecido de antemão e apenas datas/horas correspondentes devem ser considerado.
Com a ferramenta strptime
lendo datas estranhas como Mon, May-01/2000
torna-se uma questão de
strptime -i "%a, %b-%d/%Y" "Mon, May-01/2000" => 2000-05-01
assim como você teria feito em C.
Observe que strptime
na verdade usa a rotina strptime da libc do sistema e, para saída, a rotina strftime do sistema. Os modificadores de entrada e saída irão, portanto, variar entre os sistemas.
Para uma combinação de analisador/impressora portátil, use dateconv
conforme descrito acima. Seus especificadores de formato de entrada e saída são independentes do tempo de execução C.
Sem nenhuma ordem específica e sem qualquer pretensão de integridade:
dateexpr: http://www.eskimo.com/~scs/src/#dateexpr
dateutils de allanfalloon: https://github.com/alanfalloon/dateutils
sim http://yest.sourceforge.net/
pdd https://github.com/jarun/pdd
Use aquele que melhor se adapta ao seu propósito. E caso você goste do meu, vote: página openhub do dateutils