Obter a data do último dia do mês passado em um script de shell

11

Como obtenho a data de término do mês anterior, com base na data de processamento?

Exemplos:

  • Data de processamento = 15jan2015
  • Data prevista = 31dec2014,

  • Data de processamento = 10feb2015
  • Data prevista = 31jan2015
user128856
fonte

Respostas:

27

Com o GNU date:

$ date +%d%b%Y
16Aug2015
$ date -d "$(date +%Y-%m-01) -1 day" +%d%b%Y
31Jul2015

Alguns shells possuem suporte interno para manipulação de datas:

Com ksh93:

$ printf "%(%d%b%Y)T\n" "1st day, yesterday"
31Jul2015

Com zsh:

$ zmodload zsh/datetime
$ strftime -s d %Y-%m-01-12 $EPOCHSECONDS
$ strftime -rs d %Y-%m-%d-%H $d
$ strftime %d%b%Y $((d-86400))
31Jul2015
Stéphane Chazelas
fonte
4

Existem várias maneiras de fazer isso; Aqui está o mais simples que encontrei (assumindo o GNU date):

$ date -d "-$(date +%d) days"
Fri Jul 31 16:07:23 EDT 2015
user1717828
fonte
1
A resposta da @stephane é mais clara, e essa não funcionará em alguns anos estranhos, onde os dias foram ignorados / adicionados no meio do mês. Sim, isso aconteceu. consulte youtube.com/watch?v=-5wpm-gesOY
ctrl-alt-delor 17/08/2015
@ Richard, a maneira GNU data dia offsets trabalho (a 1 dia deslocamento não é o mesmo que um 24 horas um), eu acho que esta resposta e os meus deve ser equivalente e só falham em fusos horários que pular o último dia de um mês ( normalmente, se o que já aconteceu que provavelmente seria de alguma ilha do Pacífico por um interruptor para -12: 00 compensada para compensar 00:00 (ou -13 a 11 ...) ...
Stéphane Chazelas
@ Stephanie obrigado por apontar outros problemas, o tempo é difícil. Observe na sua solução, caso o meio do mês seja removido (isso aconteceu), o dia 30 não será o 30º dia, portanto, subtrair 30 não o levará ao último dia do mês anterior. Não vejo por que este não funcionará, se houver um 1º dia do mês (não garantido). No entanto, isso não significa que sim.
CTRL-ALT-DELOR
@richard, veja TZ=Pacific/Apia faketime '2011-12-31 12:00' date -d '1 day ago'. Você recebe um erro porque não havia 2011-12-30 lá. Ou seja, o deslocamento do dia foi feito no horário do calendário. 2011-12-31 menos 31 dias fornece 30/11/2011 porque tira 31 de 31. Não leva 31 * 24 * 60 * 60 * 60 segundos do horário atual. Compare com o TZ=Pacific/Apia faketime '2011-12-31 12:00' date -d '24 hour ago'que lhe dá o dia 29, ou seja, desta vez, a data em que ocorreu 24 * 60 * 60 * 60 segundos atrás.
Stéphane Chazelas
2

Aqui está uma versão que funciona no Mac OS, que usa o dateutilitário BSD :

date -v1d -v-1d +%d%b%Y

Os argumentos são aplicados em ordem. Você pode imaginar que uma data é canalizada de um argumento para o outro. Por exemplo:

  • Comece com a data atual (date ) -> 06/03/2017
  • Defina essa data para o primeiro dia do mês ( -v1d) -> 01/03/2017
  • Subtraia um dia disso ( -v-1d)-> 28-02-2017
  • Formate a data ( +%d%b%Y) -> 28Fev2017

Você pode atingir qualquer número de meses para frente ou para trás usando date -v-1m -v1d -v-1d, substituindo -1mpelo número de meses para trás ou para frente ( +1m) desejado.

Essa é a resposta genérica. Esta pergunta pergunta especificamente sobre datas relativas a uma data de início. O utilitário de data do Mac OS / BSD não permite que você forneça um carimbo de data para começar, mas é possível definir cada elemento de data individualmente:

date -v2015y -v1m -v15d -v1d -v-1d +%d%b%Y -> 31 de dezembro de 2014

spiffytech
fonte
0

Tente usar este código

date -d "-$(date +%d) days  month" +%Y-%m-%d
Andar
fonte
Isso dá o último dia deste mês.
Warren Young