web-dev-qa-db-ja.com

秒単位のタイムスパンをシェルで書式設定された時間に変換する

シェルスクリプトの秒である$ iの変数があり、それを24時間HH:MM:SSに変換しようとしています。これはシェルで可能ですか?

31
Darren

あなたが探しているものを正確に行うための楽しいハック方法があります=)

date -u -d @${i} +"%T"

説明:

  • dateユーティリティを使用すると、1970-01-01 00:00:00 UTC以降の文字列からの時間を秒単位で指定し、指定した形式で出力できます。
  • -uオプションはUTC時刻を表示するため、タイムゾーンオフセットを考慮しません(1970年からの開始時刻はUTCであるため)
  • 以下の部分はGNU date- specific(Linux):です。
    • -d partは、dateを使用する代わりに、stringから時間情報を受け入れるようnowに指示します
    • @${i} partは、date$iは秒単位です
  • +"%T"は、出力をフォーマットするためのものです。から man dateページ:%T time; same as %H:%M:%SHH:MM:SS部分、これは収まります!
74
sampson-chen

別のアプローチ:算術

i=6789
((sec=i%60, i/=60, min=i%60, hrs=i/60))
timestamp=$(printf "%d:%02d:%02d" $hrs $min $sec)
echo $timestamp

1:53:09

16
glenn jackman

-d引数は、coreutils(Linux)からの日付にのみ適用されます。

BSD/OS Xでは、使用

date -u -r $i +%T
12
Alan Tam

これが私のサイトのアルゴ/スクリプトヘルパーです: http://ram.kossboss.com/seconds-to-split-time-convert/ Iここからこのエログアルゴを使用しました: 秒を時間、分、秒に変換します

convertsecs() {
 ((h=${1}/3600))
 ((m=(${1}%3600)/60))
 ((s=${1}%60))
 printf "%02d:%02d:%02d\n" $h $m $s
}
TIME1="36"
TIME2="1036"
TIME3="91925"

echo $(convertsecs $TIME1)
echo $(convertsecs $TIME2)
echo $(convertsecs $TIME3)

秒から日、時間、分、秒のコンバーターの例:

# convert seconds to day-hour:min:sec
convertsecs2dhms() {
 ((d=${1}/(60*60*24)))
 ((h=(${1}%(60*60*24))/(60*60)))
 ((m=(${1}%(60*60))/60))
 ((s=${1}%60))
 printf "%02d-%02d:%02d:%02d\n" $d $h $m $s
 # PRETTY OUTPUT: uncomment below printf and comment out above printf if you want prettier output
 # printf "%02dd %02dh %02dm %02ds\n" $d $h $m $s
}
# setting test variables: testing some constant variables & evaluated variables
TIME1="36"
TIME2="1036"
TIME3="91925"
# one way to output results
((TIME4=$TIME3*2)) # 183850
((TIME5=$TIME3*$TIME1)) # 3309300
((TIME6=100*86400+3*3600+40*60+31)) # 8653231 s = 100 days + 3 hours + 40 min + 31 sec
# outputting results: another way to show results (via echo & command substitution with         backticks)
echo $TIME1 - `convertsecs2dhms $TIME1`
echo $TIME2 - `convertsecs2dhms $TIME2`
echo $TIME3 - `convertsecs2dhms $TIME3`
echo $TIME4 - `convertsecs2dhms $TIME4`
echo $TIME5 - `convertsecs2dhms $TIME5`
echo $TIME6 - `convertsecs2dhms $TIME6`

# OUTPUT WOULD BE LIKE THIS (If none pretty printf used): 
# 36 - 00-00:00:36
# 1036 - 00-00:17:16
# 91925 - 01-01:32:05
# 183850 - 02-03:04:10
# 3309300 - 38-07:15:00
# 8653231 - 100-03:40:31
# OUTPUT WOULD BE LIKE THIS (If pretty printf used): 
# 36 - 00d 00h 00m 36s
# 1036 - 00d 00h 17m 16s
# 91925 - 01d 01h 32m 05s
# 183850 - 02d 03h 04m 10s
# 3309300 - 38d 07h 15m 00s
# 1000000000 - 11574d 01h 46m 40s
1
kossboss

$iは、エポック以降の秒単位の日付を表します。

  date -u -d @$i +%H:%M:%S

しかし、あなたは$iは間隔ではなく(例えば、一定の期間)日付ではなく、私はあなたが何を望んでいるか理解していません。

私は次のようにCシェルを使用します。

#! /bin/csh -f

set begDate_r = `date +%s`
set endDate_r = `date +%s`

set secs = `echo "$endDate_r - $begDate_r" | bc`
set h = `echo $secs/3600 | bc`
set m = `echo "$secs/60 - 60*$h" | bc`
set s = `echo $secs%60 | bc`

echo "Formatted Time: $h HOUR(s) - $m MIN(s) - $s SEC(s)"
0
Shilv

わかりやすくするために、@ Darenの回答を続けます。タイムゾーンへの変換を使用する場合は、「u」スイッチを使用しないでくださいdate -d @$i +%Tまたは場合によってはdate -d @"$i" +%T

0
Shai Alon