2015-11-13 11 views
12

In meinem Code verwende ich DateTime Objekte, um Daten zu manipulieren, dann konvertieren sie in Zeitstempel, um sie in einigen JSON-Dateien zu speichern.DateTime mit Mikrosekunden

Aus einigen Gründen möchte ich das gleiche wie DateTime (oder etwas in der Nähe), aber mit Mikrosekunden Genauigkeit (die ich in Float beim Einfügen in die JSON-Dateien konvertieren würde).

Meine Frage ist: Gibt es ein PHP Objekt, die wie DateTime ist, aber zu Mikrosekunden verarbeiten kann?

Ziel ist es, mit Objekten Mikropunkte manipulieren zu können.

In der Dokumentation gibt es etwas, das angibt, dass DateTime mit Mikrosekunden erstellt werden kann, aber ich konnte nicht finden, wie.

u Mikrosekunden (hinzugefügt in PHP 5.2.2). Beachten Sie, dass date() immer 000000 generiert, da es einen ganzzahligen Parameter benötigt, während DateTime :: format() Mikrosekunden unterstützt, wenn DateTime mit Mikrosekunden erstellt wurde.

Ich habe versucht, den Zeitstempel eines Datetime-Objekt mit einem Floating-Wert (microtime(true)) zu setzen, aber es funktioniert nicht (ich glaube, es den Zeitstempel in einen int konvertiert, um den Verlust der Mikrosekunden verursacht).

Hier ist, wie ich

versucht
$dt = new DateTime(); 
$dt->setTimestamp(3.4); // I replaced 3.4 by microtime(true), this is just to give an example 
var_dump($dt); 
var_dump($dt->format('u')); 

Die .4 wird nicht berücksichtigt, wie man hier sehen kann (auch wenn wir die u Format verwenden können, die den Mikrosekunden entspricht).

object(DateTime)[1] 
    public 'date' => string '1970-01-01 01:00:03' (length=19) 
    public 'timezone_type' => int 3 
    public 'timezone' => string 'Europe/Berlin' (length=13) 

string '000000' (length=6) 

EDIT: ich diesen Code sah, die Mikrosekunden zu einem DateTime- hinzufügen können, aber ich würde eine Menge Änderungen an der Mikrozeit anwenden müssen, bevor Sie die Datetime zu schaffen. Da ich das sehr oft verwenden werde, möchte ich so wenig wie möglich an der Mikrozeit ändern, bevor ich das "Mikrozeitobjekt" bekomme.

$d = new DateTime("15-07-2014 18:30:00.111111"); 
+0

Ihre Frage wurde gerade vaque, wonach suchen Sie? – davejal

+0

Ich suche nach einer effizienten Möglichkeit, Daten in Mikrosekunden zu speichern, mit den gleichen Möglichkeiten (Vergleich, Formatierung usw.) wie eine DateTime. –

+0

speichern sie in einer db ich nehme an, welche? – davejal

Antwort

2

Ich beschloss, die Klasse DateTime mit den Tipps zu verlängern Sie alle mir gab.

Der Konstruktor nimmt einen Float (von microtime) oder nichts (in diesem Fall wird er mit dem aktuellen "Mikro-Timestamp" initialisiert). Ich übersteuerte auch 2 Funktionen, die wichtig waren: setTimestamp und getTimestamp.

Leider konnte ich das Performance-Problem nicht lösen, obwohl es nicht so langsam ist, wie ich dachte.

Hier ist die ganze Klasse:

<?php 
class MicroDateTime extends DateTime 
{ 
    public $microseconds = 0; 

    public function __construct($time = 'now') 
    { 
     if ($time == 'now') 
      $time = microtime(true); 

     if (is_float($time + 0)) // "+ 0" implicitly converts $time to a numeric value 
     { 
      list($ts, $ms) = explode('.', $time); 
      parent::__construct(date('Y-m-d H:i:s.', $ts).$ms); 
      $this->microseconds = $time - (int)$time; 
     } 
     else 
      throw new Exception('Incorrect value for time "'.print_r($time, true).'"'); 
    } 

    public function setTimestamp($timestamp) 
    { 
     parent::setTimestamp($timestamp); 
     $this->microseconds = $timestamp - (int)$timestamp; 
    } 

    public function getTimestamp() 
    { 
     return parent::getTimestamp() + $this->microseconds; 
    } 
} 
3

Looking at a response on the PHP DateTime manual:

Datetime nicht Sekundenbruchteilen (Mikrosekunden oder Millisekunden usw.) unterstützen Ich weiß nicht, warum dies nicht dokumentiert ist. Der Klassenkonstruktor akzeptiert sie ohne Beanstandung, aber sie werden verworfen. Es scheint keinen Weg zu geben, eine Zeichenkette wie "2012-07-08 11: 14: 15.638276" zu nehmen und sie vollständig in einer objektiven Form zu speichern.

So können Sie nicht Datum tun Mathe auf zwei Saiten, wie:

<?php 
$d1=new DateTime("2012-07-08 11:14:15.638276"); 
$d2=new DateTime("2012-07-08 11:14:15.889342"); 
$diff=$d2->diff($d1); 
print_r($diff) ; 

/* returns: 

DateInterval Object 
(
    [y] => 0 
    [m] => 0 
    [d] => 0 
    [h] => 0 
    [i] => 0 
    [s] => 0 
    [invert] => 0 
    [days] => 0 
) 

*/ 
?> 

Sie zurück 0, wenn Sie tatsächlich 0,251066 Sekunden erhalten möchten.


jedoch nehmen eine Antwort von here:

$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>"; 

empfohlen und verwenden dateTime() Klasse von verwiesen:

$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 "u" is microseconds (1 seconds = 1000000 µs). 

Referenz von dateTime() auf php.net: http://php.net/manual/en/datetime.construct.php#

+0

Mit dieser Lösung kann ich nicht leicht Mikrozeiträumen vergleichen, und das Erstellen eines DateTime-Objekts mit Mikrozeit braucht eine Menge Ressourcen (ich werde es eine Menge verwenden). –

1

Es gibt mehrere Optionen. Aber wie bereits von Ben vorgeschlagen, werde ich versuchen, dir eine andere Lösung zu geben.

Wenn Sie weitere Details zu den von Ihnen gewünschten Berechnungen angeben, könnte dies noch weiter geändert werden.

$time =microtime(true); 
$micro_time=sprintf("%06d",($time - floor($time)) * 1000000); 
$date=new DateTime(date('Y-m-d H:i:s.'.$micro_time,$time)); 
print "Date with microseconds :<br> ".$date->format("Y-m-d H:i:s.u"); 

oder

$time =microtime(true); 
var_dump($time); 

$micro_time=sprintf("%06d",($time - floor($time)) * 1000000); 
$date=new DateTime(date('Y-m-d H:i:s.'.$micro_time,$time)); 
print "Date with microseconds :<br> ".$date->format("Y-m-d H:i:s.u"); 

oder

list($ts,$ms) = explode(".",microtime(true)); 
$dt = new DateTime(date("Y-m-d H:i:s.",$ts).$ms); 
echo $dt->format("Y-m-d H:i:s.u"); 

oder

list($usec, $sec) = explode(' ', microtime()); 
print date('Y-m-d H:i:s', $sec) . $usec; 
10

Hier ist ein sehr einfaches Verfahren zur Herstellung eines Datetime-Objekt erstellen, die micro enthält.

Ich habe mich nicht zu tief in diese Frage vertieft, also wenn ich etwas verpasst habe entschuldige ich mich, hoffe aber, dass Sie das hilfreich finden.

Ich testete es aus und versuchte verschiedene andere Möglichkeiten, um diese Arbeit zu machen, die logisch schien, aber das war die einzige Methode, die funktionierte. Allerdings gibt es ein Problem war, es war die richtige Zeitabschnitt zurückkehrt aber nicht der richtige Tag Teil (wegen der UTC-Zeit höchstwahrscheinlich) Hier ist, was ich getan habe (scheint noch einfacher IMHO):

$dateObj = DateTime::createFromFormat('U.u', microtime(TRUE)); 
$dateObj->setTimeZone(new DateTimeZone('America/Denver')); 
var_dump($dateObj->format('Y-m-d H:i:s:u')); 

Hier ist ein Arbeits Beispiel: http://sandbox.onlinephpfunctions.com/code/66f20107d4adf87c90b5c8c914393d4edef180a2

+1

In seltenen Fällen kann microtime (true) einen Float mit nur einem ganzzahligen Teil zurückgeben, wodurch das Format "U.u" fehlschlägt. Das ist ein bisschen hässlich, aber das wird immer mit DateTime :: createFromFormat funktionieren ('0.u00 U', microtime()); – Planplan

+0

@Planplan Das ist es wert zu wissen. Ich denke jedoch, dass der Verlust von Mikrosekunden-Daten dem, was der OP gefordert hat, widersprechen würde ...? Also vermute ich, dass ich es als Fehler aufgefasst habe, dann wäre es wahrscheinlich der beste Weg, es so zu machen, wie Sie es nennen. – MER

0
/* 
* More or less standard complete example. Tested. 
*/ 
    private static function utime($format, $utime = null, $timezone = null) { 
    if(!$utime) { 
     // microtime(true) had too fiew digits of microsecconds 
     $time_arr = explode(" ", microtime(false)); 
     $utime = $time_arr[1] . substr($time_arr[0], 1, 7); 
    } 
    if(!$timezone) { 
     $timezone = date_default_timezone_get(); 
    } 
    $date_time_zone = timezone_open($timezone); 
    //date_create_from_format("U.u", $utime) - had a bug with 3-rd parameter 
    $date_time = date_create_from_format("U.u", $utime); 
    date_timezone_set($date_time, $date_time_zone); 
    $timestr = date_format($date_time, $format); 
    return $timestr; 
    }