source

PHP DateTime 마이크로초는 항상 0을 반환합니다.

lovecheck 2022. 10. 20. 21:59
반응형

PHP DateTime 마이크로초는 항상 0을 반환합니다.

이 코드는 항상 PHP 5.2.5에서 마이크로초 동안 0을 반환합니다.

<?php
$dt = new DateTime();
echo $dt->format("Y-m-d\TH:i:s.u") . "\n";
?>

출력:

[root@www1 ~]$ php date_test.php
2008-10-03T20:31:26.000000
[root@www1 ~]$ php date_test.php
2008-10-03T20:31:27.000000
[root@www1 ~]$ php date_test.php
2008-10-03T20:31:27.000000
[root@www1 ~]$ php date_test.php
2008-10-03T20:31:28.000000

좋은 생각 있어요?

이것은 효과가 있는 것처럼 보이지만, http://us.php.net/date가 마이크로초 지정자를 문서화하는 것은 비논리적으로 보이지만 실제로 지원하지 않습니다.

function getTimestamp()
{
        return date("Y-m-d\TH:i:s") . substr((string)microtime(), 1, 8);
}

입력에 마이크로초가 포함되도록 지정할 수 있습니다.DateTime오브젝트 및 사용microtime(true)직접 입력으로 사용합니다.

불행하게도, 만약 당신이 정확히 2초를 친다면, 이것은 실패할 것이다. 왜냐하면 그것은 존재하지 않을 것이기 때문입니다..마이크로타임 출력에 포함되므로sprintf억지로 포함시키다.0이 경우:

date_create_from_format(
    'U.u', sprintf('%.f', microtime(true))
)->format('Y-m-d\TH:i:s.uO');

또는 동등(더 OO 스타일)

DateTime::createFromFormat(
    'U.u', sprintf('%.f', microtime(true))
)->format('Y-m-d\TH:i:s.uO');

이 함수는 http://us3.php.net/date 에서 가져옵니다.

function udate($format, $utimestamp = null)
{
    if (is_null($utimestamp))
        $utimestamp = microtime(true);

    $timestamp = floor($utimestamp);
    $milliseconds = round(($utimestamp - $timestamp) * 1000000);

    return date(preg_replace('`(?<!\\\\)u`', $milliseconds, $format), $timestamp);
}

echo udate('H:i:s.u'); // 19:40:56.78128

'u'를 작동시키려면 이 기능을 구현해야 합니다.:\

이것을 시험해 보면, 마이크로초가 표시됩니다.

$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");
\DateTime::createFromFormat('U.u', microtime(true));

(최소한 대부분의 시스템에서) 다음을 제공합니다.

object(DateTime)(
  'date' => '2015-03-09 17:27:39.456200',
  'timezone_type' => 3,
  'timezone' => 'Australia/Darwin'
)

그러나 PHP 플로트 반올림 때문에 정밀도가 떨어집니다.마이크로초라고는 할 수 없습니다.

갱신하다

이것은 아마도 가장 좋은 타협일 것입니다.createFromFormat()완전 정밀도를 제공합니다.

\DateTime::createFromFormat('0.u00 U', microtime());

get time of day()

보다 명확하고, 보다 견고할 수 있습니다.사비가 발견한 버그를 해결합니다.

$time = gettimeofday(); 
\DateTime::createFromFormat('U.u', sprintf('%d.%06d', $time['sec'], $time['usec']));

네, 마지막으로 정리하고 싶습니다.

ISO 8601 형식의 날짜와 시간을 PHP로 밀리초와 마이크로초로 표시하는 방법에 대한 설명...

밀리초 또는 'ms'는 소수점 뒤에 4자리가 있습니다(예: 0.1234마이크로초 또는 'ms'는 소수점 뒤에 7자리가 있습니다).여기서 분수/이름 설명(초)

PHP의date()php date documents의 형식 문자 'u'에서 설명한 바와 같이 함수는 정수만 제외하고 밀리초 또는 마이크로초로 완전히 예상대로 동작하지 않습니다.

Lucky의 코멘트 아이디어(여기서)를 기반으로 하지만 PHP 구문을 수정하고 초 형식을 적절하게 처리함(Lucky의 코드는 초 후에 잘못된 추가 '0'을 추가함)

또한 이러한 기능은 경주 조건을 제거하고 초의 형식을 올바르게 지정합니다.

PHP 날짜(밀리초)

와 동등한 기능date('Y-m-d H:i:s').".$milliseconds";

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

출력 =2016-07-12 16:27:08.5675

PHP 날짜(마이크로초)

와 동등한 기능date('Y-m-d H:i:s').".$microseconds";또는date('Y-m-d H:i:s.u')날짜 함수가 예상대로 마이크로초/로 동작하는 경우microtime()/'u'

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

출력 =2016-07-12 16:27:08.56752900

이것은 나에게 효과가 있었고 간단한 세 줄짜리 문구입니다.

function udate($format='Y-m-d H:i:s.', $microtime=NULL) {
    if(NULL === $microtime) $microtime = microtime();
    list($microseconds,$unix_time) = explode(' ', $microtime);
    return date($format,$unix_time) . array_pop(explode('.',$microseconds));
}

디폴트에서는(파라미터는 제공되지 않습니다) 현재 마이크로초 동안 다음 형식의 문자열을 반환합니다.

YYY-MM-DD HH:MM: SS.UUUUUUUUUU

보다 심플한/빠른(단, 정밀도의 절반만 사용) 방법은 다음과 같습니다.

function udate($format='Y-m-d H:i:s.', $microtime=NULL) {
    if(NULL === $microtime) $microtime = microtime(true);
    list($unix_time,$microseconds) = explode('.', $microtime);
    return date($format,$unix_time) . $microseconds;
}

이 인쇄물은 다음 형식으로 출력됩니다.

YYY-MM-DD HH:SS.UUU

date_create

time : strtotime()에서 허용하는 형식의 문자열로 기본값은 "now"입니다.

스트롯타임

time : GNU " Date Input Formats 구문에 따라 해석하는 문자열.PHP 5.0.0 이전에는 마이크로초가 허용되지 않았습니다. PHP 5.0.0에서는 허용되지만 무시되기 때문입니다.

Lucky의 코멘트PHP 버그 데이터베이스에 있는 이 기능 요청따라 다음과 같은 것을 사용합니다.

class ExtendedDateTime extends DateTime {
    /**
     * Returns new DateTime object.  Adds microtime for "now" dates
     * @param string $sTime
     * @param DateTimeZone $oTimeZone 
     */
    public function __construct($sTime = 'now', DateTimeZone $oTimeZone = NULL) {
        // check that constructor is called as current date/time
        if (strtotime($sTime) == time()) {
            $aMicrotime = explode(' ', microtime());
            $sTime = date('Y-m-d H:i:s.' . $aMicrotime[0] * 1000000, $aMicrotime[1]);
        }

        // DateTime throws an Exception with a null TimeZone
        if ($oTimeZone instanceof DateTimeZone) {
            parent::__construct($sTime, $oTimeZone);
        } else {
            parent::__construct($sTime);
        }
    }
}

$oDate = new ExtendedDateTime();
echo $oDate->format('Y-m-d G:i:s.u');

출력:

2010-12-01 18:12:10.146625

이건 어때?

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

출력 예시

2013-07-17 08:23:37:0.88862400

이것은 가장 유연하고 정확한 것이어야 합니다.

function udate($format, $timestamp=null) {
    if (!isset($timestamp)) $timestamp = microtime();
    // microtime(true)
    if (count($t = explode(" ", $timestamp)) == 1) {
        list($timestamp, $usec) = explode(".", $timestamp);
        $usec = "." . $usec;
    }
    // microtime (much more precise)
    else {
        $usec = $t[0];
        $timestamp = $t[1];
    }
    // 7 decimal places for "u" is maximum
    $date = new DateTime(date('Y-m-d H:i:s' . substr(sprintf('%.7f', $usec), 1), $timestamp));
    return $date->format($format);
}
echo udate("Y-m-d\TH:i:s.u") . "\n";
echo udate("Y-m-d\TH:i:s.u", microtime(true)) . "\n";
echo udate("Y-m-d\TH:i:s.u", microtime()) . "\n";
/* returns:
2015-02-14T14:10:30.472647
2015-02-14T14:10:30.472700
2015-02-14T14:10:30.472749
*/

strtotime()에서 허용하는 형식의 문자열. 작동합니다.

쓰고 있는 어플리케이션의 내부에서 Date Time 오브젝트의 마이크로 타임을 설정/표시할 필요가 있습니다.DateTime 객체가 마이크로초를 인식하도록 하는 유일한 방법은 "YYY-MM-DD HH:MM:SS.uuuuu"를 클릭합니다.날짜와 시간 부분 사이의 공백은 ISO8601 형식에서 일반적으로 "T"일 수도 있습니다.

다음 함수는 로컬 시간대로 초기화된 DateTime 개체를 반환합니다(물론 필요에 따라 코드를 변경할 수 있습니다).

// Return DateTime object including microtime for "now"
function dto_now()
{
    list($usec, $sec) = explode(' ', microtime());
    $usec = substr($usec, 2, 6);
    $datetime_now = date('Y-m-d H:i:s\.', $sec).$usec;
    return new DateTime($datetime_now, new DateTimeZone(date_default_timezone_get()));
}

PHP 문서에는 "date()는 정수 파라미터를 사용하기 때문에 항상 000000을 생성합니다..."라고 명시되어 있습니다.의 신속한 교환이 필요한 경우date()수수: :

function date_with_micro($format, $timestamp = null) {
    if (is_null($timestamp) || $timestamp === false) {
        $timestamp = microtime(true);
    }
    $timestamp_int = (int) floor($timestamp);
    $microseconds = (int) round(($timestamp - floor($timestamp)) * 1000000.0, 0);
    $format_with_micro = str_replace("u", $microseconds, $format);
    return date($format_with_micro, $timestamp_int);
}

(여기서 입수 가능 : date_with_micro.diag)

Lucky의 코멘트를 바탕으로 서버에 메시지를 저장하는 간단한 방법을 작성했습니다.이전에는 해시 및 증분 파일을 사용하여 고유한 파일 이름을 얻었지만, 이 응용 프로그램에서는 마이크로초의 날짜가 적합합니다.

// Create a unique message ID using the time and microseconds
    list($usec, $sec) = explode(" ", microtime());
    $messageID = date("Y-m-d H:i:s ", $sec) . substr($usec, 2, 8);
    $fname = "./Messages/$messageID";

    $fp = fopen($fname, 'w');

출력 파일의 이름은 다음과 같습니다.

2015-05-07 12:03:17 65468400

일부 가 발생할 수 를 들어, 「」로부터 입니다.이치노21:15:05.999 21:15:06.000를 주다21:15:05.000.

보아하니 가장 간단한 것은 와 함께 사용하는 것 같다.U.u, 코멘트에 기재되어 있듯이 마이크로초가 없으면 실패합니다.

그래서 저는 이 코드를 제안합니다.

function udate($format, $time = null) {

    if (!$time) {
        $time = microtime(true);
    }

    // Avoid missing dot on full seconds: (string)42 and (string)42.000000 give '42'
    $time = number_format($time, 6, '.', '');

    return DateTime::createFromFormat('U.u', $time)->format($format);
}

이 방법은 승인된 답변보다 안전합니다.

date('Y-m-d H:i:s.') . str_pad(substr((float)microtime(), 2), 6, '0', STR_PAD_LEFT)

출력:

2012-06-01 12:00:13.036613

업데이트: 권장 안 함(댓글 참조)

date('u')는 PHP 5.2에서만 지원됩니다.PHP가 더 오래된 것일 수 있습니다!

언급URL : https://stackoverflow.com/questions/169428/php-datetime-microseconds-always-returns-0

반응형