从毫秒获取日期格式mdY H:i:su


117

我正在尝试获取格式化的日期,包括毫秒数。

唯一的问题是我不断赚到000000

date("m-d-Y H:i:s.u", $milliseconds/1000);

例如 2013/07/28 11:26:14.000000


6
这个问题要求转换毫秒数很奇怪,但是每个人都回答如何转换毫秒数。我知道您可以在两者之间进行转换,但实际上是回答问题,而不是从PHP文档或其他地方复制和粘贴无关的代码会很好。
劳伦特'18

我知道已经有一段时间了,但是bamossza的回答是我在这里找到的最好的答案
Piyin

Answers:


122

php.net说:

微秒(在PHP 5.2.2中添加)。请注意,由于它采用整数参数,因此date()将始终生成000000,而DateTime::format()如果DateTime使用微秒创建,则支持微秒。

所以使用就这么简单:

$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()参考类:

$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 at point on "u"

注意u是微秒(1秒= 1000000 µs)。

来自php.net的另一个示例:

$d2=new DateTime("2012-07-08 11:14:15.889342");

参考dateTime()php.net

我已经回答了简短的问题,并简化为作者。请参阅作者的更多信息:从毫秒获取日期格式mdY H:i:su


4
我通常选择第二种形式,因为它更易于阅读和理解。此外,DateTime比日期/时间函数更灵活,更健壮。处理微秒就是一个很好的例子。
赫伯特

我同意赫伯特的观点。@slik,这是最好的答案:)
Marco Sulla

3
@Geo和AlBundy可能是您在php <5.2.2的计算机上尝试此操作吗?PHP 5.4.39运行得非常好……
RichardBernards

这不容易吗?date('mdY H:i:s')。(int)microtime(true);
Anant

@Anant,确实很容易。但是错了。;)您得到的只是几秒钟的纪元。(不幸的是,microtime(false)两者都不起作用。)
Sz。

138

您可以使用输入格式轻松地做到这一点U.u

$now = DateTime::createFromFormat('U.u', microtime(true));
echo $now->format("m-d-Y H:i:s.u");

这将产生以下输出:

04-13-2015 05:56:22.082300

从PHP手册页获取日期格式:

  • U =自Unix时代以来的秒数
  • u =微秒

http://php.net/manual/zh/function.date.php


感谢gggsey指出了我原来的答案中的一个缺陷,将其添加number_format()到行中应该可以确定确切的秒数。太糟糕了,感觉不再优雅了...

$now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));

http://php.net/manual/zh/function.number-format.php


关于DaVe的时区说明。

通常,createFromFormat()如果未指定本地时区,则该方法将使用本地时区。

http://php.net/manual/en/datetime.createfromformat.php

但是,此处描述的技术是初始化DateTime对象microtime(),该对象用于返回自Unix纪元(1970年1月1日00:00:00 GMT)以来经过的秒数。

http://php.net/manual/zh/function.microtime.php

这意味着DateTime对象被隐式初始化为UTC,这对于只想跟踪经过时间的服务器内部任务很好。

如果需要显示特定时区的时间,则需要进行相应设置。但是,由于上述原因,应在初始化后(使用的第三个参数createFromFormat())作为一个单独的步骤进行操作。

setTimeZone()方法可用于完成此要求。

http://php.net/manual/en/datetime.settimezone.php

举个例子:

$now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));
echo $now->format("m-d-Y H:i:s.u") . '<br>';

$local = $now->setTimeZone(new DateTimeZone('Australia/Canberra'));
echo $local->format("m-d-Y H:i:s.u") . '<br>';

产生以下输出:

10-29-2015 00:40:09.433818
10-29-2015 11:40:09.433818

请注意,如果要输入mysql,则时间格式必须为:

format("Y-m-d H:i:s.u")

19
注意:DateTime::createFromFormat('U.u', microtime(true));如果microtime(true)精确到秒,将返回false 。它返回“ 1438616239”而不是“ 1438616239.000000”。
giggsey 2015年

1
很好的解决方案,谢谢。看来我失去了本地时间,从微时间创建$ now。任何想法?
daVe

1
@daVe我添加了有关时区的一些信息,希望您所追求的是。
ArchCodeMonkey 2015年

1
number_format始终是必要的,即使它不是确切的第二位。否则,您会受到precisionPHP配置选项(“显示”)的支配,该选项在PHP 7.0之前默认情况下不够高,从而导致精度损失(精确到微秒)。
张汉辉

1
始终在StackOverflow中向下滚动
tom10271 '19

15

这是一个略短的方法。我没有创建高精度的数字日期/时间,而是将微秒值转换为字符串,删除0,然后将其添加到日期/时间字符串的末尾。通过调整字符串长度参数,我可以轻松地修剪小数位数;在这里,我用4毫秒来表示,但是可以用7毫秒来表示。

$t = explode(" ",microtime());
echo date("m-d-y H:i:s",$t[1]).substr((string)$t[0],1,4);

对于microtime()的值0.98236000 1407400573,将返回08-07-14 01:08:13.982


9

我用

echo date("Y-m-d H:i:s.").gettimeofday()["usec"];

output: 2017-09-05 17:04:57.555036

6
echo date('m-d-Y H:i:s').substr(fmod(microtime(true), 1), 1);

示例输出:

02-06-2019 16:45:03.53811192512512

如果您需要限制小数位数,那么下面的行(credit mgutt)将是一个很好的选择。(对于下面的代码,6会将小数位数限制为6。)

echo date('m-d-Y H:i:').sprintf('%09.6f', date('s')+fmod(microtime(true), 1));

示例输出:

02-11-2019 15:33:03.624493

您错过了精度并领先零秒。因此,正确的版本应该是echo date('m-d-Y H:i:').sprintf('%09.6f', date('s')+fmod(microtime(true), 1));。说明我们为什么需要09stackoverflow.com/a/28739819/318765
mgutt

您再次错过了精度;)echo date('H:i:s').substr(fmod(microtime(true), 1), 1, 7);
mgutt

但是要当心,substr()不会四舍五入。与此相伴的是,round()它会减少尾随的零:stackoverflow.com/questions/7493305 / ...这就是我提出的原因sprintf()
mgutt

@mgutt什么时候第一位数不是零?基本上,仅需简单地从fmod中减去1时删除始终存在的零。该问题要求以微秒为单位,但以秒的小数位形式。没有理由限制小数位数。小数位数越多,精度越高。
ghbarratt

@mgutt我在答案中添加了第一个建议的替代方法,并解释说这将是限制小数位数的好方法
-ghbarratt

3

如果您(new Date()).toISOString()出于某种原因想要格式化像JavaScript这样的日期,可以通过以下方式在PHP中进行操作:

$now = microtime(true);
gmdate('Y-m-d\TH:i:s', $now).sprintf('.%03dZ',round(($now-floor($now))*1000));

样本输出:

2016-04-27T18:25:56.696Z

只是为了证明减去整数不会降低小数部分的精度:

>>> number_format(123.01234567890123456789,25)
=> "123.0123456789012408307826263"
>>> number_format(123.01234567890123456789-123,25)
=> "0.0123456789012408307826263"

PHP 确实舍入了小数位,但在两种情况下都以相同的方式将它们舍入。


1
不。不要对浮点数使用数学运算,这是不准确的。也不要浪费时间调用多个函数。只需使用substr()将格式化的日期截断为小数点后三位。
LS

@LS截断不会四舍五入到小数点后第三位。浮点数不会分解,直到您达到非常小的精度为止。小数点后3位应该可以。实际上,我根本不改变精度,浮点数越接近0,浮点数就越准确。减去整数不应更改AFAIK的小数位。
mpen

date('Y-m-d\TH:i:s', $time / 1000) . sprintf('.%03dZ', substr($time, 10));
F8ER

@ F8ER如果您$time已经以毫秒为单位,是的,这在技术上是可行的。不喜欢这种substr骇客,但我猜想它适用于2001年到2286
mpen

是的,$time是MS,但是,那是什么2286意思,为什么要这样想以及如何有可能摆脱这种情况?
F8ER

3

这基于ArchCodeMonkey的答案。

但是只是简化了一下,如果您只想快速实用的话。

function DateTime_us_utc(){
    return DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));
}
function DateTime_us(){
    $now = DateTime_us_utc();
    return $now->setTimeZone(new DateTimeZone(date_default_timezone_get()));
}

所以对我来说

$now = DateTime_us();
$now->format("m-d-Y H:i:s.u");

3

这是另一种我觉得更优雅/更简单的方法:

echo date('Y-m-d-H:i:s.').preg_replace("/^.*\./i","", microtime(true));

1
// Procedural
$fineStamp = date('Y-m-d\TH:i:s') . substr(microtime(), 1, 9);
echo $fineStamp . PHP_EOL;

// Object-oriented (if you must). Still relies on $fineStamp though :-\
$d = new DateTime($fineStamp);
echo $d->format('Y-m-d\TH:i:s.u') . PHP_EOL;

1

从PHP 7.1开始,您可以执行以下操作:

$date = new DateTime( "NOW" );
echo $date->format( "m-d-Y H:i:s.u" );

它将显示为:

04-11-2018 10:54:01.321688

0

该文档说:

微秒(在PHP 5.2.2中添加)。请注意,由于date()使用整数参数,因此它将始终生成000000,而DateTime :: format()确实支持微秒。

即,改用DateTime。


6
这行不通!DATE_FORMAT(新的DateTime(), 'U')给出了零:phpfiddle.org/lite/code/ggh-mvz
亚尼斯Elmeris

是的,按照上面的答案(和我的试验),您new DateTime()也将返回0000。但是,如果在实例化时为其提供了微秒精度的时间,则可以正常工作。
scipilot 2014年

@scipilot好的,那你该怎么做?
2014年

@Geo看到已接受的答案。new DateTime( 'Y-m-d H:i:s.'.$micro);
scipilot 2014年

0

现在使用PHP 7.0+,您可以执行以下操作:

$dateString = substr($millseconds_go_here,0,10);
$drawDate = new \DateTime(Date('Y-m-d H:i',$dateString));
$drawDate->setTimezone(new \DateTimeZone('UTC'));

这将按顺序执行以下操作:

  1. 修剪掉字符串的最后4个零,以便Date()可以处理日期。
  2. 使用日期将毫秒格式设置为DateTime可以理解的日期时间字符串。
  3. DateTime()可以让您修改您所在的时区,但是date_default_timezone_set("Timezone");在使用DateTime()函数和类之前请确保已设置该时区。
  4. 优良作法是在类中使用构造函数,以确保在DateTime()使用类或函数时使用正确的时区。

0

如果您使用的是Carbon,则可以使用定义的规范“ RFC3339_EXTENDED”。或自定义它。

Carbon::RFC3339_EXTENDED = 'Y-m-d\TH:i:s.vP';

0

基于@ArchCodeMonkey的答案。

如果您declare(strict_types=1)必须将第二个参数转换为字符串

在此处输入图片说明


0

我采用了几种不同的方法:

1)microtime + sscanf +日期:

sscanf(microtime(), '0.%6s00 %s', $usec, $sec);
$date = date('Y-m-d H:i:s.', $sec) . $usec;

我不确定为什么microtime()在微秒部分返回10个字符(0.dddddd00),但是也许有人可以告诉我?

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { sscanf(microtime(), '0.%6s00 %s', $usec, $sec); $date = date('Y-m-d H:i:s.', $sec) . $usec; } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "22372.335910797 ms" // macOS PHP 5.6.30
string(18) "16772.964000702 ms" // Linux PHP 5.4.16
string(18) "10382.229089737 ms" // Linux PHP 7.3.11 (same linux box as above)

2)DateTime :: createFromFormat + Datetime-> format:

$now = new DateTime('NOW');
$date = $now->format('Y-m-d H:i:s.u');

在PHP 5.x中不起作用...

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { $now = new DateTime('NOW'); $date = $now->format('Y-m-d H:i:s.u'); } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "45801.825046539 ms" // macOS PHP 5.6.30 (ms not working)
string(18) "21180.155038834 ms" // Linux PHP 5.4.16 (ms not working)
string(18) "11879.796028137 ms" // Linux PHP 7.3.11 (same linux box as above)

3)gettimeofday +日期:

$time = gettimeofday();
$date = date('Y-m-d H:i:s.', $time['sec']) . $time['usec'];

--

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { $time = gettimeofday(); $date = date('Y-m-d H:i:s.', $time['sec']) . $time['usec']; } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "23706.788063049 ms" // macOS PHP 5.6.30
string(18) "14984.534025192 ms" // Linux PHP 5.4.16
string(18) "7799.1390228271 ms" // Linux PHP 7.3.11 (same linux box as above)

4)microtime + number_format + DateTime :: createFromFormat + DateTime-> format:

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

--

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { $now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', '')); $date = $now->format('Y-m-d H:i:s.u'); } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "83326.496124268 ms" // macOS PHP 5.6.30
string(18) "61982.603788376 ms" // Linux PHP 5.4.16
string(16) "19107.1870327 ms" // Linux PHP 7.3.11 (same linux box as above)

5)microtime + sprintf + DateTime :: createFromFormat + DateTime-> format:

$now = DateTime::createFromFormat('U.u', sprintf('%.6f', microtime(true)));
$date = $now->format('Y-m-d H:i:s.u');

--

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { $now = DateTime::createFromFormat('U.u', sprintf('%.6f', microtime(true))); $date = $now->format('Y-m-d H:i:s.u'); } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "79387.331962585 ms" // macOS PHP 5.6.30
string(18) "60734.437942505 ms" // Linux PHP 5.4.16
string(18) "18594.941139221 ms" // Linux PHP 7.3.11 (same linux box as above)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.