2010-08-02 13 views

Odpowiedz

14

Korzystanie date i Shell tylko arytmetyki:

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

Nie trzeba dwukrotnie używać '$ (())'. Po prostu użyj zestawu grupujących nawiasów: 'echo $ ((($ (data -d" 2010-06-01 "" +% s ") - $ (data -d" 2010-05-15 "" +% s "))/86400)) '(dodano opcjonalne spacje dla podkreślenia i czytelności) –

+0

Zwróć uwagę, że'% s' jest specyficzne dla daty GNU, więc może nie być dostępne w systemach innych niż Linux. The [comp.unix.shell FAQ] (http://cfajohnson.com/shell/cus-faq.html # 6) ma długą dyskusję na temat obliczeń daty (w zasadzie jest to trudne, chyba że masz datę GNU). – Gilles

+0

W rzeczywistości jest większy problem: czasami zawiedzie wiosną ... [Moja odpowiedź wyjaśnia dlaczego.] (Http://stackoverflow.com/questions/3385003/shell-script-to-get-difference-in-two-dates/3391111 # 3391111) – Gilles

1

Got to

   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)}' 

Dzięki ..

+3

Jeśli zamierzasz użyć '(())' możesz równie dobrze użyć '$()' zamiast backticks. Ponadto nie ma potrzeby, aby potokować coś w 'awk', po prostu użyj' awk ... 'BEGIN {printf ...}' '. I tak naprawdę nie musisz używać 'awk', jeśli jest to tylko matematyka całkowita:' echo «Liczba dni: $ (((d2 - d1)/(60 * 60 * 24)))' ' –

+0

Dzięki ... .............. – Hulk

10

Jest to rozwiązanie, które prawie utwory: użyć formatu %s Data GNU, która drukuje liczbę sekund od 1970-01-01 00:00. Można je odjąć, aby znaleźć różnicę czasu między dwiema datami.

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

ale następujące wyświetlacze 0 w niektórych lokalizacjach:

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

Ze względu na czas letni, istnieje tylko 23 godzin pomiędzy tamtych czasów. Aby być bezpiecznym, musisz dodać co najmniej godzinę (i co najwyżej 23).

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

Albo można powiedzieć date do pracy w strefie czasowej bez DST.

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

(POSIX mówi zadzwonić strefa czasowa odniesienia jest UTC, ale także mówi nie liczyć przestępnych sekund, więc liczba sekund w ciągu dnia jest zawsze dokładnie 86400 w GMT + xx strefy czasowej).

+0

Twój trzeci przykład rzeczywiście daje '82800', ponieważ zgrupowałeś wyrażenie i faktycznie dodajesz' 0' z powodu wyższego pierwszeństwa '/', czy możesz naprawić literówkę? –

0

data Gnu wie% j, aby wyświetlić dzień w roku:

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

przejście roczniki granice da błędne wyniki, ale skoro dałeś stałe terminy ...

1

OSX date różni się od GNU date. Działa to w OSX. To jest nie przenośne rozwiązanie.

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))) 

Pomysł jest nadal taki sam jak w pozostałych odpowiedziach. Konwertuj daty na czas epoki, odejmuj i przeliczaj wynik na dni.

Powiązane problemy