150 votes

Meilleur moyen d'obtenir le temps en millisecondes en javascript ?

Existe-t-il une alternative en JavaScript pour obtenir le temps en millisecondes en utilisant l'objet date, ou au moins un moyen de réutiliser cet objet, sans avoir à instancier un nouvel objet à chaque fois que j'ai besoin d'obtenir cette valeur ? Je pose cette question parce que j'essaie de créer un moteur de jeu simple en JavaScript, et lors du calcul du "delta frame time", je dois créer un nouvel objet Date à chaque frame. Bien que je ne sois pas trop inquiet des conséquences de cette opération sur les performances, j'ai quelques problèmes avec la fiabilité de l'heure exacte renvoyée par cet objet.

J'obtiens des "sauts" étranges dans l'animation, toutes les secondes environ, et je ne sais pas si cela est lié au Garbage Collection de JavaScript ou à une limitation de l'objet Date lors d'une mise à jour aussi rapide. Si je fixe la valeur du delta à une constante, l'animation est parfaitement fluide. Je suis donc certain que ce "saut" est lié à la façon dont j'obtiens l'heure.

Le seul code pertinent que je peux donner est la façon dont je calcule le temps delta :

prevTime = curTime;
curTime = (new Date()).getTime();
deltaTime = curTime - prevTime;

Lors du calcul du mouvement / de l'animation, je multiplie une valeur constante avec le temps delta.

S'il n'y a aucun moyen d'éviter d'obtenir le temps en millisecondes en utilisant l'objet Date, une fonction qui incrémente une variable (étant le temps écoulé en millisecondes depuis le début du jeu), et qui est appelée en utilisant la fonction SetTimer à un rythme d'une fois toutes les millisecondes serait-elle une alternative efficace et fiable ?

Edit : J'ai maintenant testé mon code dans différents navigateurs et il semble que ce "saut" ne soit vraiment apparent que dans Chrome, pas dans Firefox. Mais ce serait quand même bien s'il y avait une méthode qui fonctionne dans les deux navigateurs.

5 votes

Un objet par image est nada

3 votes

A propos de l'animation qui saute toutes les secondes, cela pourrait-il avoir un rapport avec le fait que Date.getMilliseconds renvoie uniquement les millisecondes de la seconde en cours, c'est-à-dire de 0 à 999 ? Vous n'utilisez pas cette fonction dans votre exemple, mais elle est peut-être utilisée ailleurs, ou sur une autre branche ?

2 votes

Est-ce que les sauts sont liés à des problèmes bizarres de résolution en millisecondes ? D'après le Documents de Mozilla : "Lorsque vous utilisez now() pour créer des timestamps ou des identifiants uniques, gardez à l'esprit que la résolution peut être de 15 millisecondes sous Windows". Cela pourrait-il être lié aux hoquets ?

183voto

Joeri Sebrechts Points 7483

Essayez Date.now() .

Le saut est très probablement dû à la collecte des déchets. En général, le ramassage des déchets peut être évité en réutilisant les variables autant que possible, mais je ne peux pas dire spécifiquement quelles méthodes vous pouvez utiliser pour réduire les pauses du ramassage des déchets.

1 votes

J'ai essayé d'utiliser Date.now(), mais j'ai toujours les mêmes sauts. Je suis donc à présent presque certain qu'il ne s'agit pas d'un problème de garbage collection, mais plutôt d'une limitation dans l'obtention de valeurs exactes avec l'objet Date. Comme je l'ai dit, remplacer le temps delta par une valeur constante permet d'obtenir des animations / transitions fluides, donc le seul garbage collection qui pourrait se produire est avec "new Date" ou "Date.now()" (si cette fonction instancie ses propres objets que je ne connais pas).

22 votes

Juste un avertissement : Cela ne fonctionne pas dans IE8 et en dessous

1 votes

Je le fais. Tout ce que je veux c'est la date en ms. Ça semble si compliqué pour quelque chose de si nécessaire.

52voto

ngryman Points 611

Pour autant que je sache, vous ne pouvez obtenir du temps qu'avec Date .

Date.maintenant est la solution mais n'est pas disponible partout : https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/now .

var currentTime = +new Date();

Cela vous donne l'heure actuelle en millisecondes.

Pour votre sauts . Si vous calculez interpolations correctement en fonction de la temps de trame delta et vous n'avez pas de erreur d'arrondi des chiffres Je parie sur le garbage collector (GC).

Si un grand nombre d'objets temporaires sont créés dans votre boucle, le ramasse-miettes doit bloquer le thread pour effectuer un nettoyage et une réorganisation de la mémoire.

Avec Chrome, vous pouvez voir combien de temps le GC passe dans la page d'accueil. Ligne du temps panneau.

EDIT : Depuis ma réponse, Date.now() doit être considéré comme la meilleure option car il est supporté partout et sur IE >= 9.

4 votes

Quelle est la fonction de la + servir dans +new ?

33 votes

El + tout simplement Date a Number , donnant un timestamp standard Unix en millisecondes. Vous pouvez obtenir explicitement cette valeur en appelant (new Date()).getTime()

9 votes

@mikenelson : Pas terrible pour moi, c'est évident quand on sait comment fonctionne la coercition.Cela dit, Date.now() est préférée maintenant car son support est suffisamment large.

51voto

Chris GW Green Points 266

Je sais qu'il s'agit d'un vieux fil de discussion, mais pour que les choses restent à jour et plus pertinentes, vous pouvez utiliser l'option plus précise suivante performance.now() pour obtenir un timing plus fin en javascript.

window.performance = window.performance || {};
performance.now = (function() {
    return performance.now       ||
        performance.mozNow    ||
        performance.msNow     ||
        performance.oNow      ||
        performance.webkitNow ||            
        Date.now  /*none found - fallback to browser default */
})();

2 votes

La dernière alternative devrait être juste Date.now au lieu d'une expression de fonction anonyme

1 votes

Il ne fonctionne pas non plus dans les vieux navigateurs stupides, malheureusement. Heureusement, j'ai convaincu mes clients de me payer pour le temps que je perds à supporter IE7 et IE8.

2 votes

|| function() { return new Date().getTime() }

11voto

dilip kumar Points 94

Si vous avez un objet de date comme

var date = new Date('2017/12/03');

alors il existe une méthode intégrée en javascript pour obtenir la date en format millisecondes qui est la suivante valueOf()

date.valueOf(); //1512239400000 in milliseconds format

2voto

LarsKnudsen Points 1

Il s'agit d'une question très ancienne, mais qui peut toujours servir de référence si d'autres personnes l'examinent. requestAnimationFrame() est la bonne façon de gérer l'animation dans les navigateurs modernes :

MISE À JOUR : Le lien mozilla montre comment faire - je n'avais pas envie de répéter le texte derrière le lien ;)

4 votes

Bienvenue à Stack Overflow ! Vous pouvez inclure une brève explication de ce qu'est la requestAnimationFrame permet d'arrêter ce "saut" tel que décrit dans la question. Merci !

2 votes

Même avec requestAnimationFrame, nous ne sommes pas censés supposer que la fréquence d'images est la même sur toutes les plates-formes, donc nous devons toujours vérifier le temps actuel.

Prograide.com

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.

Powered by:

X