2010-08-02 2 views
14

Se non ci sono date come 2010-06-01 e un altro come 2010-05-15shell script per ottenere la differenza in due date

Utilizzando script di shell o comando date come ottenere il numero di giorni tra le due date

Thanks ..

+1

'python -c 'dalla data di importazione datetime; print (date (2010, 6, 1) - date (2010, 5, 15)). days'' – jfs

risposta

14

Utilizzando solo data e shell aritmetica:

echo $(($(($(date -d "2010-06-01" "+%s") - $(date -d "2010-05-15" "+%s")))/86400)) 
+1

Non è necessario usare '$ (())' due volte. Basta usare un insieme di parentesi raggruppate: 'echo $ ((($ (date -d" 2010-06-01 "" +% s ") - $ (date -d" 2010-05-15 "" +% s "))/86400)) '(spazi opzionali aggiunti per enfasi e leggibilità) –

+0

Si noti che'% s' è specifico per la data di GNU, quindi potrebbe non essere disponibile su sistemi non Linux. Le [domande frequenti su comp.unix.shell] (http://cfajohnson.com/shell/cus-faq.html # 6) ha una lunga discussione sui calcoli delle date (in pratica, è difficile a meno che non si abbia la data GNU). – Gilles

+0

In effetti c'è un problema più grande: a volte fallisce in primavera ... [La mia risposta spiega perché.] (Http://stackoverflow.com/questions/3385003/shell-script-to-get-difference-in-two-dates/3391111 # 3391111) – Gilles

1

Got it

   d1=`date +%s -d $1` 
      d2=`date +%s -d $2` 
      ((diff_sec=d2-d1)) 
     echo - | awk -v SECS=$diff_sec '{printf "Number of days : %d",SECS/(60*60*24)}' 

grazie ..

+3

Se vuoi usare '(())' potresti anche usare '$()' dei backtick. Inoltre, non è necessario inserire qualcosa in "awk", basta usare "awk ..." BEGIN {printf ...} ''. E non hai davvero bisogno di usare 'awk' se è solo un numero intero di matematica:' echo "Numero di giorni: $ (((d2 - d1)/(60 * 60 * 24)))" ' –

+0

Grazie ... .............. – Hulk

10

c'è una soluzione che quasi opere: utilizzano il formato %s data della data di GNU, che stampa il numero di secondi dal 1970-01-01 00:00. Questi possono essere sottratti per trovare la differenza di tempo tra due date.

echo $((($(date -d 2010-06-01 +%s) - $(date -d 2010-05-15 +%s))/86400)) 

Ma i seguenti display 0 in alcune località:

echo $((($(date -d 2010-03-29 +%s) - $(date -d 2010-03-28 +%s))/86400)) 

causa di ora legale, ci sono solo 23 ore tra quei tempi. È necessario aggiungere almeno un'ora (e al massimo 23) per essere sicuri.

echo $((($(date -d 2010-03-29 +%s) - $(date -d 2010-03-28 +%s) + 43200)/86400)) 

Oppure si può dire date a lavorare in un fuso orario, senza DST.

echo $((($(date -u -d 2010-03-29 +%s) - $(date -u -d 2010-03-28 +%s))/86400)) 

(POSIX dice di chiamare il fuso orario di riferimento è UTC, ma dice anche di non contare secondo salto, in modo che il numero di secondi in un giorno è sempre esattamente 86400 in una GMT + xx fuso orario.)

+0

Il tuo terzo esempio produce effettivamente '82800' perché hai mischiato l'espressione e in effetti stai aggiungendo' 0' a causa della precedenza più alta di '/', puoi correggere l'errore? –

0

data Gnu sa% j per visualizzare il giorno in anno:

echo $(($(date -d 2010-06-01 +%j) - $(date -d 2010-05-15 +%j))) 

attraversamento anni di confini daranno risultati sbagliati, ma dal momento che ti ha dato fissato le date ...

1

OSX date è diverso da GNU date. Ho funzionato così in OSX. Questa è la soluzione non portatile.

start_date=$(date -j -f "%Y-%m-%d" "2010-05-15" "+%s") 
end_date=$(date -j -f "%Y-%m-%d" "2010-06-01" "+%s") 

echo $((($end_date - $start_date)/(60 * 60 * 24))) 

Idea è ancora lo stesso come nelle altre risposte. Convertire le date in epoch time, sottrarre e convertire i risultati in giorni.