Comment obtenir l'heure actuelle d'Unix en millisecondes en bash?


232

Comment obtenir l'heure actuelle d'Unix en millisecondes (c'est-à-dire le nombre de millisecondes depuis l'époque Unix le 1er janvier 1970)?

Réponses:


265

Cette:

date +%s 

retournera le nombre de secondes depuis l'époque.

Cette:

date +%s%N

renvoie les secondes et les nanosecondes actuelles.

Alors:

date +%s%N | cut -b1-13

vous donnera le nombre de millisecondes écoulées depuis l'époque - secondes actuelles plus les trois nanosecondes à gauche.


et de MikeyB - echo $(($(date +%s%N)/1000000))(diviser par 1000 ne rapporte qu’en microsecondes)


39
Je me demande combien de ms la coupe ajoute :-)
Kyle Brandt

13
Ou si vous voulez tout faire dans le shell, en évitant les frais généraux onéreux d'un processus supplémentaire (en fait, nous évitons le problème lorsque le nombre de chiffres dans% + s + N change):echo $(($(date +%s%N)/1000))
MikeyB

5
C'est le principe de la matière ... évitez les nombres magiques et codez ce que vous voulez dire .
MikeyB

25
Je pense qu'il convient de noter que l'homme a demandé Unix, pas Linux, et que la réponse actuelle (date +% s% N) ne fonctionne pas sur mon système AIX.
Pete

12
@Pete +1 Idem pour OS X et FreeBSD
date

100

Vous pouvez simplement utiliser %3Npour tronquer les nanosecondes aux 3 chiffres les plus significatifs (qui sont alors des millisecondes):

$ date +%s%3N
1397392146866

Cela fonctionne par exemple sur mon kubuntu 12.04.

Sachez toutefois que cela %Npeut ne pas être mis en œuvre en fonction de votre système cible. Par exemple, testé sur un système intégré (rootrois de la racine, compilé à l’aide d’une chaîne d’outils croisés de bras non-HF), il n’existait pas de %N:

$ date +%s%3N
1397392146%3N

(Et aussi ma tablette Android (non enracinée) n'a pas %N).


1
@warren: J'ai vu que vous avez modifié et changé le 1397392146%3Npour 1397392146%N, mais la sortie 1397392146%3Nest que ce que je vraiment vu sur la console busybox de ma tablette Android. Pourriez-vous expliquer votre édition?
Joe

Le commentaire de Warren dans l'historique est "changé de 3 à 6, car 3 ne vous emmène qu'en microsecondes". Son édition semble totalement fausse; vous devriez le faire reculer.
bukzor

1
C’est une caractéristique de GNU coreutils en particulier. En fin de compte, cela est implémenté dans gnulib ici: github.com/gagern/gnulib/blob/… .
telotortium

probablement un point a du sens. date +%s.%3Nimpressions 1510718281.134.
darksky

Cela devrait être la réponse acceptée.
Noah Sussman

61

date +%N ne fonctionne pas sous OS X, mais vous pouvez utiliser l'un des

  • rubis: ruby -e 'puts Time.now.to_f'
  • python: python -c 'import time; print time.time()'
  • node.js: node -e 'console.log(Date.now())'
  • PHP: php -r 'echo microtime(TRUE);'
  • Élixir: DateTime.utc_now() |> DateTime.to_unix(:millisecond)
  • les internets: wget -qO- http://www.timeapi.org/utc/now?\\s.\\N
  • ou en millisecondes arrondi à la seconde près date +%s000

1
pour être complet ...node -e 'console.log(Date.now())'
slf

1
Utiliser PHP:php -r 'echo microtime(TRUE);'
TachyonVortex Le

8
Bien sûr, vous devez simplement attendre que ces interprètes se réchauffent. Cela fonctionne aussi:wget -qO- http://www.timeapi.org/utc/now?\\s.\\N
Camilo Martin

8
Ou, si vous n'avez pas réellement besoin des millisecondes mais juste du format correct:date +%s000
Lenar Hoyt

1
apple.stackexchange.com/questions/135742/… a des instructions pour le faire sous OSX via Brew'scoreutils
sameers

10

Il suffit de jeter cela dehors, mais je pense que la formule correcte avec la division serait:

echo $(($(date +%s%N)/1000000))

10

Ma solution n'est pas la meilleure mais a fonctionné pour moi.

date +%s000

Je devais juste convertir une date comme le 2012-05-05 en millisecondes.


1
Hack

7
Vous devez être quelqu'un parmi mes collègues.
Nakilon

7

Pour les personnes qui suggèrent d’exécuter des programmes externes pour obtenir les millisecondes ... à ce rythme, vous pouvez tout aussi bien faire ceci:

wget -qO- http://www.timeapi.org/utc/now?\\s.\\N

Le point étant: avant de choisir une réponse, gardez à l’esprit que tous les programmes ne fonctionneront pas en une seconde. Mesure!


Vous ne demandez pas l'heure au système local. Ce qui, je suppose, est impliqué dans la question. Vous dépendez également d'une connexion réseau.
Orkoden

2
@orkoden La question demande explicitement le "nombre de millisecondes depuis l'époque Unix le 1er janvier 1970". En outre, je souligne davantage le fait que vous ne devriez jamais lancer tout un tas de ruby ​​ou de python (ou wget) juste pour avoir le temps - soit que cela se fasse par un canal rapide ou que des millisecondes importent peu.
Camilo Martin le

2
Oui, j'ai compris que vous donniez une solution pire pour mettre en évidence les défauts des mauvaises solutions. J'ai essayé plusieurs solutions et mesuré le temps. lpaste.net/119499 Les résultats sont plutôt intéressants. Même sur une machine i7 très rapide, cela dateprend 3 ms.
Orkoden

@orkoden Nice test! Quel OS? Cela pourrait avoir à voir avec les frais généraux de génération de processus.
Camilo Martin

1
@Nakilon et c’est la raison pour laquelle il ne faut pas s’appuyer sur des commodités faciles à boucler comme celles de la production.
Camilo Martin

5

cette solution fonctionne sur macOS.

Si vous envisagez d'utiliser un script bash et que vous disposez de python, vous pouvez utiliser ce code:

#!/bin/bash

python -c 'from time import time; print int(round(time() * 1000))'

pourquoi le vote bas?
Frank Thonig

Ne semble pas particulièrement justifié. L'indication sur la flèche vers le bas indique "Cette réponse n'est pas utile", mais IMO, c'est utile. Peut-être qu'ils voulaient que vous en fassiez un script Python à la place. Ce serait plus simple et fonctionnerait également comme une commande bash.
Andrew Schulman

Ne vous inquiétez pas trop des votes négatifs (ce n'était pas le mien) ... surtout s'ils sont anonymes (d'où on ne peut pas savoir ce qui semble être faux, n'est-ce pas?). Juste pour vous aider à le traiter ... voici un autre +1 ... devinez quoi: vous êtes également autorisé à "voter" maintenant, n'est-ce pas?
Pierre.Vriens

Le vote négatif semble avoir été causé par un problème avec le système. Il a depuis été supprimé, à nouveau par le système.
Michael Hampton

2

Si vous recherchez un moyen d'afficher la durée d'exécution de votre script, les résultats suivants fourniront un résultat (pas tout à fait exact):

Au début de votre script, entrez les informations suivantes:

basetime=$(date +%s%N)

Cela vous donnera une valeur de départ de quelque chose comme 1361802943996000000

À la fin de votre script, utilisez ce qui suit

echo "runtime: $(echo "scale=3;($(date +%s%N) - ${basetime})/(1*10^09)" | bc) seconds"

qui affichera quelque chose comme

runtime: 12.383 seconds

Remarques:

(1 * 10 ^ 09) peut être remplacé par 1000000000 si vous le souhaitez

"scale=3"est un paramètre plutôt rare qui oblige bcà faire ce que vous voulez. Il y en a beaucoup plus!

Je n'ai testé cela que sur Win7 / MinGW ... Je n'ai pas de boîte * nix appropriée à portée de main.


3
ou vous pouvez simplement utilisertime <script>
Warren

2

Voici comment obtenir le temps en millisecondes sans effectuer de division. Peut-être que c'est plus rapide ...

# test=`date +%s%N`
# testnum=${#test}
# echo ${test:0:$testnum-6}
1297327781715

Mise à jour: une autre alternative de pure bash qui fonctionne uniquement avec bash 4.2+est identique à celle ci-dessus mais utilise printfpour obtenir la date. Ce sera certainement plus rapide car aucun processus n'est dérivé du processus principal.

printf -v test '%(%s%N)T' -1
testnum=${#test}
echo ${test:0:$testnum-6}

Une autre prise ici est que si votre strftimemise en œuvre devrait soutenir %set %Nqui est pas le cas sur ma machine de test. Voir man strftimepour les options supportées. Voir aussi man bashpour voir la printfsyntaxe. -1et -2sont des valeurs spéciales pour le temps.


On dirait que mon strftime(3)ne supporte pas, %Ndonc aucun moyen printfd’imprimer des nanosecondes. J'utilise Ubuntu 14.04.
haridsv

@haridsv, oui, ce n'est pas dans la glibc. datesemble être l'option la plus fiable.
akostadinov

2

L’horodatage le plus précis que nous puissions obtenir (du moins pour Mac OS X) est probablement le suivant:

python -c 'import datetime; print datetime.datetime.now().strftime("%s.%f")'

1490665305.021699

Mais il ne faut pas oublier qu'il faut environ 30 millisecondes pour fonctionner. Nous pouvons le réduire à l’échelle de la fraction de 2 chiffres, et tout au début calculer l’aide moyenne due à la lecture de l’heure, puis l’éliminer de la mesure. Voici un exemple:

function getTimestamp {
  echo `python -c 'import datetime; print datetime.datetime.now().strftime("%s.%f")' | cut -b1-13` 
}
function getDiff {
  echo "$2-$1-$MeasuringCost" | bc
}
prev_a=`getTimestamp`
acc=0
ITERATIONS=30
for i in `seq 1 $ITERATIONS`;do 
  #echo -n $i 
  a=`getTimestamp`
  #echo -n "   $a"
  b=`echo "$a-$prev_a" | bc`
  prev_a=$a
  #echo "  diff=$b"
  acc=`echo "$acc+$b" | bc`
done
MeasuringCost=`echo "scale=2; $acc/$ITERATIONS" | bc`
echo "average: $MeasuringCost sec"
t1=`getTimestamp`
sleep 2
t2=`getTimestamp`
echo "measured seconds: `getDiff $t1 $t2`"

Vous pouvez décommenter les commandes echo pour mieux voir comment cela fonctionne.

Les résultats de ce script sont généralement l'un de ces 3 résultats:

measured seconds: 1.99
measured seconds: 2.00
measured seconds: 2.01

1

Utiliser date et expr peut vous y amener c'est-à-dire

X=$(expr \`date +%H\` \\* 3600 + \`date +%M\` \\* 60 + \`date +%S\`)
echo $X

Développez-le pour faire ce que vous voulez

Je me rends bien compte que cela ne donne pas des millisecondes depuis l’époque, mais que cela peut toujours être utile comme réponse à certains cas, tout dépend de ce dont vous avez réellement besoin, multipliez par 1000 si vous avez besoin d’un nombre en millisecondes: D

Le moyen le plus simple serait de créer un petit exécutable (à partir de C f.ex.) et de le rendre disponible pour le script.


Il y a un problème potentiel qui se répète dateplusieurs fois. Dans certains cas, la date ou l'heure peuvent changer entre les exécutions au fur et à mesure que votre commande est écrite. Il est préférable d'exécuter dateune fois et analyser les parties et faire votre calcul. Une des manières de le faire serait t=$(date +%H%M%S); (( x = ${t:0:2} * 3600 + ${t:2:2} * 60 + ${t:4:2} )); echo "$x". Ceci utilise la syntaxe Bash puisque la question est étiquetée bash . Comme vous le dites, votre réponse (et ma variante) ne donne que quelques secondes pour la journée en cours jusqu'à présent et non depuis l’époque et non en millis.
Dennis Williamson

1

(répéter ci-dessus) date +%Nne fonctionne pas sous OS X, mais vous pouvez aussi utiliser:

Perl (nécessite le module Time :: Format). Peut-être pas le meilleur module CPAN à utiliser mais fait le travail. Time :: Format est généralement mis à disposition avec les distributions.

perl -w -e'use Time::Format; printf STDOUT ("%s.%s\n", time, $time{"mmm"})'

Le PO a spécifiquement demandé des moyens de le faire en utilisant bash. Comment cette bash est-elle sauvegardée comme méthode pour lancer autre chose?
MadHatter

J'utilise ceci dans mes scripts shell bash ... sous OSX. Donc, datene peut pas être utilisé et il n'y a pas de commandes uniquement bash qui répondent au besoin.
TVNshack

C'est suffisant. Si vous deviez clarifier les raisons pour lesquelles OSX ne datepeut pas être utilisé dans votre réponse , je supprimerais mon vote négatif.
MadHatter

Cela a été expliqué quelques réponses ci-dessus. Je ne pouvais pas ajouter comme commentaire cette commande qui manquait avec la liste proposée. Donc je l'ai ajouté ici.
TVNshack

Très bien, je reconnais que c’est un ajout utile au canon. +1 de moi!
MadHatter

1

Rassembler toutes les réponses précédentes, lorsque sous OSX

ProductName:    Mac OS X
ProductVersion: 10.11.6
BuildVersion:   15G31+

tu peux faire comme

microtime() {
    python -c 'import time; print time.time()'
}
compute() {
    local START=$(microtime)
    #$1 is command $2 are args
    local END=$(microtime)
    DIFF=$(echo "$END - $START" | bc)
    echo "$1\t$2\t$DIFF"
}

0

Si vous voulez un calcul simple shell écoulé, c'est facile et portable, en utilisant la réponse ci-dessus:

now() {
    python -c 'import datetime; print datetime.datetime.now().strftime("%s.%f")'
}
seismo:~$ x=`now`
seismo:~$ y=`now`
seismo:~$ echo "$y - $x" | bc
5.212514

0

Pour linux alpin (beaucoup d’images de docker) et éventuellement d’autres environnements Linux minimaux, vous pouvez abuser adjtimex:

adjtimex | awk '/(time.tv_usec):/ { printf("%06d\n", $2) }' | head -c3

adjtimexest utilisé pour lire (et définir) les variables de temps du noyau. Avec awkvous pouvez obtenir les microsecondes, avec headvous ne pouvez utiliser que les 3 premiers chiffres.

Je n'ai aucune idée de la fiabilité de cette commande.

Remarque: volé sans vergogne de cette réponse

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.