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

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

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

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


0

Tente usar este código

date -d "-$(date +%d) days  month" +%Y-%m-%d

Isso dá o último dia deste mês.
— Warren Young
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.