Saniye
Geçen süreyi (saniye cinsinden) ölçmek için ihtiyacımız olan:
- geçen saniye sayısını temsil eden bir tam sayı ve
- bu tamsayıyı kullanılabilir bir biçime dönüştürmenin bir yolu.
Geçen saniyelerin tamsayı değeri:
Böyle bir tamsayıyı kullanılabilir bir biçime dönüştürün
Bash dahili printf
bunu doğrudan yapabilir:
$ TZ=UTC0 printf '%(%H:%M:%S)T\n' 12345
03:25:45
benzer şekilde
$ elapsedseconds=$((12*60+34))
$ TZ=UTC0 printf '%(%H:%M:%S)T\n' "$elapsedseconds"
00:12:34
ancak bu gerçekten bir süre değil, bir duvar saati süresi yazdırdığımız için 24 saatten uzun süreler boyunca başarısız olacaktır:
$ hours=30;mins=12;secs=24
$ elapsedseconds=$(( ((($hours*60)+$mins)*60)+$secs ))
$ TZ=UTC0 printf '%(%H:%M:%S)T\n' "$elapsedseconds"
06:12:24
Ayrıntı sevenler için bash-hackers.org'dan :
%(FORMAT)T
FORMAT'ın biçim dizesi olarak kullanılmasından kaynaklanan tarih-saat dizesini çıktılar strftime(3)
. İlişkili bağımsız değişken, Epoch'tan bu yana geçen saniye sayısı veya -1 (geçerli saat) veya -2 (kabuk başlangıç saati). Karşılık gelen bağımsız değişken sağlanmazsa, geçerli saat varsayılan olarak kullanılır.
Bu nedenle , süre baskısının başka bir uygulaması olan textifyDuration $elpasedseconds
yeri aramak isteyebilirsiniz 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 tarihi.
Belirlenmiş zamanı elde etmek için, neredeyse bir yıl uzunluğa ulaşmak ve Nanosaniye dahil olmak üzere çeşitli şekillerde harici bir araç (GNU tarihi) kullanmalıyız.
Tarih içinde.
Dış aritmetiğe gerek yoktur, hepsini bir adımda yapın date
:
date -u -d "0 $FinalDate seconds - $StartDate seconds" +"%H:%M:%S"
Evet, 0
komut dizesinde sıfır var . Gerekli.
Bu, date +"%T"
komutun bir date +"%s"
komutla değiştirilebileceği varsayılır, böylece değerler saniyeler içinde saklanır (yazdırılır).
Komutun aşağıdakilerle sınırlı olduğunu unutmayın:
- Pozitif değerler
$StartDate
ve $FinalDate
saniye.
- Değer
$FinalDate
, daha sonradan (daha sonra) büyüktür $StartDate
.
- Zaman farkı 24 saatten küçük.
- Saat, Dakika ve Saniye ile çıktı biçimini kabul edersiniz. Değiştirmesi çok kolay.
- -U UTC saatlerini kullanmak kabul edilebilir. "DST" ve yerel saat düzeltmelerini önlemek için.
Eğer dizeyi kullanmanız gerekiyorsa10:33:56
, sadece saniyeye dönüştürün,
ayrıca saniye kelimesi sn olarak kısaltılabilir:
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"
Saniyede zaman dönüşümünün (yukarıda gösterildiği gibi) "bu" günün başlangıcına (Bugün) göre olduğunu unutmayın.
Konsept nanosaniyeye uzatılabilir, şöyle:
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"
Daha uzun (364 güne kadar) zaman farklarını hesaplamak gerekirse, (bazı) yılın başlangıcını referans olarak ve biçim değerini %j
(yıl içindeki gün numarası) kullanmalıyız:
Benzer:
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
Ne yazık ki, bu durumda, ONE'yi 1
gün sayısından manuel olarak çıkarmamız gerekiyor . Tarih komutu yılın ilk gününü 1 olarak görüntüler. O kadar zor değil ...
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[@]}"
Uzun saniye kullanımı geçerlidir ve burada belgelenmiştir:
https://www.gnu.org/software/coreutils/manual/html_node/Examples-of-date.html#Examples-of-date
Meşgul Kutusu tarihi
Daha küçük cihazlarda kullanılan bir araç (kurulumu çok küçük yürütülebilir): Busybox.
Date adlı bir meşgul kutusuna bağlantı verin:
$ ln -s /bin/busybox date
Daha sonra bunu çağırarak kullanın date
(PATH dahil bir dizine yerleştirin).
Veya aşağıdaki gibi bir takma ad yapın:
$ alias date='busybox date'
Busybox tarihinin güzel bir seçeneği var: -D giriş zamanının biçimini almak için. Bu, zaman olarak kullanılacak birçok biçimi açar. -D seçeneğini kullanarak, zamanı 10:33:56 doğrudan dönüştürebiliriz:
date -D "%H:%M:%S" -d "10:33:56" +"%Y.%m.%d-%H:%M:%S"
Ve yukarıdaki Komuta'nın çıktısından da görebileceğiniz gibi, günün "bugün" olduğu varsayılır. Dönemden başlamak için:
$ 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 tarihi saati -D olmadan da alabilir (yukarıdaki formatta):
$ date -u -d "1970.01.01-$string1" +"%Y.%m.%d-%H:%M:%S"
1970.01.01-10:33:56
Ve çıktı biçimi çağdan beri saniye bile olabilir.
$ date -u -d "1970.01.01-$string1" +"%s"
52436
Her iki kez ve biraz bash matematik (busybox henüz matematik yapamaz):
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 ))
Veya biçimlendirilmiş:
$ date -u -D "%s" -d "$(( t2 - t1 ))" +"%H:%M:%S"
00:02:14
time
komutu kullanamaz mısınız?