를 사용하여 시작 및 종료 시간을 인쇄하면 date +"%T"
다음과 같은 결과가 나타납니다.
10:33:56
10:36:10
이 두 가지의 차이점을 어떻게 계산하고 인쇄 할 수 있습니까?
나는 다음과 같은 것을 얻고 싶다 :
2m 14s
답변
Bash에는 SECONDS
셸이 시작된 후 경과 한 시간 (초)을 추적 하는 편리한 내장 변수가 있습니다. 이 변수는 할당 될 때 속성을 유지하며 할당 후 반환 된 값은 할당 이후의 시간 (초)에 할당 된 값을 더한 값입니다.
따라서 SECONDS
시간이 지정된 이벤트를 시작하기 전에 0으로 설정 하고 이벤트를 읽은 SECONDS
후 표시하기 전에 시간을 산술 할 수 있습니다.
SECONDS=0
# do some work
duration=$SECONDS
echo "$(($duration / 60)) minutes and $(($duration % 60)) seconds elapsed."
이 솔루션은 date +%s
GNU 확장 에 의존하지 않기 때문에 Bash가 지원하는 모든 시스템에 이식 가능합니다.
답변
초
경과 시간 (초)을 측정하려면 다음이 필요합니다.
- 경과 된 초 수를 나타내는 정수
- 이러한 정수를 사용 가능한 형식으로 변환하는 방법.
경과 된 초의 정수 값 :
-
경과 된 초 수의 정수 값을 찾는 두 가지 bash 내부 방법이 있습니다.
-
배쉬 변수 SECONDS (SECONDS가 설정되어 있지 않으면 특수 속성이 손실 됨)
-
SECONDS 값을 0으로 설정 :
SECONDS=0 sleep 1 # Process to execute elapsedseconds=$SECONDS
-
SECONDS
시작시 변수 값 저장 :a=$SECONDS sleep 1 # Process to execute elapsedseconds=$(( SECONDS - a ))
-
-
Bash printf 옵션
%(datefmt)T
:a="$(TZ=UTC0 printf '%(%s)T\n' '-1')" ### `-1` is the current time sleep 1 ### Process to execute elapsedseconds=$(( $(TZ=UTC0 printf '%(%s)T\n' '-1') - a ))
-
이러한 정수를 사용 가능한 형식으로 변환
bash internal printf
은 직접 수행 할 수 있습니다.
$ TZ=UTC0 printf '%(%H:%M:%S)T\n' 12345
03:25:45
비슷하게
$ elapsedseconds=$((12*60+34))
$ TZ=UTC0 printf '%(%H:%M:%S)T\n' "$elapsedseconds"
00:12:34
그러나 실제로는 실제 시간이 아닌 벽시계 시간을 인쇄하므로 24 시간 이상 지속되지 않습니다.
$ hours=30;mins=12;secs=24
$ elapsedseconds=$(( ((($hours*60)+$mins)*60)+$secs ))
$ TZ=UTC0 printf '%(%H:%M:%S)T\n' "$elapsedseconds"
06:12:24
bash-hackers.org 에서 세부 사항을 좋아하는 사람들을 위해 :
%(FORMAT)T
FORMAT을 형식 문자열로 사용하여 생성 된 날짜-시간 문자열을 출력합니다strftime(3)
. 연관된 인수는 Epoch 이후의 시간 (초 ) 또는 -1 (현재 시간) 또는 -2 (쉘 시작 시간)입니다. 해당 인수가 제공되지 않으면 현재 시간이 기본값으로 사용됩니다.
따라서 또 다른 지속 시간 인쇄 구현이 textifyDuration $elpasedseconds
있는 곳을 호출하고 싶을 수도 있습니다 textifyDuration
.
textifyDuration() {
local duration=$1
local shiff=$duration
local secs=$((shiff % 60)); shiff=$((shiff / 60));
local mins=$((shiff % 60)); shiff=$((shiff / 60));
local hours=$shiff
local splur; if [ $secs -eq 1 ]; then splur=''; else splur='s'; fi
local mplur; if [ $mins -eq 1 ]; then mplur=''; else mplur='s'; fi
local hplur; if [ $hours -eq 1 ]; then hplur=''; else hplur='s'; fi
if [[ $hours -gt 0 ]]; then
txt="$hours hour$hplur, $mins minute$mplur, $secs second$splur"
elif [[ $mins -gt 0 ]]; then
txt="$mins minute$mplur, $secs second$splur"
else
txt="$secs second$splur"
fi
echo "$txt (from $duration seconds)"
}
GNU 날짜.
형식화 된 시간을 얻으려면 몇 가지 방법으로 외부 도구 (GNU 날짜)를 사용하여 거의 1 년 길이까지 나노초를 포함해야합니다.
날짜 안에 수학.
외부 산술이 필요하지 않습니다. 한 번에 한 단계 만 수행하십시오 date
.
date -u -d "0 $FinalDate seconds - $StartDate seconds" +"%H:%M:%S"
예, 0
명령 문자열에 0이 있습니다. 필요합니다.
즉, date +"%T"
명령을 명령으로 변경 date +"%s"
하여 값을 초 단위로 저장 (인쇄) 할 수 있다고 가정합니다 .
명령은 다음으로 제한됩니다.
$StartDate
및$FinalDate
초의 양수 값- 의 값
$FinalDate
이 (보다 늦음)보다 큽니다$StartDate
. - 24 시간보다 작은 시차.
- 시간, 분 및 초가있는 출력 형식을 승인합니다. 변경하기 매우 쉽습니다.
- -u UTC 시간을 사용할 수 있습니다. “DST”및 현지 시간 수정을 피합니다.
문자열 을 사용해야 하는 경우 10:33:56
초로 변환하면 초라
는 단어가 sec로 축약 될 수 있습니다.
string1="10:33:56"
string2="10:36:10"
StartDate=$(date -u -d "$string1" +"%s")
FinalDate=$(date -u -d "$string2" +"%s")
date -u -d "0 $FinalDate sec - $StartDate sec" +"%H:%M:%S"
위에서 설명한 초 시간 변환은 “오늘”오늘의 시작 (오늘)과 관련이 있습니다.
이 개념은 다음과 같이 나노초로 확장 될 수 있습니다.
string1="10:33:56.5400022"
string2="10:36:10.8800056"
StartDate=$(date -u -d "$string1" +"%s.%N")
FinalDate=$(date -u -d "$string2" +"%s.%N")
date -u -d "0 $FinalDate sec - $StartDate sec" +"%H:%M:%S.%N"
더 긴 (최대 364 일) 시간 차이를 계산해야하는 경우 (일부) 연도를 참조로 사용하고 형식 값 %j
( 연도의 일수)을 사용해야합니다 .
비슷하다:
string1="+10 days 10:33:56.5400022"
string2="+35 days 10:36:10.8800056"
StartDate=$(date -u -d "2000/1/1 $string1" +"%s.%N")
FinalDate=$(date -u -d "2000/1/1 $string2" +"%s.%N")
date -u -d "2000/1/1 $FinalDate sec - $StartDate sec" +"%j days %H:%M:%S.%N"
Output:
026 days 00:02:14.340003400
안타깝게도이 경우 1
일 수에서 ONE 을 수동으로 빼야 합니다. 날짜 명령은 연중 첫날을 1로 간주합니다. 그렇게 어렵지 않습니다 …
a=( $(date -u -d "2000/1/1 $FinalDate sec - $StartDate sec" +"%j days %H:%M:%S.%N") )
a[0]=$((10#${a[0]}-1)); echo "${a[@]}"
https://www.gnu.org/software/coreutils/manual/html_node/Examples-of-date.html#Examples-of-date
는 긴 초 단위의 사용이 유효하고 문서화되어 있습니다.
비지 박스 날짜
더 작은 장치 (설치할 아주 작은 실행 파일)에 사용되는 도구 : Busybox.
다음과 같이 busybox에 링크를 작성하십시오.
$ ln -s /bin/busybox date
그런 다음 이것을 호출하여 사용하십시오 date
(PATH 포함 디렉토리에 배치).
또는 다음과 같은 별칭을 만드십시오.
$ alias date='busybox date'
Busybox 날짜에는 좋은 옵션이 있습니다. -D는 입력 시간 형식을 수신합니다. 그것은 시간으로 사용될 많은 형식을 엽니 다. -D 옵션을 사용하면 시간 10:33:56을 직접 변환 할 수 있습니다.
date -D "%H:%M:%S" -d "10:33:56" +"%Y.%m.%d-%H:%M:%S"
위 명령의 결과에서 볼 수 있듯이 그 날은 “오늘”인 것으로 가정합니다. 에포크에서 시작하는 시간을 얻으려면 :
$ string1="10:33:56"
$ date -u -D "%Y.%m.%d-%H:%M:%S" -d "1970.01.01-$string1" +"%Y.%m.%d-%H:%M:%S"
1970.01.01-10:33:56
Busybox 날짜는 -D 없이도 시간을 수신 할 수 있습니다 (위 형식).
$ date -u -d "1970.01.01-$string1" +"%Y.%m.%d-%H:%M:%S"
1970.01.01-10:33:56
그리고 출력 형식은 에포크 이후 몇 초가 될 수도 있습니다.
$ date -u -d "1970.01.01-$string1" +"%s"
52436
두 경우 모두 약간의 bash 수학 (busybox는 아직 수학을 수행 할 수 없음) :
string1="10:33:56"
string2="10:36:10"
t1=$(date -u -d "1970.01.01-$string1" +"%s")
t2=$(date -u -d "1970.01.01-$string2" +"%s")
echo $(( t2 - t1 ))
또는 형식 :
$ date -u -D "%s" -d "$(( t2 - t1 ))" +"%H:%M:%S"
00:02:14
답변
내가 한 방법은 다음과 같습니다.
START=$(date +%s);
sleep 1; # Your stuff
END=$(date +%s);
echo $((END-START)) | awk '{print int($1/60)":"int($1%60)}'
정말 간단합니다. 시작 시간 (초)을 마친 다음 끝 시간 (초)을 가져 와서 분 : 초 단위로 차이를 인쇄합니다.
답변
다른 옵션은 ( http://www.fresse.org/dateutils/#datediff ) datediff
에서 사용하는 것 입니다 .dateutils
$ datediff 10:33:56 10:36:10
134s
$ datediff 10:33:56 10:36:10 -f%H:%M:%S
0:2:14
$ datediff 10:33:56 10:36:10 -f%0H:%0M:%0S
00:02:14
당신은 또한 사용할 수 있습니다 gawk
. mawk
1.3.4 또한이 strftime
과 mktime
의 있지만 이전 버전 mawk
과는 nawk
하지 않습니다.
$ TZ=UTC0 awk 'BEGIN{print strftime("%T",mktime("1970 1 1 10 36 10")-mktime("1970 1 1 10 33 56"))}'
00:02:14
또는 GNU로 다른 방법을 사용할 수 있습니다 date
.
$ date -ud@$(($(date -ud'1970-01-01 10:36:10' +%s)-$(date -ud'1970-01-01 10:33:56' +%s))) +%T
00:02:14
답변
나는 date
명령을 회상하지 않는 다른 방법을 제안하고 싶습니다 . 이미 %T
날짜 형식으로 타임 스탬프를 수집 한 경우 도움이 될 수 있습니다 .
ts_get_sec()
{
read -r h m s <<< $(echo $1 | tr ':' ' ' )
echo $(((h*60*60)+(m*60)+s))
}
start_ts=10:33:56
stop_ts=10:36:10
START=$(ts_get_sec $start_ts)
STOP=$(ts_get_sec $stop_ts)
DIFF=$((STOP-START))
echo "$((DIFF/60))m $((DIFF%60))s"
같은 방법으로 밀리 초를 처리 할 수도 있습니다.
ts_get_msec()
{
read -r h m s ms <<< $(echo $1 | tr '.:' ' ' )
echo $(((h*60*60*1000)+(m*60*1000)+(s*1000)+ms))
}
start_ts=10:33:56.104
stop_ts=10:36:10.102
START=$(ts_get_msec $start_ts)
STOP=$(ts_get_msec $stop_ts)
DIFF=$((STOP-START))
min=$((DIFF/(60*1000)))
sec=$(((DIFF%(60*1000))/1000))
ms=$(((DIFF%(60*1000))%1000))
echo "${min}:${sec}.$ms"
답변
여기 마술이 있습니다 :
time1=14:30
time2=$( date +%H:%M ) # 16:00
diff=$( echo "$time2 - $time1" | sed 's%:%+(1/60)*%g' | bc -l )
echo $diff hours
# outputs 1.5 hours
sed
a :
를 1/60으로 변환 할 수식으로 바꿉니다 . 그런 다음에 의해 만들어진 시간 계산bc
답변
현재 날짜 (GNU coreutils) 7.4 -d를 사용하여 산술을 수행 할 수 있습니다.
$ date -d -30days
Sat Jun 28 13:36:35 UTC 2014
$ date -d tomorrow
Tue Jul 29 13:40:55 UTC 2014
사용할 수있는 단위는 일, 년, 월, 시간, 분 및 초입니다.
$ date -d tomorrow+2days-10minutes
Thu Jul 31 13:33:02 UTC 2014