2010-08-02 14 views
14

Nếu có các ngày là 2010-06-01 và một ngày khác là 2010-05-15Tập lệnh shell để có sự khác biệt trong hai ngày

Sử dụng lệnh shell hoặc lệnh ngày làm cách nào để có được số ngày giữa hai ngày

Cảm ơn ..

+1

'python -c'from ngày nhập ngày giờ; print (date (2010, 6, 1) - date (2010, 5, 15)). days'' – jfs

Trả lời

14

Chỉ sử dụng ngày và vỏ arithmetics:

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

Không cần sử dụng '$ (())' hai lần. Chỉ cần sử dụng một tập hợp các dấu ngoặc đơn nhóm: 'echo $ ((($ (ngày -d" 2010-06-01 "" +% s ") - $ (ngày -d" 2010-05-15 "" +% s "))/86400)) '(không gian tùy chọn được thêm vào để nhấn mạnh và dễ đọc) –

+0

Lưu ý rằng'% s' là cụ thể cho ngày GNU, vì vậy nó có thể không có sẵn trên các hệ thống không phải Linux. Câu hỏi thường gặp [comp.unix.shell] (http://cfajohnson.com/shell/cus-faq.html # 6) có một cuộc thảo luận dài về tính toán ngày (về cơ bản, thật khó trừ khi bạn có ngày tháng GNU). – Gilles

+0

Trong thực tế, có một vấn đề lớn hơn: đôi khi nó thất bại trong mùa xuân… [Câu trả lời của tôi giải thích lý do.] (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)}' 

nhờ ..

+3

Nếu bạn định sử dụng '(())' bạn cũng có thể sử dụng '$()' để thay thế của backticks. Ngoài ra, không cần phải đưa thứ gì đó vào 'awk', chỉ cần sử dụng' awk ... 'BEGIN {printf ...}' '. Và bạn không thực sự cần phải sử dụng 'awk' nếu nó chỉ là số nguyên math: 'echo" Số ngày: $ (((d2 - d1)/(60 * 60 * 24))) "' –

+0

Cảm ơn ... .............. – Hulk

10

Có một giải pháp mà gần công trình: sử dụng định dạng %s ngày ngày GNU, mà in số giây kể từ 1970/01/01 00:00. Đây có thể được trừ để tìm sự khác biệt thời gian giữa hai ngày.

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

Nhưng các màn hình sau 0 ở một số địa điểm:

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

Bởi vì thời gian tiết kiệm ánh sáng ban ngày, chỉ có 23 tiếng đồng hồ giữa những khoảng thời gian. Bạn cần thêm ít nhất một giờ (và tối đa 23 giờ) để được an toàn.

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

Hoặc bạn có thể yêu cầu date làm việc trong múi giờ không có DST.

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

(POSIX nói để gọi múi giờ tham chiếu là UTC, nhưng nó cũng nói không đếm giây nhuận, vì vậy số giây trong một ngày luôn là chính xác 86400 trong một GMT + xx múi giờ.)

+0

Ví dụ thứ ba của bạn thực sự mang lại '82800' vì bạn đã nhóm sai biểu thức và thực sự thêm '0' do ưu tiên cao hơn của'/', bạn có thể khắc phục lỗi đánh máy không? –

0

ngày Gnu biết% j để hiển thị các ngày trong năm:

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

qua năm ranh giới sẽ cho kết quả sai, nhưng kể từ khi bạn đã cho số ngày cố định ...

1

OSX date khác với GNU date. Đã làm việc như thế này trong OSX. Đây là không phải là giải pháp di động.

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

Ý tưởng vẫn giống như trong các câu trả lời khác. Chuyển đổi ngày thành thời gian epoch, trừ và chuyển đổi kết quả thành ngày.

Các vấn đề liên quan