tl;dr。 microtime(false)を使用して、結果をMySQLbigintに100万分の1秒として保存します。それ以外の場合は、大きな太った毛玉である浮動小数点演算についてすべてを学ぶ必要があります。
PHP microtime関数は、あるシステムコールからUnixタイムスタンプ(現在は約16進数の50eb7c00または10進数の1,357,609,984)を取得し、別のシステムコールからマイクロ秒の時間を取得します。次に、それらを文字列にします。次に、(true)で呼び出すと、その数値が64ビットIEEE 745浮動小数点数に変換されます。これは、PHPがfloat
と呼ぶものです。 。
今日の時点で、整数のUNIXタイムスタンプを格納するには、小数点の左側に10桁の10進数が必要です。これは、子孫が11桁を必要とし始める西暦2280年頃まで当てはまります。マイクロ秒を格納するには、小数点以下6桁が必要です。
合計マイクロ秒の精度は得られません。ほとんどのシステムは、1〜33ミリ秒の範囲の解像度で1秒未満のシステムクロックを維持します。システムに依存します。
MySQLバージョン5.6.4以降では、DATETIME(6)
を指定できます 日付と時刻をマイクロ秒の解像度で保持する列。このようなMySQLバージョンを使用している場合は、絶対にその方法です。
バージョン5.6.4より前では、MySQL DOUBLE
を使用する必要があります (IEEE 754 64ビット浮動小数点)これらの数値を格納します。 MySQL FLOAT
(IEEE 754 32ビット浮動小数点)仮数には、現在のUNIX時間を秒単位で完全に正確に格納するのに十分なビットがありません。
なぜこれらのタイムスタンプを保存するのですか?やりたいですか
WHERE table.timestamp = 1357609984.100000
または特定のアイテムを検索するための同様のクエリ?処理チェーンのどこかでfloatまたはdoubleの数値を使用する場合(つまり、microtime(true)
を使用する場合でも、これは危険にさらされます。 一度も)。彼らは、あなたがそうすべきだと思っていたとしても、平等になっていないことで有名です。代わりに、このようなものを使用する必要があります。 0.001
数値処理業界では「イプシロン」と呼ばれています。
WHERE table.timestamp BETWEEN 1357609984.100000 - 0.001
AND 1357609984.100000 + 0.001
または同様のもの。これらのタイムスタンプを小数または100万分の1秒単位でbigint
に保存すると、この問題は発生しません。 列。
IEEE 64ビット浮動小数点には、53ビットの仮数(精度)があります。現在のUNIXエポックタイムスタンプ(1970年1月1日00:00Zからの秒数)に100万を掛けると、51ビットが使用されます。したがって、下位ビットを気にする場合、DOUBLEの精度はそれほど高くありません。一方、精度は数世紀の間尽きることはありません。
int64(BIGINT)で精度が不足することはありません。 MySQLでの順序付けのためだけにマイクロ秒のタイムスタンプを実際に保存している場合は、DATETIME(6)
を使用します。 たくさんの日付演算を無料で手に入れるからです。インメモリの大容量アプリを実行している場合は、int64を使用します。