Hiển thị giây dưới dạng ngày / giờ / phút / giây?


31

Có thể dễ dàng định dạng giây như một thời gian có thể đọc được của con người trong bash?

Tôi không muốn định dạng nó là một ngày, nhưng là số ngày / giờ / phút, v.v ...


Bạn có thể cung cấp một ví dụ / một vài ví dụ xin vui lòng?
gabe.

1
Bạn đang nói rằng bạn có một khoảng thời gian, hoặc một ngày kể từ thời đại?
Paul Tomblin

Câu trả lời:


41

Bạn có thể sử dụng một cái gì đó như thế này:

function displaytime {
  local T=$1
  local D=$((T/60/60/24))
  local H=$((T/60/60%24))
  local M=$((T/60%60))
  local S=$((T%60))
  (( $D > 0 )) && printf '%d days ' $D
  (( $H > 0 )) && printf '%d hours ' $H
  (( $M > 0 )) && printf '%d minutes ' $M
  (( $D > 0 || $H > 0 || $M > 0 )) && printf 'and '
  printf '%d seconds\n' $S
}

Ví dụ:

$ displaytime 11617
3 hours 13 minutes and 37 seconds
$ displaytime 42
42 seconds
$ displaytime 666
11 minutes and 6 seconds

11

Cách dễ nhất và sạch nhất là lớp lót này (ở đây giả sử GNU date):

Nếu số giây là, nói:

seconds=123456789 # as in one of the answers above

eval "echo $(date -ud "@$seconds" +'$((%s/3600/24)) days %H hours %M minutes %S seconds')"

-> đầu ra: 1428 days 21 hours 33 minutes 09 seconds


Nếu thời lượng của bạn sẽ luôn ít hơn một ngày, bạn có thể sử dụng +%Tđịnh dạng cho Giờ: Phút: Giây date +%T "1970-01-01 + ${seconds} seconds"để có được điều này21:33:09
Yzmir Ramirez

7

Tín dụng được chuyển đến Stéphane Gimenez nhưng nếu ai đó chỉ muốn hiển thị giây nếu thời gian ít hơn một phút thì đây là phiên bản sửa đổi của tôi mà tôi sử dụng (cũng với số nhiều cố định):

converts()
{
    local t=$1

    local d=$((t/60/60/24))
    local h=$((t/60/60%24))
    local m=$((t/60%60))
    local s=$((t%60))

    if [[ $d > 0 ]]; then
            [[ $d = 1 ]] && echo -n "$d day " || echo -n "$d days "
    fi
    if [[ $h > 0 ]]; then
            [[ $h = 1 ]] && echo -n "$h hour " || echo -n "$h hours "
    fi
    if [[ $m > 0 ]]; then
            [[ $m = 1 ]] && echo -n "$m minute " || echo -n "$m minutes "
    fi
    if [[ $d = 0 && $h = 0 && $m = 0 ]]; then
            [[ $s = 1 ]] && echo -n "$s second" || echo -n "$s seconds"
    fi  
    echo
}

Một ví dụ khác trong POSIX:

converts(){
    t=$1

    d=$((t/60/60/24))
    h=$((t/60/60%24))
    m=$((t/60%60))
    s=$((t%60))

    if [ $d -gt 0 ]; then
            [ $d = 1 ] && printf "%d day " $d || printf "%d days " $d
    fi
    if [ $h -gt 0 ]; then
            [ $h = 1 ] && printf "%d hour " $h || printf "%d hours " $h
    fi
    if [ $m -gt 0 ]; then
            [ $m = 1 ] && printf "%d minute " $m || printf "%d minutes " $m
    fi
    if [ $d = 0 ] && [ $h = 0 ] && [ $m = 0 ]; then
            [ $s = 1 ] && printf "%d second" $s || printf "%d seconds" $s
    fi
    printf '\n'
}

Điều này làm việc thực sự tốt. Tôi chỉ cần dán chức năng vào kịch bản của mình và chạy convert $sđể có đầu ra đẹp.
flickerfly

3

Tôi sẽ làm như thế này:

$ seconds=123456789; echo $((seconds/86400))" days "$(date -d "1970-01-01 + $seconds seconds" "+%H hours %M minutes %S seconds")
1428 days 21 hours 33 minutes 09 seconds
$

Đây là một lớp lót ở trên, được chia nhỏ để dễ hiểu hơn:

$ seconds=123456789
$ echo $((seconds/86400))" days"\
     $(date -d "1970-01-01 + $seconds seconds" "+%H hours %M minutes %S seconds")

Ở phần trên tôi đang lặp lại đầu ra của một lệnh khác chạy bên trong lệnh $( ... )phụ. Lệnh phụ đó đang thực hiện việc này, tính toán số ngày (giây / 86400), sau đó sử dụng datelệnh trong một lệnh phụ khác $(date -d ... ), để tạo giờ, phút và giây trong một số giây nhất định.


2

Tôi đã sửa đổi chức năng hiển thị ở trên ... như sau:

seconds2time ()
{
   T=$1
   D=$((T/60/60/24))
   H=$((T/60/60%24))
   M=$((T/60%60))
   S=$((T%60))

   if [[ ${D} != 0 ]]
   then
      printf '%d days %02d:%02d:%02d' $D $H $M $S
   else
      printf '%02d:%02d:%02d' $H $M $S
   fi
}

bởi vì tôi luôn muốn thấy HH: MM: SS, ngay cả khi chúng là số không.


1

Tôi đang xây dựng dựa trên câu trả lời của atti mà tôi thích như một ý tưởng.

Bạn có thể làm điều này với BUILTIN bash printfmà sẽ lấy giây kể từ khi kỷ nguyên như một cuộc tranh cãi. Không cần ngã ba để chạy date.

Bạn phải đặt múi giờ thành UTC printfvì nó định dạng thời gian trong múi giờ địa phương của bạn và bạn sẽ nhận được câu trả lời sai nếu bạn không ở trong thời gian UTC.

$ seconds=123456789
$ TZ=UTC printf "%d days %(%H hours %M minutes %S seconds)T\n" $((seconds/86400)) $seconds
1428 days 21 hours 33 minutes 09 seconds

Trong giờ địa phương của tôi (hiện tại là NZDT - +1300), câu trả lời là sai nếu tôi không đặt múi giờ

$ seconds=123456789
$ printf "%d days %(%H hours %M minutes %S seconds)T\n" $((seconds/86400)) $seconds
1428 days 09 hours 33 minutes 09 seconds

Có và không thiết lập múi giờ

$ seconds=$(( 3600 * 25))
$ printf "%d days %(%H hours %M minutes %S seconds)T\n" $((seconds/86400)) $seconds
1 days 13 hours 00 minutes 00 seconds

$ TZ=UTC printf "%d days %(%H hours %M minutes %S seconds)T\n" $((seconds/86400)) $seconds
1 days 01 hours 00 minutes 00 seconds

Lưu ý rằng bash đã printfgiới thiệu %(datefmt)Tký hiệu này bắt đầu bằng bash-4.2-alpha.
giám mục

-1

Đây một

secs=378444
echo $(($secs/86400))d $(($(($secs - $secs/86400*86400))/3600))h:$(($(($secs - $secs/86400*86400))%3600/60))m:$(($(($secs - $secs/86400*86400))%60))s

Đầu ra:

4d 9h:7m:24s

-2

date --date '@1005454800'mang lại cho bạn Sun Nov 11 00:00:00 EST 2001, tức là 1005454800 giây sau kỷ nguyên Unix. Bạn có thể định dạng với tùy chọn ngày + FORMAT.


7
Đó là một ngày, không phải là một khoảng thời gian, mà câu hỏi đã được hỏi về.
Gilles 'SO- ngừng trở nên xấu xa'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.