php datetime

php date milliseconds



DateTime con microsegundos (6)

En mi código, estoy usando objetos DateTime para manipular fechas, luego convertirlos a marca de tiempo para guardarlos en algunos archivos JSON.

Por algunas razones, quiero tener lo mismo que DateTime (o algo cercano), pero con microsegundos de precisión (que convertiría en flotante al insertarlo dentro de los archivos JSON).

Mi pregunta es: ¿hay un objeto PHP similar a DateTime , pero puede manejar microsegundos también?

El objetivo es poder manipular microtimes con objetos.

En la documentación de date() , hay algo que indica que DateTime se puede crear con microsegundos, pero no pude encontrar cómo.

u Microsegundos (añadido en PHP 5.2.2). Tenga en cuenta que date () siempre generará 000000 ya que toma un parámetro entero, mientras que DateTime :: format () admite microsegundos si DateTime se creó con microsegundos.

He intentado establecer la marca de tiempo de un objeto DateTime con un valor flotante ( microtime(true) ), pero no funciona (creo que convierte la marca de tiempo en un int, causando la pérdida de los microsegundos).

Aquí es cómo lo intenté

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

El .4 no se tiene en cuenta como puede ver aquí (aunque podemos usar el formato u , que corresponde a los microsegundos).

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)

EDITAR: vi este código, que permite agregar microsegundos a un DateTime, pero necesitaría aplicar muchas modificaciones al microtime antes de crear el DateTime. Como lo usaré mucho, quiero hacer las pequeñas modificaciones al microtiempo antes de obtener el "objeto de microtiempo".

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


/! / EDITAR /! /

Ahora uso https://github.com/briannesbitt/Carbon , el resto de esta respuesta está aquí solo por razones históricas.

EDICIÓN FINAL

Decidí extender la clase DateTime usando los consejos que me dieron.

El constructor toma un flotante (de microtime ) o nada (en este caso se inicializará con el "micro-timestamp" actual). También anulé 2 funciones que eran importantes: setTimestamp y getTimestamp .

Desafortunadamente, no pude resolver el problema de las actuaciones, aunque no es tan lento como pensaba.

Aquí está toda la clase:

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


Aquí hay un método muy simple de crear un objeto DateTime que incluye microtime.

No profundicé demasiado en esta pregunta, así que si me perdí algo me disculpo, pero espero que les resulte útil.

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

Lo probé e intenté varias otras formas de hacer que este trabajo pareciera lógico, pero este fue el único método que funcionó. Sin embargo, hubo un problema, estaba devolviendo la parte de la hora correcta pero no la parte del día correcta (debido a la hora UTC más probable) Esto es lo que hice (aún parece más simple, en mi humilde opinión):

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

Aquí hay un ejemplo http://sandbox.onlinephpfunctions.com/code/66f20107d4adf87c90b5c8c914393d4edef180a2 : http://sandbox.onlinephpfunctions.com/code/66f20107d4adf87c90b5c8c914393d4edef180a2

ACTUALIZAR
Como se señaló en los comentarios, a partir de PHP 7.1, el método recomendado por Planplan parece ser superior al que se muestra arriba.

Entonces, nuevamente para PHP 7.1 y versiones posteriores, puede ser mejor usar el siguiente código en lugar de lo anterior:

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

Tenga en cuenta que lo anterior funciona solo para las versiones de PHP 7.1 y superiores. Las versiones anteriores de PHP devolverán 0s en lugar de microtime, por lo tanto, perderán todos los datos de microtime.

Aquí hay una caja de arena actualizada que muestra: http://sandbox.onlinephpfunctions.com/code/a88522835fdad4ae928d023a44b721e392a3295e

NOTA: al probar el recinto de seguridad anterior, nunca vi el fallo de microtiempo (VERDADERO) que Planplan mencionó que experimentó. Sin embargo, el método actualizado parece registrar un mayor nivel de precisión, como sugiere KristopherWindsor.


Hay múltiples opciones. Pero como ya proporcionó Ben, intentaré darle otra solución.

Si proporcionó más detalles sobre qué tipo de cálculos que desea hacer, podría cambiarlos aún más.

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

o

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

o

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

o

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


desde que resolví mi problema, quiero compartirlo contigo. Php71 + tiene una precisión de microsecconds, si desea convertirlo en precisión nano simplemente multiplíquelo por 1000 (10 ^ 3).

$nsTimestamp = (int) (new /DateTime())->getTimestamp() * 1000


Mirando una respuesta en el manual de PHP DateTime :

DateTime no admite segundos divididos (microsegundos o milisegundos, etc.) No sé por qué esto no está documentado. El constructor de la clase los aceptará sin queja, pero se descartan. No parece haber una forma de tomar una cadena como "2012-07-08 11: 14: 15.638276" y almacenarla de forma objetiva de manera completa.

Por lo tanto, no puedes hacer citas de matemáticas en dos cadenas como:

<?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 ) */ ?>

Obtienes 0 cuando realmente quieres obtener 0.251066 segundos.

Sin embargo, tomando una respuesta desde 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>";

Recomendado y usar la clase dateTime() de la referenciada:

$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).

Referencia de dateTime() en php.net: http://php.net/manual/en/datetime.construct.php#


/* * 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; }