PHP DateTime микросекунды всегда возвращает 0 - PullRequest
69 голосов
/ 04 октября 2008

этот код всегда возвращает 0 в PHP 5.2.5 для микросекунд:

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

Есть идеи?

Ответы [ 18 ]

1 голос
/ 02 декабря 2010

Работа с 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
0 голосов
/ 09 мая 2013

Внутри приложения, которое я пишу, мне нужно установить / отобразить микровремя для объектов DateTime. Кажется, единственный способ заставить объект DateTime распознавать микросекунды - это инициализировать его временем в формате «ГГГГ-ММ-ДД ЧЧ: ММ: СС.уууууу». Пробел между частями даты и времени также может быть символом «Т», как обычно в формате ISO8601.

Следующая функция возвращает объект 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()));
}
0 голосов
/ 13 сентября 2015

В некоторых ответах используются несколько временных меток, что является концептуально неправильным, и могут возникнуть проблемы с перекрытием: секунды из 21:15:05.999 в сочетании с микросекундами из 21:15:06.000 дают 21:15:05.000.

По-видимому, самым простым является использование DateTime::createFromFormat() с 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);
}
0 голосов
/ 07 мая 2015

Основываясь на комментариях Лаки, я написал простой способ хранения сообщений на сервере. В прошлом я использовал хэши и приращения для получения уникальных имен файлов, но для этого приложения хорошо работает дата с микросекундами.

// 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
0 голосов
/ 29 августа 2013

В документации 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.php )

0 голосов
/ 14 декабря 2008

Строка в формате, принятом strtotime () Это работает!

0 голосов
/ 04 июня 2012

Этот метод безопаснее принятого ответа:

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

Обновление: не рекомендуется (см. Комментарии)

0 голосов
/ 17 ноября 2010

дата ('u') поддерживается только из PHP 5.2. Ваш PHP может быть старше!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...