J'imprime l'heure de début et de fin en utilisant date +"%T"
ce qui donne quelque chose comme :
10:33:56
10:36:10
Comment pourrais-je calculer et imprimer la différence entre les deux ?
J'aimerais obtenir quelque chose comme :
2m 14s
J'imprime l'heure de début et de fin en utilisant date +"%T"
ce qui donne quelque chose comme :
10:33:56
10:36:10
Comment pourrais-je calculer et imprimer la différence entre les deux ?
J'aimerais obtenir quelque chose comme :
2m 14s
Bash a une fonction pratique SECONDS
variable intégrée qui indique le nombre de secondes écoulées depuis le démarrage de l'interpréteur de commandes. Cette variable conserve ses propriétés lorsqu'elle est assignée, et la valeur renvoyée après l'assignation est le nombre de secondes écoulées depuis l'assignation plus la valeur assignée.
Ainsi, vous pouvez simplement définir SECONDS
à 0 avant de lancer l'événement minuté, il suffit de lire SECONDS
après l'événement, et faire l'arithmétique du temps avant de l'afficher.
#!/usr/bin/env bash
SECONDS=0
# do some work
duration=$SECONDS
echo "$(($duration / 60)) minutes and $(($duration % 60)) seconds elapsed."
Comme cette solution ne dépend pas de date +%s
(qui est une extension GNU), il est portable sur tous les systèmes supportés par Bash.
+1. Par ailleurs, vous pouvez tromper date
en effectuant l'arithmétique du temps pour vous, en écrivant date -u -d @"$diff" +'%-Mm %-Ss'
. (Cela interprète $diff
en tant que secondes depuis l'époque, et calcule les minutes et les secondes en UTC). Mais ce n'est probablement pas plus élégant, juste mieux caché :-P
C'est simple et agréable. Si quelqu'un a besoin d'heures : echo "$(($diff / 3600)) hours, $((($diff / 60) % 60)) minutes and $(($diff % 60)) seconds elapsed."
Il faut lire $(date -u +%s)
pour empêcher une condition de course sur les dates où l'heure d'été est changée. Et attention aux méchantes secondes intercalaires ;)
En quoi est-ce différent de ma solution ? Je ne vois vraiment pas l'intérêt d'appeler awk
dans ce cas, puisque Bash gère tout aussi bien l'arithmétique des nombres entiers.
Votre réponse est également correcte. Certaines personnes, comme moi, préfèrent travailler avec awk plutôt qu'avec les incohérences de bash.
Pourriez-vous nous en dire plus sur les incohérences de Bash concernant l'arithmétique des nombres entiers ? J'aimerais en savoir plus à ce sujet, car je n'en avais pas connaissance.
Je voudrais proposer une autre façon d'éviter de rappeler date
commande. Cela peut s'avérer utile si vous avez déjà rassemblé des horodatages en %T
le format de la date :
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"
on peut même traiter les millisecondes de la même manière.
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"
Le traitement des millisecondes se comporte mal si le champ des millisecondes commence par un zéro. Par exemple, ms="033" donnera comme chiffre de fin "027" parce que le champ ms est interprété en octal. en changeant "echo" ... "+ms))" en ... "+${ms##+(0)}))" résoudra ce problème tant que "shopt -s extglob" apparaît quelque part au-dessus dans le script. On devrait probablement enlever les zéros de tête de h, m, et s aussi...
À partir de la date (GNU coreutils) 7.4, vous pouvez maintenant utiliser -d pour faire de l'arithmétique :
$ date -d -30days
Sat Jun 28 13:36:35 UTC 2014
$ date -d tomorrow
Tue Jul 29 13:40:55 UTC 2014
Les unités que vous pouvez utiliser sont les jours, les années, les mois, les heures, les minutes et les secondes :
$ date -d tomorrow+2days-10minutes
Thu Jul 31 13:33:02 UTC 2014
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
5 votes
Dans un autre ordre d'idées, ne pourriez-vous pas utiliser le
time
commande ?1 votes
Utilisez le temps unix à la place,
date +%s
puis soustraire pour obtenir la différence en secondes.