Comment obtenir l'heure actuelle en millisecondes en PHP?

323

time() est en secondes - y en a-t-il une en millisecondes?

Arrivant
la source

Réponses:

506

La réponse courte est:

$milliseconds = round(microtime(true) * 1000);
laurent
la source
26
@FredrikWendt, je pense que vous confondez avec time(). microtime(true)d'autre part retourne l'heure actuelle en secondes depuis l'époque Unix précise à la microseconde la plus proche (voir référence PHP). Il est en fait très facile de tester si vous exécutez le code ci-dessus en boucle et affichez les millisecondes.
laurent
6
Je l'ai absolument fait! :-)
Fredrik Wendt
10
J'aime la réponse courte.
Erick Robertson
9
Cela ne devrait-il pas être microtime(true) / 1000(division plutôt que multiplication)?
Jordan Lev
18
@JordanLev, il doit s'agir d'une multiplication car microtime (true) renvoie l'horodatage Unix en secondes sous forme de flottant.
laurent
88

Utilisez microtime. Cette fonction renvoie une chaîne séparée par un espace. La première partie est la partie fractionnaire des secondes, la seconde partie est la partie intégrante. Passez truepour obtenir un numéro:

var_dump(microtime());       // string(21) "0.89115400 1283846202"
var_dump(microtime(true));   // float(1283846202.89)

Méfiez-vous des pertes de précision si vous utilisez microtime(true).

Il y a aussi gettimeofdayqui retourne la partie microsecondes sous forme d'entier.

var_dump(gettimeofday());
/*
array(4) {
  ["sec"]=>
  int(1283846202)
  ["usec"]=>
  int(891199)
  ["minuteswest"]=>
  int(-60)
  ["dsttime"]=>
  int(1)
}
*/
kennytm
la source
Donc, de manière générale, c'est microtime()égal 1000*time(), non?
COMer
Je vois, il peut y avoir des erreurs, mais l'erreur devrait être inférieure à 1000, non?
COMer
@COMer: De quelle variante parlez-vous?
kennytm
microtime(true)et1000*time()
COMer
@COMer: 1000*time()ne vous donnera pas des millisecondes. microtime(true)renvoie un floatqui a 14 chiffres de précision. La partie secondes a déjà pris 10, ce qui laisse 4 chiffres pour la partie microsecondes. Cela devrait être suffisant car les millisecondes ne nécessitent que 3 chiffres supplémentaires.
kennytm
46

Réponse courte:

Plateformes 64 bits uniquement!

function milliseconds() {
    $mt = explode(' ', microtime());
    return ((int)$mt[1]) * 1000 + ((int)round($mt[0] * 1000));
}

[ Si vous utilisez PHP 64 bits, la constante PHP_INT_SIZEest égale à8 ]


Longue réponse:

Si vous voulez d'abord une fonction équivalente de time()en millisecondes, vous devez considérer que comme time()renvoie le nombre de secondes écoulées depuis le "temps d'époque" (01/01/1970), le nombre de millisecondes depuis le "temps d'époque" est un grand nombre et ne rentre pas dans un entier de 32 bits.

La taille d'un entier en PHP peut être de 32 ou 64 bits selon la plateforme.

Depuis http://php.net/manual/en/language.types.integer.php

La taille d'un entier dépend de la plate-forme, bien qu'une valeur maximale d'environ deux milliards soit la valeur habituelle (c'est-à-dire 32 bits signés). Les plates-formes 64 bits ont généralement une valeur maximale d'environ 9E18, à l'exception de Windows, qui est toujours de 32 bits. PHP ne prend pas en charge les entiers non signés. La taille entière peut être déterminée en utilisant la constante PHP_INT_SIZE, et la valeur maximale en utilisant la constante PHP_INT_MAX depuis PHP 4.4.0 et PHP 5.0.5.

Si vous avez des entiers 64 bits, vous pouvez utiliser la fonction suivante:

function milliseconds() {
    $mt = explode(' ', microtime());
    return ((int)$mt[1]) * 1000 + ((int)round($mt[0] * 1000));
}

microtime() renvoie le nombre de secondes depuis le "temps d'époque" avec une précision allant jusqu'à microsecondes avec deux nombres séparés par un espace, comme ...

0.90441300 1409263371

Le deuxième nombre est les secondes (entier) tandis que le premier est la partie décimale.

La fonction ci-dessus milliseconds()prend la partie entière multipliée par1000

1409263371000

ajoute ensuite la partie décimale multipliée 1000et arrondie à 0 décimales

1409263371904

Notez que les deux $mt[1]et le résultat de roundsont convertis en int. Ceci est nécessaire car ils sont floats et l'opération sur eux sans casting entraînerait le retour de la fonction a float.

Enfin, cette fonction est légèrement plus précise que

round(microtime(true)*1000);

celui avec un rapport de 1:10 (environ) renvoie 1 milliseconde de plus que le résultat correct. Cela est dû à la précision limitée du type float ( microtime(true)renvoie un float). Quoi qu'il en soit, si vous préférez toujours le plus court, round(microtime(true)*1000);je suggère de lancer intle résultat.


Même si cela dépasse la portée de la question, il convient de mentionner que si votre plate-forme prend en charge les entiers 64 bits, vous pouvez également obtenir l'heure actuelle en microsecondes sans encourir de débordement.

Si fait 2^63 - 1(le plus grand entier signé) divisé par 10^6 * 3600 * 24 * 365(approximativement les microsecondes en un an) donne 292471.

C'est la même valeur que vous obtenez avec

echo (int)( PHP_INT_MAX / ( 1000000 * 3600 * 24 * 365 ) );

En d'autres termes, un entier signé de 64 bits peut stocker une période de plus de 200 000 ans mesurée en microsecondes.

Vous pouvez alors avoir

function microseconds() {
    $mt = explode(' ', microtime());
    return ((int)$mt[1]) * 1000000 + ((int)round($mt[0] * 1000000));
}
Paolo
la source
pourquoi pas: `function getMilliEpoch () {$ mt = explode ('', microtime ()); retourne $ mt [1]. substr ($ mt [0], 0, 5) * 1000; } `
Michael
Maintenant, il y a un paramètre pour la fonction microtime, s'il est défini sur true, il renvoie les secondes et les millisecondes depuis le 1er janvier 1970, 0 heure 0 minutes 0 secondes comme flottant. Voici un exemple: microtime (vrai) // 1553260455.7242
kukko
@kukko oui, mais en raison de la précision limitée du type de flotteur, le calcul du nombre de millicesecondes à partir du microtime (vrai) se traduira par une valeur légèrement inexacte
Paolo
42

Comme d'autres l'ont indiqué, vous pouvez utiliser microtime()pour obtenir une précision en millisecondes sur les horodatages.

D'après vos commentaires, vous semblez le vouloir comme un horodatage UNIX de haute précision. Quelque chose comme DateTime.Now.Ticksdans le monde .NET.

Pour ce faire, vous pouvez utiliser la fonction suivante:

function millitime() {
  $microtime = microtime();
  $comps = explode(' ', $microtime);

  // Note: Using a string here to prevent loss of precision
  // in case of "overflow" (PHP converts it to a double)
  return sprintf('%d%03d', $comps[1], $comps[0] * 1000);
}
Andrew Moore
la source
C'est la façon de le faire!
tonix
1
perrrrrrfect .. ♥.
SRB interdit le
N'est-ce pas retourner l'heure du serveur? Dans mon cas, je vois que l'heure stockée dans db est l'heure de mon navigateur local. Supposons que mon fuseau horaire soit EST + 3 et que l'heure de mon navigateur soit GMT + 6, alors que je soumets un formulaire à partir de l'emplacement GMT + 6, je vois que l'heure stockée est GMT + 6 équivalent milliseconde. Alors quel est le problème? :(
Zenith
12

Utilisation microtime(true)en PHP 5, ou la modification suivante en PHP 4:

array_sum(explode(' ', microtime()));

Une façon portable d'écrire ce code serait:

function getMicrotime()
{
    if (version_compare(PHP_VERSION, '5.0.0', '<'))
    {
        return array_sum(explode(' ', microtime()));
    }

    return microtime(true);
}
Alix Axel
la source
11

echo date('Y-m-d H:i:s.') . gettimeofday()['usec'];

production:

2016-11-19 15:12:34.346351

mojmir.novak
la source
1
Cela utilise le même horodatage:$t = gettimeofday(); echo date('Y-m-d H:i:s.',$t['sec']) . $t['usec'];
Savvas Radevic
les microsecondes devraient être $timeofday=gettimeofday(); echo sprintf("%s.%06d", date('Y-m-d H:i:s', $timeofday['sec']), $timeofday['usec']);
complétées par
7

essaye ça:

public function getTimeToMicroseconds() {
    $t = microtime(true);
    $micro = sprintf("%06d", ($t - floor($t)) * 1000000);
    $d = new DateTime(date('Y-m-d H:i:s.' . $micro, $t));

    return $d->format("Y-m-d H:i:s.u"); 
}
Hồ Lê Thiện Thành
la source
7

Cela fonctionne même si vous êtes en PHP 32 bits:

list($msec, $sec) = explode(' ', microtime());

$time_milli = $sec.substr($msec, 2, 3); // '1491536422147'
$time_micro = $sec.substr($msec, 2, 6); // '1491536422147300'

Notez que cela ne vous donne pas des entiers, mais des chaînes. Cependant, cela fonctionne bien dans de nombreux cas, par exemple lors de la création d'URL pour les demandes REST.


Si vous avez besoin d'entiers, le PHP 64 bits est obligatoire.

Ensuite, vous pouvez réutiliser le code ci-dessus et le convertir en (int):

list($msec, $sec) = explode(' ', microtime());

// these parentheses are mandatory otherwise the precedence is wrong!
//                  ↓                        ↓
$time_milli = (int) ($sec.substr($msec, 2, 3)); // 1491536422147
$time_micro = (int) ($sec.substr($msec, 2, 6)); // 1491536422147300

Ou vous pouvez utiliser les bons vieux one-liners:

$time_milli = (int) round(microtime(true) * 1000);    // 1491536422147
$time_micro = (int) round(microtime(true) * 1000000); // 1491536422147300
Gras Double
la source
5
$timeparts = explode(" ",microtime());
$currenttime = bcadd(($timeparts[0]*1000),bcmul($timeparts[1],1000));
echo $currenttime;

REMARQUE: PHP5 est requis pour cette fonction en raison des améliorations apportées à microtime () et le module mathématique bc est également requis (car nous avons affaire à de grands nombres, vous pouvez vérifier si vous avez le module dans phpinfo).

J'espère que cela vous aidera.

amnippon
la source
5
$the_date_time = new DateTime($date_string);
$the_date_time_in_ms = ($the_date_time->format('U') * 1000) +
    ($the_date_time->format('u') / 1000);
user3767296
la source
Est-ce en fait comme remplir trois zéros à droite?
Zeeshan
Pas du tout. Il convertit les deux parties en millisecondes et donne la somme. Il est donc plus précis que d'ajouter des zéros.
user3767296
1
Bien que cet extrait de code puisse résoudre la question, y compris une explication aide vraiment à améliorer la qualité de votre message. N'oubliez pas que vous répondrez à la question des lecteurs à l'avenir et que ces personnes ne connaissent peut-être pas les raisons de votre suggestion de code. Essayez également de ne pas surcharger votre code avec des commentaires explicatifs, cela réduit la lisibilité du code et des explications!
Michał Perłakowski
1

PHP 5.2.2 <

$d = new DateTime();
echo $d->format("Y-m-d H:i:s.u"); // u : Microseconds

PHP 7.0.0 <7.1

$d = new DateTime();
echo $d->format("Y-m-d H:i:s.v"); // v : Milliseconds 
Sadee
la source
1
En php <7.1, les nouvelles microsecondes de DateTime () sont toujours égales à 0, voir php.net/manual/en/migration71.incompatible.php .
mabi
-2

Utilisez ceci:

function get_millis(){
  list($usec, $sec) = explode(' ', microtime());
  return (int) ((int) $sec * 1000 + ((float) $usec * 1000));
}

Au revoir

MIKEEEEE
la source