Ottieni la data dell'ultimo giorno del mese scorso in uno script di shell


11

Come posso ottenere la data di fine del mese precedente, in base alla data di elaborazione?

Esempi:

  • Data di elaborazione = 15jan2015
  • Data prevista = 31dec2014,

  • Data di elaborazione = 10feb2015
  • Data prevista = 31jan2015

Risposte:


27

Con GNU date:

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

Alcune shell hanno il supporto integrato per la manipolazione della data:

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

4

Ci sono molti modi per farlo; ecco il più semplice che ho trovato (assumendo qui GNU date):

$ date -d "-$(date +%d) days"
Fri Jul 31 16:07:23 EDT 2015

1
La risposta di @stephane è più chiara e questa non funzionerà in alcuni anni strani, in cui i giorni sono stati saltati / aggiunti a metà mese. Sì, è successo. vedi youtube.com/watch?v=-5wpm-gesOY
ctrl-alt-delor

@richard, il modo in cui funzionano gli offset del giorno della data GNU (un offset di 1 giorno non è lo stesso di quello di 24 ore), penso che questa e la mia dovrebbero essere equivalenti e fallire solo nei fusi orari che salterebbero l'ultimo giorno di un mese ( in genere, se mai accadesse che sarebbe probabilmente in qualche isola del Pacifico per passare a offset -12: 00 a offset 12:00 (o da -13 a 11 ...) ...
Stéphane Chazelas

@Stephane grazie per aver segnalato altri problemi, il tempo è difficile. Nota nella tua soluzione, nel caso in cui venga rimossa la metà del mese (questo è successo), il giorno 30 non è il 30 ° giorno, quindi sottraendo 30 non ti porterà all'ultimo giorno del mese precedente. Non riesco a capire perché questo non funzionerà, se c'è un 1 ° giorno del mese (non garantito). Tuttavia questo non significa che lo farà.
ctrl-alt-delor

@richard, vedi TZ=Pacific/Apia faketime '2011-12-31 12:00' date -d '1 day ago'. Viene visualizzato un errore perché non è presente il 30-12-2011. Cioè, l' offset del giorno è stato fatto sull'ora del calendario. 2011-12-31 meno 31 giorni ti dà 30/11/2011 perché richiede 31 di 31. Non ci vogliono 31 * 24 * 60 * 60 * 60 secondi di tempo corrente. Confronta con TZ=Pacific/Apia faketime '2011-12-31 12:00' date -d '24 hour ago'quale ti dà il 29, cioè questa volta, la data che era 24 * 60 * 60 * 60 secondi fa.
Stéphane Chazelas,

2

Ecco una versione che funziona su Mac OS, che utilizza l' dateutilità BSD :

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

Gli argomenti vengono applicati in ordine. Puoi immaginare che una data sia convogliata da un argomento al successivo. Per esempio:

  • Inizia con la data corrente ( date) -> 2017-03-06
  • Imposta quella data al 1 ° giorno del suo mese ( -v1d) -> 2017-03-01
  • Sottrai un giorno da quello ( -v-1d)-> 2017-02-28
  • Formatta la data ( +%d%b%Y) -> 28Feb2017

Puoi raggiungere qualsiasi numero di mesi in avanti o indietro utilizzando date -v-1m -v1d -v-1d, sostituendo -1mcon il numero di mesi indietro o avanti ( +1m) che desideri.

Questa è la risposta generica. Questa domanda pone domande specifiche sulle date relative a una data di inizio. L'utilità di data Mac OS / BSD non ti consente di fornire un datastamp da cui iniziare, ma puoi impostare ogni elemento data singolarmente:

date -v2015y -v1m -v15d -v1d -v-1d +%d%b%Y -> 31Dec2014


0

Prova a usare questo codice

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

Questo dà l'ultimo giorno di questo mese.
Warren Young,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.