Obtenga la fecha del último día del mes pasado en un script de shell

11

¿Cómo obtengo la fecha de finalización del mes anterior, según la fecha de procesamiento?

Ejemplos:

  • Fecha de procesamiento = 15jan2015
  • Fecha esperada = 31dec2014,

  • Fecha de procesamiento = 10feb2015
  • Fecha esperada = 31jan2015
usuario128856
fuente

Respuestas:

27

Con GNU date:

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

Algunos shells tienen soporte incorporado para la manipulación de fechas:

Con ksh93:

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

Con 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
fuente
4

Hay muchas maneras de hacer esto; Aquí es el más simple que encontré (aquí suponiendo GNU date):

$ date -d "-$(date +%d) days"
Fri Jul 31 16:07:23 EDT 2015
usuario1717828
fuente
1
La respuesta de @stephane es más clara, y esta no funcionará en algunos años extraños, donde los días se omitieron / agregaron a mediados de mes. Si esto ha sucedido. ver youtube.com/watch?v=-5wpm-gesOY
ctrl-alt-delor
@richard, la forma en que funcionan las compensaciones de día de la fecha GNU (una compensación de 1 día no es lo mismo que una de 24 horas), creo que esta respuesta y la mía deberían ser equivalentes y solo fallarían en las zonas horarias que se saltearían el último día de un mes ( por lo general, si eso ocurriera, probablemente sería en alguna isla del Pacífico cambiar a -12: 00 compensación a 12:00 compensación (o -13 a 11 ...) ...
Stéphane Chazelas
@Stephane, gracias por señalar otros problemas, el tiempo es difícil. Tenga en cuenta en su solución, en el caso de que se elimine la mitad del mes (esto ha sucedido), entonces el día 30 no es el día 30, por lo que restar 30 no lo llevará al último día del mes anterior. No puedo ver por qué este no funcionará, si hay un primer día del mes (no garantizado). Sin embargo, esto no significa que lo hará.
ctrl-alt-delor
@richard, ver TZ=Pacific/Apia faketime '2011-12-31 12:00' date -d '1 day ago'. Recibe un error porque no había 2011-12-30 allí. Es decir, el desplazamiento del día se realizó en la hora del calendario. 31/12/2011 menos 31 días le da 30/11/2011 porque le quita 31 de 31. No le quita 31 * 24 * 60 * 60 * 60 segundos de la hora actual. Compare con lo TZ=Pacific/Apia faketime '2011-12-31 12:00' date -d '24 hour ago'que le da el 29, es decir, esta vez, la fecha en que fue hace 24 * 60 * 60 * 60 segundos.
Stéphane Chazelas
2

Aquí hay una versión que funciona en Mac OS, que utiliza la dateutilidad BSD :

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

Los argumentos se aplican en orden. Puede imaginarse que una fecha se canaliza de un argumento a otro. Por ejemplo:

  • Comience con la fecha actual ( date) -> 2017-03-06
  • Establezca esa fecha en el primer día de su mes ( -v1d) -> 2017-03-01
  • Reste un día de eso ( -v-1d)-> 2017-02-28
  • +%d%b%YDar formato a la fecha ( ) -> 28 de febrero de 2017

Puede alcanzar cualquier cantidad de meses hacia adelante o hacia atrás usando date -v-1m -v1d -v-1d, reemplazando -1mcon la cantidad de meses hacia atrás o hacia adelante ( +1m) que desee.

Esa es la respuesta genérica. Esta pregunta específicamente pregunta sobre fechas relativas a una fecha de inicio. La utilidad de fecha Mac OS / BSD no le permite proporcionar un sello de fecha para comenzar, pero puede configurar cada elemento de fecha individualmente:

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

spiffytech
fuente
0

Intenta usar este código

date -d "-$(date +%d) days  month" +%Y-%m-%d
Caminar
fuente
Eso da el último día de este mes.
Warren Young