mdY H: i: su tarih formatını milisaniyeden alıyor


117

Milisaniyeden itibaren mikrosaniyeler dahil olmak üzere biçimlendirilmiş bir tarih almaya çalışıyorum.

Tek sorun, sürekli olarak 000000 almam

date("m-d-Y H:i:s.u", $milliseconds/1000);

ex. 07-28-2013 11: 26: 14.000000


6
Sorunun milisaniyeleri dönüştürmeyi istemesi tuhaf , ancak herkes mikrosaniyelerin nasıl dönüştürüleceğini yanıtlıyor. İkisi arasında dönüşüm yapabileceğinizi biliyorum, ancak PHP belgesinden veya başka bir yerden ilgisiz kodu kopyalayıp yapıştırmak yerine soruyu cevaplamak güzel olurdu.
laurent

Bir süredir biliyorum ama bamossza'nın cevabı burada bulduğum en
iyisiydi

Yanıtlar:


122

php.net diyor ki:

Mikrosaniyeler (PHP 5.2.2'de eklenmiştir). Not date()hep üretecektir 000000bir tamsayı parametre alır çünkü, oysa DateTime::format()eğer destek mikrosaniye yapar DateTimemikrosaniye ile oluşturuldu.

Bu yüzden basit kullanın:

$micro_date = microtime();
$date_array = explode(" ",$micro_date);
$date = date("Y-m-d H:i:s",$date_array[1]);
echo "Date: $date:" . $date_array[0]."<br>";

Önerilen ve dateTime()referanslardan sınıf kullanın :

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

print $d->format("Y-m-d H:i:s.u"); // note at point on "u"

Not umikrosaniyedir (1 saniye = 1000000 µs).

Php.net'ten başka bir örnek :

$d2=new DateTime("2012-07-08 11:14:15.889342");

Referans dateTime()üzerinde php.net

Soruyu kısa ve yazar için basitleştirerek cevapladım. Lütfen yazara daha fazla bilgi için bakın : milisaniyeden itibaren tarih formatı mdY H: i: su alma


4
Okumak ve anlamak daha kolay olduğu için genellikle ikinci formu tercih ederim. Ek olarak, DateTime, tarih / saat işlevlerinden çok daha esnek ve sağlamdır. Mikrosaniyelerin işlenmesi bir durumdur.
Herbert

3
@Geo ve AlBundy bunu php <5.2.2 olan bir makinede deniyor musunuz? PHP 5.4.39 bunu mükemmel şekilde çalıştırır ...
RichardBernards

bu kolay olmaz mıydı? tarih ('mdY H: i: s'). (int) mikrotime (doğru);
Anant

@Anant, gerçekten çok kolay olurdu. Ama yanlış. ;) Orada elde ettiğiniz şey sadece saniyeler içinde çağdır. (Ne yazık ki microtime(false)
ikisiyle

Bu kod tüm yerel ayarlarda düzgün çalışmıyor. Almanya gibi bazı ülkeler ".1234" yerine "0,1234" veya "0.1234" yazıyor, bu nedenle kodunuz benim için şu çıktıyı veriyor: 2012-07-08 11:14:15.0.889342
Daniel Marschall

138

Bunu giriş formatıyla kolayca yapabilirsiniz U.u.

$now = DateTime::createFromFormat('U.u', microtime(true));
echo $now->format("m-d-Y H:i:s.u");

Bu, aşağıdaki çıktıyı üretir:

04-13-2015 05:56:22.082300

Tarih formatları için PHP kılavuz sayfasından:

  • U = Unix Döneminden beri geçen saniye sayısı
  • u = Mikrosaniye

http://php.net/manual/en/function.date.php


Orijinal cevabımdaki bir kusuru işaret ettiği için teşekkürler giggsey'e gidiyor, satıra eklemek number_format()tam saniye durumunu düzeltmeli. Ne yazık ki artık o kadar zarif hissetmiyor ...

$now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));

http://php.net/manual/en/function.number-format.php


DaVe'ye yanıt olarak saat dilimlerine ilişkin bir not.

Normalde, createFromFormat()yöntem belirtilmezse yerel saat dilimini kullanır.

http://php.net/manual/en/datetime.createfromformat.php

Bununla birlikte, burada açıklanan teknik microtime(), Unix Epoch'tan (01 Ocak 1970 00:00:00 GMT) bu yana geçen saniye sayısını döndüren DateTime nesnesini başlatmaktadır .

http://php.net/manual/en/function.microtime.php

Bu, DateTime nesnesinin örtük olarak UTC'ye başlatıldığı anlamına gelir; bu, yalnızca geçen zamanı izlemek isteyen dahili sunucu görevleri için uygundur.

Belirli bir saat dilimi için saati görüntülemeniz gerekiyorsa, buna göre ayarlamanız gerekir. Bununla birlikte, bu başlatma sonra ayrı bir adım olarak yapılmalıdır ( olup üçüncü parametre kullanılarak createFromFormat()yukarıda ele alındığı nedenlerden dolayı).

setTimeZone()Yöntem, bu gereksinimi gerçekleştirmek için kullanılabilir.

http://php.net/manual/en/datetime.settimezone.php

Örnek olarak:

$now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));
echo $now->format("m-d-Y H:i:s.u") . '<br>';

$local = $now->setTimeZone(new DateTimeZone('Australia/Canberra'));
echo $local->format("m-d-Y H:i:s.u") . '<br>';

Aşağıdaki çıktıyı üretir:

10-29-2015 00:40:09.433818
10-29-2015 11:40:09.433818

Mysql'ye giriş yapmak istiyorsanız, saat formatının şöyle olması gerektiğini unutmayın:

format("Y-m-d H:i:s.u")

19
Not: Tam saniyede çalıştırılırsa DateTime::createFromFormat('U.u', microtime(true));yanlış döndürür microtime(true). "1438616239.000000" yerine "1438616239" döndürür.
giggsey

1
Harika çözüm, teşekkürler. Görünüşe göre yerel saatimi mikro zamandan itibaren $ şimdi oluştururken kaybediyorum. Herhangi bir fikir?
Dave

1
@daVe Saat dilimleri hakkında bazı bilgiler ekledim, umarım peşinde olduğun şey budur.
ArchCodeMonkey

1
number_formatO kesin saniye değilken bile, her zaman gereklidir. Aksi takdirde precisionPHP 7.0'dan itibaren varsayılan olarak yeterince yüksek olmayan (mikrosaniyeye kadar doğru değil) PHP yapılandırma seçeneğinin insafına kalırsınız .
Teoh Han Hui

1
StackOverflow'da her zaman aşağı kaydırın
tom10271

15

İşte biraz daha kısa bir yaklaşım. Yüksek hassasiyetli sayısal bir tarih / saat oluşturmak için çalışmak yerine, mikrosaniye değerini bir dizeye dönüştürür, kaldırır 0ve tarih / saat dizesinin sonuna eklerim. Dize uzunluğu parametresini ayarlayarak ondalık sayıları kolayca kırpabilirim; burada 4milisaniye almak için kullanıyorum , ancak 7mikrosaniye almak için kullanabilirsiniz .

$t = explode(" ",microtime());
echo date("m-d-y H:i:s",$t[1]).substr((string)$t[0],1,4);

Bir mikrotime () değeri için 0.98236000 1407400573bu döndürülür 08-07-14 01:08:13.982.


9

Ben kullanıyorum

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

output: 2017-09-05 17:04:57.555036

6
echo date('m-d-Y H:i:s').substr(fmod(microtime(true), 1), 1);

örnek çıktı:

02-06-2019 16:45:03.53811192512512

Ondalık basamak sayısını sınırlamanız gerekiyorsa, aşağıdaki satır (kredi mgutt) iyi bir alternatif olacaktır. (Aşağıdaki kodla 6, ondalık basamak sayısını 6 ile sınırlar.)

echo date('m-d-Y H:i:').sprintf('%09.6f', date('s')+fmod(microtime(true), 1));

örnek çıktı:

02-11-2019 15:33:03.624493

Hassasiyeti ve öndeki sıfırı saniyeler boyunca kaçırdınız. Yani doğru sürüm olmalıdır echo date('m-d-Y H:i:').sprintf('%09.6f', date('s')+fmod(microtime(true), 1));. Neden ihtiyacımız olduğunun açıklaması 09: stackoverflow.com/a/28739819/318765
mgutt

Hassasiyeti yine kaçırdınız;)echo date('H:i:s').substr(fmod(microtime(true), 1), 1, 7);
mgutt

Ama dikkat et, substr()yuvarlanmıyor. Ve onunla birleştiğinde round(), sondaki sıfırları keserdi : stackoverflow.com/questions/7493305/… Teklif etmemin nedeni buydu sprintf().
mgutt

@mgutt İlk rakam ne zaman sıfır olmaz? Temelde ihtiyaç duyulan şey basitçe, geri kalanı fmod'dan 1'e alırken her zaman orada olan sıfırı kaldırmaktır. Soru mikrosaniyeleri sorar, ancak saniyelerin ondalık basamakları şeklinde. Ondalık basamak sayısını sınırlamak için hiçbir neden yoktur. Daha fazla ondalık basamak daha iyi hassasiyettir.
ghbarratt

@mgutt, gerekirse ondalık basamak sayısını sınırlamanın iyi bir yolu olacağını açıklayarak, cevabıma önerilen ilk alternatifinizi ekledim
ghbarratt

3

JavaScript gibi bir tarihi (new Date()).toISOString()herhangi bir nedenle biçimlendirmek istiyorsanız, bunu PHP'de şu şekilde yapabilirsiniz:

$now = microtime(true);
gmdate('Y-m-d\TH:i:s', $now).sprintf('.%03dZ',round(($now-floor($now))*1000));

Örnek çıktı:

2016-04-27T18:25:56.696Z

Sadece tam sayıyı çıkarmanın ondalık bölümün doğruluğunu azaltmadığını kanıtlamak için:

>>> number_format(123.01234567890123456789,25)
=> "123.0123456789012408307826263"
>>> number_format(123.01234567890123456789-123,25)
=> "0.0123456789012408307826263"

PHP yaptığı ondalık basamağa yuvarlak, ama onlara her iki durumda da aynı şekilde yuvarlanır.


1
Hayır. Kayan nokta numarasında matematik kullanmayın, bu yanlış. Ayrıca birkaç işlevi arayarak zaman kaybetmeyin. Biçimlendirilmiş tarihi üç ondalık basamağa indirmek için substr () kullanın.
LS

@LS Kesmek, muhtemelen daha da yanlış olan 3. ondalık sayıyı yuvarlamaz. Siz gerçekten çok küçük hassasiyetler elde edene kadar yüzer parçalar bozulmaz; 3 ondalık basamak iyi olmalıdır. Aslında, hassasiyeti hiç değiştirdiğimi sanmıyorum, kayan değerler siz 0'a yaklaştıkça daha doğru olur. Tam sayıyı çıkarmak AFAIK'in ondalık basamaklarını değiştirmemelidir.
mpen

Peki ya date('Y-m-d\TH:i:s', $time / 1000) . sprintf('.%03dZ', substr($time, 10));?
F8ER

@ F8ER Eğer $timezaten milisaniye içinde ise, evet, teknik olarak işe yarayacaktır. Sevmiyor musun substrhack, ama 2001 ve 2286. arasındaki tarihlerde çalışacak tahmin
mpen

Evet, $timeMS, ama peki ya 2286, neden böyle düşünüyorum ve bundan kaçmak nasıl mümkün olabilir?
F8ER

3

Bu, ArchCodeMonkey'in yanıtına dayanmaktadır.

Ancak hızlı bir şekilde çalışan bir şey istiyorsanız, sadece basitleştirilmiştir.

function DateTime_us_utc(){
    return DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));
}
function DateTime_us(){
    $now = DateTime_us_utc();
    return $now->setTimeZone(new DateTimeZone(date_default_timezone_get()));
}

O zaman benim için

$now = DateTime_us();
$now->format("m-d-Y H:i:s.u");

3

İşte biraz daha zarif / basit bulduğum başka bir yöntem:

echo date('Y-m-d-H:i:s.').preg_replace("/^.*\./i","", microtime(true));

2

PHP 7.1'den itibaren şunu yapabilirsiniz:

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

Şu şekilde görüntülenecektir:

04-11-2018 10:54:01.321688

1
// Procedural
$fineStamp = date('Y-m-d\TH:i:s') . substr(microtime(), 1, 9);
echo $fineStamp . PHP_EOL;

// Object-oriented (if you must). Still relies on $fineStamp though :-\
$d = new DateTime($fineStamp);
echo $d->format('Y-m-d\TH:i:s.u') . PHP_EOL;

0

Belgeler şunları söylüyor:

Mikrosaniyeler (PHP 5.2.2'de eklenmiştir). DateTime :: format () mikrosaniyeleri desteklerken, bir tamsayı parametresi aldığından date () her zaman 000000 oluşturacaktır.

Yani, bunun yerine DateTime kullanın.


6
Bu çalışmıyor! date_format (new DateTime (), 'u') sıfır verir: phpfiddle.org/lite/code/ggh-mvz
Jānis Elmeris

Evet, yukarıdaki cevaba göre (ve denemelerim) new DateTime()de u için 0000 döndürecektir. Ancak, örneğini oluştururken ona mikrosaniye doğruluk süresi sağlarsanız, sorunsuz çalışır.
scipilot

@scipilot tamam, peki bunu nasıl yapıyorsun?
Coğrafi

@Geo kabul edilen cevaba bakın. new DateTime( 'Y-m-d H:i:s.'.$micro);
scipilot

0

PHP 7.0+ ile şimdi burada şunları yapabilirsiniz:

$dateString = substr($millseconds_go_here,0,10);
$drawDate = new \DateTime(Date('Y-m-d H:i',$dateString));
$drawDate->setTimezone(new \DateTimeZone('UTC'));

Bu, sırayla aşağıdakileri yapar:

  1. Date()Tarihi işleyebilmek için dizeden son 4 sıfırı kırpar .
  2. Tarihi, milisaniyeleri, DateTime'ın anlayabileceği bir tarih saat dizesine biçimlendirmek için kullanır.
  3. DateTime()daha sonra bulunduğunuz saat dilimini değiştirmenize izin verebilir, ancak işlevleri ve sınıfları date_default_timezone_set("Timezone");kullanmadan önce bunun ayarlandığından emin olun DateTime().
  4. DateTime()Sınıflar veya işlevler kullanıldığında doğru zaman diliminde olduğunuzdan emin olmak için sınıflarınızda bir kurucu kullanmak iyi bir uygulamadır .

0

Carbon kullanıyorsanız "RFC3339_EXTENDED" tanımlı spesifikasyonu kullanabilirsiniz. veya özelleştirin.

Carbon::RFC3339_EXTENDED = 'Y-m-d\TH:i:s.vP';

0

@ArchCodeMonkey cevabına göre.

Eğer varsa, declare(strict_types=1)dizeye ikinci argüman atmalısınız.

görüntü açıklamasını buraya girin


0

Birkaç farklı şekilde yedekledim:

1) mikro zaman + sscanf + tarih:

sscanf(microtime(), '0.%6s00 %s', $usec, $sec);
$date = date('Y-m-d H:i:s.', $sec) . $usec;

Mikrotime () 'nin mikrosaniye bölümü için neden 10 karakter (0.dddddd00) döndürdüğünden emin değilim ama belki birisi bana söyleyebilir?

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { sscanf(microtime(), '0.%6s00 %s', $usec, $sec); $date = date('Y-m-d H:i:s.', $sec) . $usec; } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "22372.335910797 ms" // macOS PHP 5.6.30
string(18) "16772.964000702 ms" // Linux PHP 5.4.16
string(18) "10382.229089737 ms" // Linux PHP 7.3.11 (same linux box as above)

2) DateTime :: createFromFormat + Datetime-> format:

$now = new DateTime('NOW');
$date = $now->format('Y-m-d H:i:s.u');

PHP 5.x'te çalışmıyor ...

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { $now = new DateTime('NOW'); $date = $now->format('Y-m-d H:i:s.u'); } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "45801.825046539 ms" // macOS PHP 5.6.30 (ms not working)
string(18) "21180.155038834 ms" // Linux PHP 5.4.16 (ms not working)
string(18) "11879.796028137 ms" // Linux PHP 7.3.11 (same linux box as above)

3) gettimeofday + tarih:

$time = gettimeofday();
$date = date('Y-m-d H:i:s.', $time['sec']) . $time['usec'];

-

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { $time = gettimeofday(); $date = date('Y-m-d H:i:s.', $time['sec']) . $time['usec']; } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "23706.788063049 ms" // macOS PHP 5.6.30
string(18) "14984.534025192 ms" // Linux PHP 5.4.16
string(18) "7799.1390228271 ms" // Linux PHP 7.3.11 (same linux box as above)

4) mikrotime + sayı_formatı + DateTime :: createFromFormat + DateTime-> format:

$now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));
$date = $now->format('Y-m-d H:i:s.u');

-

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { $now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', '')); $date = $now->format('Y-m-d H:i:s.u'); } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "83326.496124268 ms" // macOS PHP 5.6.30
string(18) "61982.603788376 ms" // Linux PHP 5.4.16
string(16) "19107.1870327 ms" // Linux PHP 7.3.11 (same linux box as above)

5) microtime + sprintf + DateTime :: createFromFormat + DateTime-> format:

$now = DateTime::createFromFormat('U.u', sprintf('%.6f', microtime(true)));
$date = $now->format('Y-m-d H:i:s.u');

-

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { $now = DateTime::createFromFormat('U.u', sprintf('%.6f', microtime(true))); $date = $now->format('Y-m-d H:i:s.u'); } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "79387.331962585 ms" // macOS PHP 5.6.30
string(18) "60734.437942505 ms" // Linux PHP 5.4.16
string(18) "18594.941139221 ms" // Linux PHP 7.3.11 (same linux box as above)
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.