2015-11-13 2 views
12

私のコードでは、DateTimeオブジェクトを使用して日付を操作し、タイムスタンプに変換してJSONファイルに保存しています。DateTime with microseconds

いくつかの理由から、私はDateTime(または近いもの)と同じことをしたいと思いますが、マイクロ秒の精度(JSONファイルの内部に挿入するとfloatに変換されます)で精度があります。

私の質問は:DateTimeのようなものですPHPオブジェクトがありますが、あまりにもマイクロを扱うことができますか?

目的は、オブジェクトでミクロタイムを操作できるようにすることです。

ドキュメントには、DateTimeをマイクロ秒で作成できることが示されていますが、方法を見つけることができませんでした。

uマイクロ秒(PHP 5.2.2で追加)。 DateTime :: format()は、DateTimeがマイクロ秒単位で作成された場合は、マイクロ秒をサポートしますが、date()は常に が000000を生成することに注意してください。

(私はそれがマイクロ秒の損失を引き起こし、intにタイムスタンプを変換思う)私は、浮動値(microtime(true))とDateTimeオブジェクトのタイムスタンプを設定しようとしたが、それは動作しません。ここで

は(我々はマイクロ秒に対応u形式を使用することができていても)あなたがここに見ることができるように、私は考慮されない

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

.4

を試みた方法です。

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) 

編集:私は日時にマイクロ秒を追加することができますこのコードを、見ましたが、私はのDateTimeを作成する前に、微小時間への変更の多くを適用する必要があります。私はこれをたくさん使うので、 "ミクロ時間オブジェクト"を取得する前に、可能な限り微小時間を少し変更したいと思っています。

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

あなたの質問はただvaqueになりました。あなたは何を探していますか? – davejal

+0

私は、日付と同じ可能性(比較、書式など)で、マイクロ秒で日付を格納する効率的な方法を探しています。 –

+0

DBに格納しておきます。 – davejal

答えて

2

私はあなたのすべてが私を与えたヒントを使用して、クラスDateTimeを延長することを決めました。

コンストラクタは浮動小数点数(microtime)か何も持たない(この場合、現在の "マイクロタイムスタンプ"で初期化されます)。 重要度の高い2つの関数、つまりsetTimestampgetTimestampもオーバーライドしました。

私は思ったほど遅くはないが、残念ながらパフォーマンスの問題は解決できませんでした。

はここでクラス全体です:

<?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はスプリット秒(マイクロ秒またはミリ秒など)、これは、文書化されていない理由を私は知らない をサポートしていません。 クラスコンストラクターは苦情を受けずに受け取りますが、破棄されます。 「2012-07-08 11:14:15.638276」のような文字列を使用して目的のフォームに完全に格納する方法はありません。

ですから、例えば2つの文字列に日付の計算を行うことはできません。あなたが実際に0.251066秒を取得したいときは、バック0を得る

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

*/ 
?> 


しかし、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>"; 

推奨してからdateTime()クラスを使用し、参照:dateTime()

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

リファレンスphp.net上:http://php.net/manual/en/datetime.construct.php#

+0

このソリューションでは、マイクロタイムを簡単に比較することはできません。マイクロタイムを使用してDateTimeオブジェクトを作成するには、多くのリソースが必要です(私はそれを多く使用します)。 –

1

複数のオプションがあります。しかし、すでにベンによって提供されているように、私はあなたに別の解決策を提供しようとします。

どのような計算をしたいのかについて詳しく説明していれば、さらに変更することができます。

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

または

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

または

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

または

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

ここでのmicrotimeを含んでDateTimeオブジェクトを作成するための非常に簡単な方法があります。

私はこの質問に深く掘り下げませんでした。私が何かを逃した場合、私はお詫びしますが、あなたがこれが役に立つと願っています。

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

論理的に見えるこの作業を行うためにさまざまな方法でテストしましたが、これがうまくいきました。 しかし問題があった、それは (理由はUTC時間の最も可能性が高い)、正しい時刻の部分ではなく、正しい日の部分を返していました。ここ(まだシンプルな私見はそう)私がやったことだ:

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

ここで働いています例:http://sandbox.onlinephpfunctions.com/code/66f20107d4adf87c90b5c8c914393d4edef180a2

+1

まれにmicrotime(true)は整数部分のみを持つ浮動小数点数を返すことができ、 'U.u'形式は失敗します。 これはちょっと醜いですが、これは常にDateTime :: createFromFormat( '0.u00 U'、microtime())で動作します。 – Planplan

+0

@Planplanそれは知る価値がある。しかし、マイクロ秒データの損失は、OPが要求していたものに反するように見えるだろうと思う...? だから私はそれをエラーとしてキャッチしていると思って、あなたが話しているやり方で、おそらく最良の方法でしょう。 – 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; 
    }