दिन / घंटे / मिनट / सेकंड के रूप में सेकंड प्रदर्शित करना?


31

क्या बैश में मानव-पठनीय समय के रूप में सेकंड आसानी से प्रारूपित करना संभव है?

मैं इसे दिनांक के रूप में प्रारूपित नहीं करना चाहता, लेकिन दिनों / घंटों / मिनटों की संख्या के रूप में ...


क्या आप एक उदाहरण / कई उदाहरण प्रदान कर सकते हैं?
गाबे

1
क्या आप कह रहे हैं कि आपके पास अंतराल, या एक तिथि है?
पॉल टॉम्बलिन

जवाबों:


41

आप इस तरह से कुछ का उपयोग कर सकते हैं:

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
}

उदाहरण:

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

11

सबसे आसान और साफ तरीका यह एक लाइनर है (यहाँ GNU मानकर date):

यदि सेकंड की संख्या है, तो कहें:

seconds=123456789 # as in one of the answers above

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

-> आउटपुट: 1428 days 21 hours 33 minutes 09 seconds


अपने अवधि हमेशा एक दिन से भी कम हो जाएगा, तो आप उपयोग कर सकते हैं +%Tइस के लिए सेकंड: मिनट: घंटे के लिए प्रारूप date +%T "1970-01-01 + ${seconds} seconds"प्राप्त करने के लिए21:33:09
Yzmir रामिरेज़

7

क्रेडिट स्टीफन जिमेनेज़ को जाता है लेकिन अगर कोई व्यक्ति केवल कुछ सेकंड ही प्रदर्शित करना चाहेगा, जब एक अवधि एक मिनट से भी कम हो तो मेरा संशोधित संस्करण है जिसका मैं उपयोग करता हूं (साथ ही निश्चित बहुवचन भी):

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
}

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

यह वास्तव में अच्छी तरह से काम किया। मैंने बस अपनी स्क्रिप्ट में फ़ंक्शन को चिपकाया और convert $sसुंदर आउटपुट प्राप्त करने के लिए दौड़ा ।
झिलमिलाहट

3

मैं इसे इस तरह से करूँगा:

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

यहां एक लाइनर ऊपर है, टूट गया ताकि इसे समझना आसान हो:

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

ऊपर में मैं एक और कमांड के आउटपुट को गूंज रहा हूं जो $( ... )उप-कमांड के अंदर चलता है । वह उप-कमांड ऐसा कर रहा है, किसी दिए गए संख्या के लिए घंटे, मिनट और सेकंड उत्पन्न करने के लिए दिन (सेकंड / 86400) की संख्या की गणना करता है, फिर dateदूसरे उप-कमांड में कमांड का उपयोग करता है $(date -d ... )


2

मैंने ऊपर डिस्प्लेटाइम फ़ंक्शन को संशोधित किया ... इस प्रकार है:

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
}

क्योंकि मैं हमेशा HH: MM: SS देखना चाहता हूं, भले ही वे शून्य हों।


1

मैं अटारी के उत्तर पर निर्माण कर रहा हूं जो मुझे एक विचार के रूप में पसंद आया।

आप इसे बैश बिलिन के साथ कर सकते हैं printfजो एक तर्क के रूप में युग के बाद सेकंड ले जाएगा। दौड़ने के लिए कांटे की जरूरत नहीं date

आपको यूटीसी के लिए समय-क्षेत्र निर्धारित करना होगा printfक्योंकि यह आपके स्थानीय समय-क्षेत्र में समय को निर्धारित करता है और यदि आप यूटीसी समय में नहीं हैं तो आपको गलत उत्तर मिल जाएगा।

$ 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

मेरे स्थानीय समय में (जो वर्तमान में NZDT - +1300 है) उत्तर देने में गलत है यदि मैं समय-सीमा निर्धारित नहीं करता हूं

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

के साथ और timezone सेट किए बिना

$ 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

ध्यान दें कि बैश printfने इस %(datefmt)Tनोटेशन की शुरुआत बैश-4.2-अल्फा से की है।
बिशप

-1

यहाँ एक

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

आउटपुट:

4d 9h:7m:24s

-2

date --date '@1005454800'आपको देता है Sun Nov 11 00:00:00 EST 2001, जो यूनिक्स युग के बाद 1005454800 सेकंड है। आप दिनांक + FORMAT विकल्प के साथ प्रारूपित कर सकते हैं।


7
यह एक तारीख है, अवधि नहीं, जिसके बारे में सवाल पूछ रहा था।
गिलेस एसओ- बुराई को रोकना '
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.