PHP'de milisaniye olarak şimdiki zaman nasıl alınır?


Yanıtlar:


506

Kısa cevap ise:

$milliseconds = round(microtime(true) * 1000);

26
@FredrikWendt, sanırım kafa karıştırıyorsunuz time(). microtime(true)Öte yandan, Unix döneminin en yakın mikrosaniyeye kadar doğru olduğundan, saniye cinsinden geçerli saati döndürür (bkz. PHP referansı). Yukarıdaki kodu bir döngüde çalıştırıp milisaniyeyi görüntülemenizi test etmek aslında çok kolaydır.
laurent

6
Kesinlikle yaptım! :-)
Fredrik Wendt

10
Kısa cevabı seviyorum.
Erick Robertson

9
Bu olmamalı mı microtime(true) / 1000(çoklu uygulama yerine bölünme)?
Jordan Lev

18
@JordanLev, bu çarpma olmalıdır çünkü mikrotime (true) Unix zaman damgasını bir kayan nokta olarak saniye cinsinden döndürür .
laurent

88

Kullanın microtime. Bu işlev boşlukla ayrılmış bir dize döndürür. İlk kısım saniyenin kesirli kısmı, ikinci kısım ayrılmaz kısımdır. Aktarın truesayı olarak almak için:

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

Kullanıyorsanız hassas kayıplara dikkat edin microtime(true).

gettimeofdayMikrosaniye kısmını bir tamsayı olarak döndüren de vardır.

var_dump(gettimeofday());
/*
array(4) {
  ["sec"]=>
  int(1283846202)
  ["usec"]=>
  int(891199)
  ["minuteswest"]=>
  int(-60)
  ["dsttime"]=>
  int(1)
}
*/

Genel olarak konuşmak microtime()eşittir 1000*time(), değil mi?
Comer

Görüyorum ki, hatalar olabilir, ama hata daha küçük olmalı 1000, değil mi?
Comer

@COMer: Hangi varyanttan bahsediyorsun?
kennytm

microtime(true)ve1000*time()
Comer

@COMer: 1000*time()size milisaniye vermeyecektir. 14 basamak hassasiyetli microtime(true)bir a döndürür float. Saniye kısmı zaten 10 aldı, böylece mikrosaniye kısmı için 4 basamak bıraktı. Milisaniye sadece 3 ekstra basamak gerektirdiğinden bu yeterli olmalıdır.
kennytm

46

Kısa cevap:

Sadece 64 bit platformlar!

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

[ Eğer 64 bit PHP çalıştırıyorsanız o zaman sabit PHP_INT_SIZEeşittir8 ]


Uzun cevap:

time()Önce milisaniye cinsinden eşdeğer bir işlev istiyorsanız time(), "dönem" (01/01/1970) tarihinden bu yana geçen saniye sayısını döndürürken, "dönem" den bu yana geçen milisaniye sayısının büyük bir sayı olduğunu düşünmeniz gerekir. ve 32 bitlik bir tamsayıya sığmaz.

PHP'de bir tamsayı boyutu platforma bağlı olarak 32 veya 64 bit olabilir.

Gönderen http://php.net/manual/en/language.types.integer.php

Bir tamsayının boyutu platforma bağlıdır, ancak yaklaşık iki milyarlık bir maksimum değer normal değerdir (32 bit imzalı). 64 bit platformlar, genellikle her zaman 32 bit olan Windows hariç maksimum 9E18 değerine sahiptir. PHP imzasız tam sayıları desteklemez. Tamsayı boyutu, PHP_.0_SIZE sabiti kullanılarak ve PHP 4.4.0 ve PHP 5.0.5'ten beri PHP_INT_MAX sabiti kullanılarak maksimum değer ile belirlenebilir.

64 bit tamsayılarınız varsa, aşağıdaki işlevi kullanabilirsiniz:

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

microtime() boşluk ile ayrılmış iki sayı ile mikrosaniye kadar hassasiyetle, "dönem zaman" beri saniye sayısını döndürür ...

0.90441300 1409263371

İkinci sayı saniye (tamsayı), birincisi ondalık kısımdır.

Yukarıdaki fonksiyon milliseconds()tamsayı kısmı ile çarpılır1000

1409263371000

sonra ondalık kısmı 1000ile 0 ondalık sayı ile çarpılır ve yuvarlanır

1409263371904

Her ikisinin $mt[1]ve sonucunun yayınlandığına dikkat roundedin int. Bu gereklidir, çünkü bunlar floatve döküm yapmadan yapılan işlemler işlevin geri dönmesine neden olacaktır float.

Son olarak, bu işlev biraz daha hassastır.

round(microtime(true)*1000);

1:10 (yaklaşık) oranıyla doğru sonuçtan 1 milisaniye daha fazla sonuç verir. Bu, şamandıra tipinin sınırlı hassasiyetinden kaynaklanmaktadır ( microtime(true)bir şamandıra döndürür). Yine de daha kısa tercih ederseniz sonuca round(microtime(true)*1000);döküm öneririm int.


Sorunun kapsamı dışında olsa bile, platformunuz 64 bit tamsayıları destekliyorsa , taşmaya maruz kalmadan geçerli süreyi mikrosaniye olarak alabileceğinizi belirtmek gerekir .

Eğer gerçek 2^63 - 1(en büyük işaretli tamsayı) bölünürse 10^6 * 3600 * 24 * 365(yaklaşık bir yılda mikrosaniye) verir 292471.

Bu elde ettiğiniz değerle aynı

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

Başka bir deyişle, imzalı bir 64 bit tamsayı mikrosaniye cinsinden ölçülen 200.000 yıldan fazla bir zaman aralığını depolamak için alana sahiptir.

O zaman sahip olabilirsiniz

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

neden sadece: `` getMilliEpoch () işlevi {$ mt = explode ('', microtime ()); dönüş $ mt [1]. substr (mt [0], 0,5) * 1000; } '
Michael

Şimdi mikro zamanı fonksiyonu için bir parametre var, eğer true olarak ayarlanmışsa, 1 Ocak 1970'den bu yana saniye ve milisaniyeyi döndürür, 0 saat 0 dakika 0 saniye yüzer. İşte bir örnek: microtime (true) // 1553260455.7242
kukko

@kukko evet, ancak şamandıra türünün sınırlı hassasiyeti nedeniyle , mikro saatten (gerçek) milisaniye sayısını hesaplamak biraz yanlış bir değerle
Paolo

42

Diğerlerinin belirttiği gibi, microtime()zaman damgalarında milisaniye hassasiyet elde etmek için kullanabilirsiniz .

Yorumlarınızdan, yüksek hassasiyetli UNIX Zaman Damgası olarak görünmesini istersiniz. Gibi bir şey DateTime.Now.Ticks.NET dünyada.

Bunu yapmak için aşağıdaki işlevi kullanabilirsiniz:

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);
}

Bunu yapmanın yolu!
tonix

1
perrrrrrfect .. ♥.
SRB,

Sunucu zamanını döndürmüyor mu? Benim durumumda db'de saklanan sürenin yerel tarayıcı zamanım olduğunu görüyorum. Diyelim ki, sever zaman dilimim EST + 3 ve tarayıcı zamanım GMT + 6, GMT + 6 konumundan bir form gönderirken, depolanan sürenin GMT + 6 kez eşdeğer milisaniye olduğunu görüyorum. Peki, sorun nedir? :(
Zenith

12

microtime(true)PHP 5 veya PHP 4'te aşağıdaki değişiklikleri kullanın :

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

Bu kodu yazmanın taşınabilir bir yolu:

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

    return microtime(true);
}

11

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

çıktı:

2016-11-19 15:12:34.346351


1
Bu aynı zaman damgasını kullanır:$t = gettimeofday(); echo date('Y-m-d H:i:s.',$t['sec']) . $t['usec'];
Savvas Radevic

mikrosaniye sıfır dolgulu olmalıdır:$timeofday=gettimeofday(); echo sprintf("%s.%06d", date('Y-m-d H:i:s', $timeofday['sec']), $timeofday['usec']);
mabi

7

bunu dene:

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"); 
}

6

Bu, 32 bit PHP'de olsanız bile çalışır:

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

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

Bunun size tamsayılar değil, dizeler verdiğini unutmayın. Ancak, çoğu durumda, örneğin REST istekleri için URL oluştururken bu işe yarar.


Tamsayılara ihtiyacınız varsa, 64 bit PHP zorunludur.

Sonra yukarıdaki kodu yeniden kullanabilir ve (int) 'e yayınlayabilirsiniz:

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

Veya iyi ol 'tek gömleklerini kullanabilirsiniz:

$time_milli = (int) round(microtime(true) * 1000);    // 1491536422147
$time_micro = (int) round(microtime(true) * 1000000); // 1491536422147300

5
$timeparts = explode(" ",microtime());
$currenttime = bcadd(($timeparts[0]*1000),bcmul($timeparts[1],1000));
echo $currenttime;

NOT: Bu işlev için microtime () ile yapılan geliştirmeler nedeniyle PHP5 gereklidir ve bc math modülü de gereklidir (büyük sayılarla uğraştığımız için, modülün phpinfo'da olup olmadığını kontrol edebilirsiniz).

Umarım bu yardımcı olur.


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);

Bu aslında sağa üç sıfır doldurmak gibi mi?
Zeeshan

Bir şey değil. Her iki parçayı milisaniyeye dönüştürür ve toplamı verir. Yani sıfır eklemekten daha doğrudur.
user3767296

1
Bu kod snippet'i soruyu çözebilir, ancak bir açıklama da dahil olmak üzere , yayınınızın kalitesini artırmaya yardımcı olur. Gelecekte okuyucular için soruyu cevapladığınızı ve bu kişilerin kod önerinizin nedenlerini bilmeyebileceğini unutmayın. Lütfen kodunuzu açıklayıcı yorumlarla doldurmamaya çalışın, bu hem kodun hem de açıklamaların okunabilirliğini azaltır!
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 

1
Php <7.1'de yeni DateTime () mikrosaniyeleri her zaman 0'dır, bkz. Php.net/manual/en/migration71.incompatible.php .
mabi

-2

Bunu kullan:

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

Hoşçakal

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.