I am trying to get a formatted date, including the microseconds from a UNIX timestamp specified in milliseconds.
The only problem is I keep getting 000000, e.g.
$milliseconds = 1375010774123;
$d = date("m-d-Y H:i:s.u", $milliseconds/1000);
print $d;
07-28-2013 11:26:14.000000
You can readily do this this with the input format U.u.
$now = DateTime::createFromFormat('U.u', microtime(true));
echo $now->format("m-d-Y H:i:s.u");
This produces the following output:
04-13-2015 05:56:22.082300
From the PHP manual page for date formats:
U = Seconds since the Unix Epoch
u = Microseconds
http://php.net/manual/en/function.date.php
Thanks goes to giggsey for pointing out a flaw in my original answer, adding number_format() to the line should fix the case of the exact second. Too bad it doesn't feel quite as elegant any more...
$now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));
http://php.net/manual/en/function.number-format.php
A note on time zones in response to DaVe.
Normally the createFromFormat() method will use the local time zone if one is not specified.
http://php.net/manual/en/datetime.createfromformat.php
However, the technique described here is initialising the DateTime object using microtime() which returns the number of seconds elapsed since the Unix Epoch (01 Jan 1970 00:00:00 GMT).
http://php.net/manual/en/function.microtime.php
This means that the DateTime object is implicitly initialised to UTC, which is fine for server internal tasks that just want to track elapsed time.
If you need to display the time for a particular time zone then you need to set it accordingly. However, this should be done as a separate step after the initialisation (not using the third parameter of createFromFormat()) because of the reasons discussed above.
The setTimeZone() method can be used to accomplish this requirement.
http://php.net/manual/en/datetime.settimezone.php
As an example:
$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>';
Produces the following output:
10-29-2015 00:40:09.433818
10-29-2015 11:40:09.433818
Note that if you want to input into mysql, the time format needs to be:
format("Y-m-d H:i:s.u")
php.net says:
Microseconds (added in PHP 5.2.2). Note that date() will always generate 000000 since it takes an integer parameter, whereas DateTime::format() does support microseconds if DateTime was created with microseconds.
So use as simple:
$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>";
Recommended and use dateTime() class from referenced:
$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"
Note u is microseconds (1 seconds = 1000000 µs).
Another example from php.net:
$d2=new DateTime("2012-07-08 11:14:15.889342");
Reference of dateTime() on php.net
I've answered on question as short and simplify to author. Please see for more information to author: getting date format m-d-Y H:i:s.u from milliseconds
Here's a slightly shorter approach. Rather than work to create a high-precision numeric date/time, I convert the microsecond value to a string, remove the 0, and add it to the end of the date/time string. I can easily trim the number of decimals by adjusting the string length parameter; here I use 4 to get milliseconds, but you could use 7 to get microseconds.
$t = explode(" ",microtime());
echo date("m-d-y H:i:s",$t[1]).substr((string)$t[0],1,4);
For a microtime() value of 0.98236000 1407400573, this returns 08-07-14 01:08:13.982.
I'm use
echo date("Y-m-d H:i:s.").gettimeofday()["usec"];
output: 2017-09-05 17:04:57.555036
# PHP 8 type safe when using declare(strict_types=1);
echo date('m-d-Y H:i:s').substr((string) fmod(microtime(true), 1), 1, 4);
example output:
02-06-2019 16:45:03.53811192512512
If you have a need to limit the number of decimal places then the below line (credit mgutt) would be a good alternative. (With the code below, the 6 limits the number of decimal places to 6.)
echo date('m-d-Y H:i:').sprintf('%09.6f', date('s')+fmod(microtime(true), 1));
example output:
02-11-2019 15:33:03.624493
For PHP 8.0+
The bug has been recently fixed and now you can use UNIX timestamps with a fractional part.
$milliseconds = 1375010774123;
$d = new DateTime( '#'. $milliseconds/1000 );
print $d->format("m-d-Y H:i:s.u");
Output:
07-28-2013 11:26:14.123000
For PHP < 8.0
You need to specify the format of your UNIX timestamp before you can use it in the DateTime object. As noted in other answers, you can simply work around this bug by using createFromFormat() and number_format()
$milliseconds = 1375010774123;
$d = DateTime::createFromFormat('U.v', number_format($milliseconds/1000, 3, '.', ''));
print $d->format("m-d-Y H:i:s.u");
Output:
07-28-2013 11:26:14.123000
For PHP < 7.3
If you are still using PHP older than 7.3 you can replace U.v with U.u. It will not make any difference, but the millisecond format identifier is present only since PHP 7.3.
$milliseconds = 1375010774123;
// V - Use microseconds instead of milliseconds
$d = DateTime::createFromFormat('U.u', number_format($milliseconds/1000, 3, '.', ''));
print $d->format("m-d-Y H:i:s.u");
Output:
07-28-2013 11:26:14.123000
If you want to format a date like JavaScript's (new Date()).toISOString() for some reason, this is how you can do it in PHP:
$now = microtime(true);
gmdate('Y-m-d\TH:i:s', $now).sprintf('.%03dZ',round(($now-floor($now))*1000));
Sample output:
2016-04-27T18:25:56.696Z
Just to prove that subtracting off the whole number doesn't reduce the accuracy of the decimal portion:
>>> number_format(123.01234567890123456789,25)
=> "123.0123456789012408307826263"
>>> number_format(123.01234567890123456789-123,25)
=> "0.0123456789012408307826263"
PHP did round the decimal places, but it rounded them the same way in both cases.
This is based on answer from ArchCodeMonkey.
But just simplified, if you just want something quick that works.
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()));
}
So for me then
$now = DateTime_us();
$now->format("m-d-Y H:i:s.u");
As of PHP 7.1 you can simply do this:
$date = new DateTime( "NOW" );
echo $date->format( "m-d-Y H:i:s.u" );
It will display as:
04-11-2018 10:54:01.321688
Here is another method that I find slightly more elegant/simple:
echo date('Y-m-d-H:i:s.').preg_replace("/^.*\./i","", microtime(true));
// 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;
The documentation says the following:
Microseconds (added in PHP 5.2.2). Note that date() will always
generate 000000 since it takes an integer parameter, whereas
DateTime::format() does support microseconds.
I.e., use DateTime instead.
With PHP 7.0+ now here you can do the following:
$dateString = substr($millseconds_go_here,0,10);
$drawDate = new \DateTime(Date('Y-m-d H:i',$dateString));
$drawDate->setTimezone(new \DateTimeZone('UTC'));
This does the following in order:
Trims the last 4 zeros off the string so Date() can handle the date.
Uses date to format the milliseconds into a date time string that DateTime can understand.
DateTime() can then allow you to modify the time zone you are in, but ensure that date_default_timezone_set("Timezone"); is set before you use DateTime() functions and classes.
It is good practice to use a constructor in your classes to make sure your in the correct timezone when DateTime() classes or functions are used.
if you are using Carbon, you can use the defined spec "RFC3339_EXTENDED".
or customize it.
Carbon::RFC3339_EXTENDED = 'Y-m-d\TH:i:s.vP';
Based on #ArchCodeMonkey answer.
If you have declare(strict_types=1) you must cast second argument to string
This function work from php5.2 till php7.4. Here it is including test code:
#!/usr/bin/php
<?php
function dtfn ($t=null) // for filenames, date + time, year first, ms always 3 digits
{
if (!$t) $t = microtime(true);
$dtx = date('Y-m-d_H.i.s', $t);
$ms = sprintf("%03u", 1000 * fmod($t,1));
return "$dtx.$ms";
}
function xxx($t)
{
echo sprintf("%12s: %s\n", $t, dtfn($t));
}
xxx(1);
xxx(1.0);
xxx(1.01);
xxx(1.0101);
xxx(1.23456789);
results:
1: 1970-01-01_01.00.01.000
1: 1970-01-01_01.00.01.000
1.01: 1970-01-01_01.00.01.010
1.0101: 1970-01-01_01.00.01.010
1.23456789: 1970-01-01_01.00.01.234
Single line version (useful as function param) for php >= 7.3:
printf("%s",
(DateTime::createFromFormat('U.u', microtime(true)))
->setTimezone(new \DateTimeZone('UTC'))
->format("Y-m-d.H:i:s.v")
);
See v and u in formats
Simplest solution for me was:
date('c', substr($timestamp, 0, -3))
Related
This question already has answers here:
Convert one date format into another in PHP
(17 answers)
Closed 1 year ago.
Input time format:
2016-05-03 01:38:54
Ouput time format:
2016-05-03T01:38:54.003Z
Here what is .003, is it millisecond or microsecond?
And in PHP the microsecond format is 'u', but when I am trying to use this using the following code snippet, I am getting 6 digits after the decimal point:
<?php
date_default_timezone_set("Asia/Kolkata");
echo date('Y-m-d\TH:i:s.u\Z', strtotime("2016-05-03 01:38:54"));
I am getting the output as:
2016-05-03T01:38:54.000000Z
But in this output after the decimal point it is showing 6 digit, which I want to change it to 3 digit. How can I do that?
So how should I get the output format?
date_default_timezone_set("Asia/Kolkata");
$t = strtotime('2016-05-03 01:38:54');
$micro = sprintf("%06d",($t - floor($t)) * 1000000);
$d = new DateTime( date('Y-m-d H:i:s.'.$micro, $t) );
$new= $d->Format("Y-m-d\T H:i:s.u\Z");
echo substr($new, 0, -4) ."Z";
//output 2016-05-03T 01:38:54.030Z
I'd use the DateTime class as follows:
$tz = new DateTimeZone('Asia/Kolkata');
$date = new DateTime('2016-05-03 01:38:54', $tz );
echo substr($date->format('Y-m-d\TH:i:s.u'), 0, -3) ."Z";
// 2016-05-03T01:38:54.000Z
http://ideone.com/Wrrve9
According to PHP date manual
u Microseconds (added in PHP 5.2.2). Note that date() will always
generate 000000 since it takes an integer parameter, whereas
DateTime::format() does support microseconds if DateTime was created
with microseconds.
try this
$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\T H:i:s.u\Z"); // note at point on "u"
The cleanest solution might be a modified version of adityabhai at gmail dot com's comment on http://php.net/manual/en/function.date.php:
echo date('Y-m-d H:i:s' . substr((string)microtime(), 1, 4));
In my code, I'm using DateTime objects to manipulate dates, then convert them to timestamp in order to save them in some JSON files.
For some reasons, I want to have the same thing as DateTime (or something close), but with microseconds precision (that I would convert to float when inserting inside the JSON files).
My question is : is there a PHP object that is like DateTime, but can handle microseconds too ?
The goal is to be able to manipulate microtimes with objects.
In the date() documentation, there is something that indicates that DateTime can be created with microseconds, but I wasn't able to find how.
u Microseconds (added in PHP 5.2.2). Note that date() will always
generate 000000 since it takes an integer parameter, whereas
DateTime::format() does support microseconds if DateTime was created
with microseconds.
I have tried to set the timestamp of a DateTime object with a floating value (microtime(true)), but it doesn't work (I think it converts the timestamp to an int, causing the loss of the microseconds).
Here is how i tried
$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'));
The .4 is not taken into account as you can see here (even though we can use the u format, which corresponds to the microseconds).
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)
EDIT : I saw this code, which allows to add microseconds to a DateTime, but I would need to apply a lot of modifications to the microtime before creating the DateTime. Since I will use this a lot, I want to do as little modifications to the microtime as possible before getting the "microtime object".
$d = new DateTime("15-07-2014 18:30:00.111111");
Here's a very simple method of creating a DateTime object that includes microtime.
I didn't delve into this question too deeply so if I missed something I apologize but hope you find this helpful.
$date = DateTime::createFromFormat('U.u', microtime(TRUE));
var_dump($date->format('Y-m-d H:i:s.u'));
I tested it out and tried various other ways to make this work that seemed logical but this was the sole method that worked for PHP versions prior to 7.1.
However there was a problem, it was returning the correct time portion but not the correct day portion (because of UTC time most likely)
Here's what I did (still seems simpler IMHO):
$dateObj = DateTime::createFromFormat('U.u', microtime(TRUE));
$dateObj->setTimeZone(new DateTimeZone('America/Denver'));
var_dump($dateObj->format('Y-m-d H:i:s:u'));
Here's a working example: http://sandbox.onlinephpfunctions.com/code/66f20107d4adf87c90b5c8c914393d4edef180a2
UPDATE
As pointed out in comments, as of PHP 7.1, the method recommended by Planplan appears to be superior to the one shown above.
So, again for PHP 7.1 and later it may be better to use the below code instead of the above:
$dateObj = DateTime::createFromFormat('0.u00 U', microtime());
$dateObj->setTimeZone(new DateTimeZone('America/Denver'));
var_dump($dateObj->format('Y-m-d H:i:s:u'));
Please be aware that the above works only for PHP versions 7.1 and above. Previous versions of PHP will return 0s in place of the microtime, therefore losing all microtime data.
Here's an updated sandbox showing both:
http://sandbox.onlinephpfunctions.com/code/a88522835fdad4ae928d023a44b721e392a3295e
NOTE: in testing the above sandbox I did not ever see the microtime(TRUE) failure which Planplan mentioned that he experienced. The updated method does, however, appear to record a higher level of precision as suggested by KristopherWindsor.
NOTE2: Please be aware that there may be rare cases where either approach will fail because of an underlying decision made regarding the handling of microseconds in PHP DateTime code. Either:
avoid use of this for scientific purposes or anything where a very high level of accuracy is required.
OR be prepared for no microsecond data to return on an exact second mark... (where a microsecond ... which is 1 millionth of a second, will have no data to return as it is complete zeros... from what I've read this is not clear from what's returned and could be done in a better way but is worth creating code to handle ... again, for high precisions uses)
Thanks for the headsup Sz. (see comments).
Looking at a response on the PHP DateTime manual:
DateTime does not support split seconds (microseconds or milliseconds etc.)
I don't know why this isn't documented.
The class constructor will accept them without complaint, but they are discarded.
There does not appear to be a way to take a string like "2012-07-08 11:14:15.638276" and store it in an objective form in a complete way.
So you cannot do date math on two strings such as:
<?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
)
*/
?>
You get back 0 when you actually want to get 0.251066 seconds.
However, taking a response from 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>";
Recommended and use dateTime() class from referenced:
$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).
Reference of dateTime() on php.net: http://php.net/manual/en/datetime.construct.php#
/!\ EDIT /!\
I now use https://github.com/briannesbitt/Carbon, the rest of this answer is just here for historical reasons.
END EDIT
I decided to extend the class DateTime using the tips you all gave me.
The constructor takes a float (from microtime) or nothing (in this case it will be initialized with the current "micro-timestamp").
I also overrided 2 functions that were important : setTimestamp and getTimestamp.
Unfortunately, I couldn't solve the performances issue, although it's not as slow as I thought.
Here's the whole class :
<?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;
}
}
There are multiple options. But as already provided by Ben, I will try to give you another solution.
If you provided more details on what kind of calculations you want to do it could be changed further.
$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");
or
$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");
or
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");
or
list($usec, $sec) = explode(' ', microtime());
print date('Y-m-d H:i:s', $sec) . $usec;
/*
* 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;
}
This worked for me in PHP 7.2:
$dateTime = \DateTime::createFromFormat('U.u', sprintf('%f', $aFloat), $optionalTimezone);
I got to thinking that since the format code 'u' would output only the microsecond part of a date when converting to a string then doing the reverse would be the same. And that it also expects a period character '.' so if $aFloat happened to be a whole number then default conversion to a string would leave off the decimal point. Initially I thought the float to string conversion needed '%.6f' but the 'u' is expecting a string which is left justified. Trailing zeros are unnecessary.
I'm a little late with this, but I had to develop a solution that works for PHP 5, PHP 7.0, and PHP 7.1+.
list($msec, $now) = explode(' ', microtime(false));
$z = gmdate('Y-m-d\TH:i:s' . substr($msec, 1) . '\Z', $now);
This gives you a valid UTC timestring with microseconds. If you need still need it as a DateTime object, you can just pass this string directly:
$dt = new DateTime($z);
This works from PHP 5.2 if you need the DateTime, but if you just need the string with microseconds it's good all the way back to PHP 4.
since I resolved my issue i want to share it with You.
Php71+ have microsecconds accuracy, if You want to convert it into nano accuracy just multiply it by 1000 (10^3).
$nsTimestamp = (int) (new \DateTime())->getTimestamp() * 1000
$micro_seconds = microtime(false) * 1000000;
echo date('Y-m-d H:i:s.'. floor($micro_seconds));
more about date:
https://www.php.net/manual/en/function.date.php
more about microtime: https://www.php.net/manual/en/function.microtime.php
Beautiful date and time, step by step:
Note that the microtime() tells time AND microtime (numbers after the period)
echo microtime(true) ."<br>"; //1601674357.9448
sleep(0.99);
echo microtime(true) ."<br>"; //1601674357.9449
sleep(0.99);
echo microtime(true) ."<br>"; //1601674357.945
So let's take the numbers after the period:
echo substr(microtime(true), 11,4) . "<br>"; //945
But if for a moment you only had 1 or 2 digits after the period? We complete with zeros...
Ok, now we always have 4 digits which are the microseconds
echo str_pad(substr(microtime(true), 11,4), 4, '0', STR_PAD_RIGHT) . "<br>"; //9450
So, let's add the date... Final result:
$date = gmdate('Y-m-d h:i:s.');
$time = str_pad(substr(microtime(true), 11,4), 4, '0', STR_PAD_RIGHT);
echo $date . $time; //2020-10-02 09:43:57.9450
I am trying to get a formatted date, including the microseconds from a UNIX timestamp specified in milliseconds.
The only problem is I keep getting 000000, e.g.
$milliseconds = 1375010774123;
$d = date("m-d-Y H:i:s.u", $milliseconds/1000);
print $d;
07-28-2013 11:26:14.000000
You can readily do this this with the input format U.u.
$now = DateTime::createFromFormat('U.u', microtime(true));
echo $now->format("m-d-Y H:i:s.u");
This produces the following output:
04-13-2015 05:56:22.082300
From the PHP manual page for date formats:
U = Seconds since the Unix Epoch
u = Microseconds
http://php.net/manual/en/function.date.php
Thanks goes to giggsey for pointing out a flaw in my original answer, adding number_format() to the line should fix the case of the exact second. Too bad it doesn't feel quite as elegant any more...
$now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));
http://php.net/manual/en/function.number-format.php
A note on time zones in response to DaVe.
Normally the createFromFormat() method will use the local time zone if one is not specified.
http://php.net/manual/en/datetime.createfromformat.php
However, the technique described here is initialising the DateTime object using microtime() which returns the number of seconds elapsed since the Unix Epoch (01 Jan 1970 00:00:00 GMT).
http://php.net/manual/en/function.microtime.php
This means that the DateTime object is implicitly initialised to UTC, which is fine for server internal tasks that just want to track elapsed time.
If you need to display the time for a particular time zone then you need to set it accordingly. However, this should be done as a separate step after the initialisation (not using the third parameter of createFromFormat()) because of the reasons discussed above.
The setTimeZone() method can be used to accomplish this requirement.
http://php.net/manual/en/datetime.settimezone.php
As an example:
$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>';
Produces the following output:
10-29-2015 00:40:09.433818
10-29-2015 11:40:09.433818
Note that if you want to input into mysql, the time format needs to be:
format("Y-m-d H:i:s.u")
php.net says:
Microseconds (added in PHP 5.2.2). Note that date() will always generate 000000 since it takes an integer parameter, whereas DateTime::format() does support microseconds if DateTime was created with microseconds.
So use as simple:
$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>";
Recommended and use dateTime() class from referenced:
$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"
Note u is microseconds (1 seconds = 1000000 µs).
Another example from php.net:
$d2=new DateTime("2012-07-08 11:14:15.889342");
Reference of dateTime() on php.net
I've answered on question as short and simplify to author. Please see for more information to author: getting date format m-d-Y H:i:s.u from milliseconds
Here's a slightly shorter approach. Rather than work to create a high-precision numeric date/time, I convert the microsecond value to a string, remove the 0, and add it to the end of the date/time string. I can easily trim the number of decimals by adjusting the string length parameter; here I use 4 to get milliseconds, but you could use 7 to get microseconds.
$t = explode(" ",microtime());
echo date("m-d-y H:i:s",$t[1]).substr((string)$t[0],1,4);
For a microtime() value of 0.98236000 1407400573, this returns 08-07-14 01:08:13.982.
I'm use
echo date("Y-m-d H:i:s.").gettimeofday()["usec"];
output: 2017-09-05 17:04:57.555036
# PHP 8 type safe when using declare(strict_types=1);
echo date('m-d-Y H:i:s').substr((string) fmod(microtime(true), 1), 1, 4);
example output:
02-06-2019 16:45:03.53811192512512
If you have a need to limit the number of decimal places then the below line (credit mgutt) would be a good alternative. (With the code below, the 6 limits the number of decimal places to 6.)
echo date('m-d-Y H:i:').sprintf('%09.6f', date('s')+fmod(microtime(true), 1));
example output:
02-11-2019 15:33:03.624493
For PHP 8.0+
The bug has been recently fixed and now you can use UNIX timestamps with a fractional part.
$milliseconds = 1375010774123;
$d = new DateTime( '#'. $milliseconds/1000 );
print $d->format("m-d-Y H:i:s.u");
Output:
07-28-2013 11:26:14.123000
For PHP < 8.0
You need to specify the format of your UNIX timestamp before you can use it in the DateTime object. As noted in other answers, you can simply work around this bug by using createFromFormat() and number_format()
$milliseconds = 1375010774123;
$d = DateTime::createFromFormat('U.v', number_format($milliseconds/1000, 3, '.', ''));
print $d->format("m-d-Y H:i:s.u");
Output:
07-28-2013 11:26:14.123000
For PHP < 7.3
If you are still using PHP older than 7.3 you can replace U.v with U.u. It will not make any difference, but the millisecond format identifier is present only since PHP 7.3.
$milliseconds = 1375010774123;
// V - Use microseconds instead of milliseconds
$d = DateTime::createFromFormat('U.u', number_format($milliseconds/1000, 3, '.', ''));
print $d->format("m-d-Y H:i:s.u");
Output:
07-28-2013 11:26:14.123000
If you want to format a date like JavaScript's (new Date()).toISOString() for some reason, this is how you can do it in PHP:
$now = microtime(true);
gmdate('Y-m-d\TH:i:s', $now).sprintf('.%03dZ',round(($now-floor($now))*1000));
Sample output:
2016-04-27T18:25:56.696Z
Just to prove that subtracting off the whole number doesn't reduce the accuracy of the decimal portion:
>>> number_format(123.01234567890123456789,25)
=> "123.0123456789012408307826263"
>>> number_format(123.01234567890123456789-123,25)
=> "0.0123456789012408307826263"
PHP did round the decimal places, but it rounded them the same way in both cases.
This is based on answer from ArchCodeMonkey.
But just simplified, if you just want something quick that works.
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()));
}
So for me then
$now = DateTime_us();
$now->format("m-d-Y H:i:s.u");
As of PHP 7.1 you can simply do this:
$date = new DateTime( "NOW" );
echo $date->format( "m-d-Y H:i:s.u" );
It will display as:
04-11-2018 10:54:01.321688
Here is another method that I find slightly more elegant/simple:
echo date('Y-m-d-H:i:s.').preg_replace("/^.*\./i","", microtime(true));
// 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;
The documentation says the following:
Microseconds (added in PHP 5.2.2). Note that date() will always
generate 000000 since it takes an integer parameter, whereas
DateTime::format() does support microseconds.
I.e., use DateTime instead.
With PHP 7.0+ now here you can do the following:
$dateString = substr($millseconds_go_here,0,10);
$drawDate = new \DateTime(Date('Y-m-d H:i',$dateString));
$drawDate->setTimezone(new \DateTimeZone('UTC'));
This does the following in order:
Trims the last 4 zeros off the string so Date() can handle the date.
Uses date to format the milliseconds into a date time string that DateTime can understand.
DateTime() can then allow you to modify the time zone you are in, but ensure that date_default_timezone_set("Timezone"); is set before you use DateTime() functions and classes.
It is good practice to use a constructor in your classes to make sure your in the correct timezone when DateTime() classes or functions are used.
if you are using Carbon, you can use the defined spec "RFC3339_EXTENDED".
or customize it.
Carbon::RFC3339_EXTENDED = 'Y-m-d\TH:i:s.vP';
Based on #ArchCodeMonkey answer.
If you have declare(strict_types=1) you must cast second argument to string
This function work from php5.2 till php7.4. Here it is including test code:
#!/usr/bin/php
<?php
function dtfn ($t=null) // for filenames, date + time, year first, ms always 3 digits
{
if (!$t) $t = microtime(true);
$dtx = date('Y-m-d_H.i.s', $t);
$ms = sprintf("%03u", 1000 * fmod($t,1));
return "$dtx.$ms";
}
function xxx($t)
{
echo sprintf("%12s: %s\n", $t, dtfn($t));
}
xxx(1);
xxx(1.0);
xxx(1.01);
xxx(1.0101);
xxx(1.23456789);
results:
1: 1970-01-01_01.00.01.000
1: 1970-01-01_01.00.01.000
1.01: 1970-01-01_01.00.01.010
1.0101: 1970-01-01_01.00.01.010
1.23456789: 1970-01-01_01.00.01.234
Single line version (useful as function param) for php >= 7.3:
printf("%s",
(DateTime::createFromFormat('U.u', microtime(true)))
->setTimezone(new \DateTimeZone('UTC'))
->format("Y-m-d.H:i:s.v")
);
See v and u in formats
Simplest solution for me was:
date('c', substr($timestamp, 0, -3))
I have a PHP DateTime object with microseconds created as follows:
$time = microtime(true);
$microseconds = sprintf('%06d', ($time - floor($time)) * 1000000);
$dt = new DateTime(date('Y-m-d H:i:s.' . $microseconds, $time));
How can I modify the microseconds value of $dt, without creating a completely new DateTime instance?
You can't.
There are three methods that can modify the value of a DateTime instance: add, sub and modify. We can rule out add and sub immediately because they work in terms of a DateInterval which does not have sub-second precision.
modify accepts a string in one of the standard recognized formats. Of those formats, only the relative ones are of interest here because the other ones work in an absolute manner; and there is no relative format that allows tweaking the msec part (that unit is not recognized).
as of PHP 7.1
DateTime::setTime() supports microseconds.
This seems to have been available since 7.1.0-rc4
$dt = new DateTime('2020-01-01 0:00');
$dt->modify('+500 ms'); // Milliseconds.
$dt->modify('+123456 usec'); // Microseconds.
$dt->modify('+123456 microseconds'); // This works too.
It's mentioned here in the manual.
Manually creating a DateTime object with micro seconds:
$d = new DateTime("15-07-2014 18:30:00.111111");
Getting a DateTime object of the current time with microseconds:
$d = date_format(new DateTime(),'d-m-Y H:i:s').substr((string)microtime(), 1, 8);
Difference between two DateTime objects in microseconds (e.g. returns: 2.218939)
//Returns the difference, in seconds, between two datetime objects including
//the microseconds:
function mdiff($date1, $date2){
$date1sec = strtotime($date1->format('d-m-Y H:i:s.u'));
$date2sec = strtotime($date2->format('d-m-Y H:i:s.u'));
//Absolute val of Date 1 in seconds from (EPOCH Time) - Date 2 in seconds from (EPOCH Time)
$secdiff = abs($date1sec-$date2sec);
//Creates variables for the microseconds of date1 and date2
$micro1 = $date1->format("u");
$micro2 = $date2->format("u");
if (($date1sec<$date2sec && $micro1>$micro2)||($date1sec>$date2sec && $micro1<$micro2)){
$microdiff = abs(1000000 - abs($micro1-$micro2));
$secdiff = $secdiff - 1;
} else {
$microdiff = abs($micro1 - $micro2);
}
//Creates the variable that will hold the seconds (?):
$difference = $secdiff.".".$microdiff;
return $difference;
}
Essentially it finds the difference for the DateTime Objects using strtotime and then adding the extra microseconds on.
Do you need me to create add and sub?
i had a similar problem and ended up having to wrap the whole thing
https://gist.github.com/chandeeland/9817516
For the people only in need to zero-out microseconds (I had to because of database layer) here's the snippet I ended up using:
$format = "Y-m-d H:i:s e";
$now = (new \DateTime())->format($format);
$dateTime = \DateTime::createFromFormat($format, $now);
Note that using $format = 'c', ISO 8601, will not work, as explained here (https://stackoverflow.com/a/10478469/8119317).
I am trying to get a formatted date, including the microseconds from a UNIX timestamp specified in milliseconds.
The only problem is I keep getting 000000, e.g.
$milliseconds = 1375010774123;
$d = date("m-d-Y H:i:s.u", $milliseconds/1000);
print $d;
07-28-2013 11:26:14.000000
You can readily do this this with the input format U.u.
$now = DateTime::createFromFormat('U.u', microtime(true));
echo $now->format("m-d-Y H:i:s.u");
This produces the following output:
04-13-2015 05:56:22.082300
From the PHP manual page for date formats:
U = Seconds since the Unix Epoch
u = Microseconds
http://php.net/manual/en/function.date.php
Thanks goes to giggsey for pointing out a flaw in my original answer, adding number_format() to the line should fix the case of the exact second. Too bad it doesn't feel quite as elegant any more...
$now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));
http://php.net/manual/en/function.number-format.php
A note on time zones in response to DaVe.
Normally the createFromFormat() method will use the local time zone if one is not specified.
http://php.net/manual/en/datetime.createfromformat.php
However, the technique described here is initialising the DateTime object using microtime() which returns the number of seconds elapsed since the Unix Epoch (01 Jan 1970 00:00:00 GMT).
http://php.net/manual/en/function.microtime.php
This means that the DateTime object is implicitly initialised to UTC, which is fine for server internal tasks that just want to track elapsed time.
If you need to display the time for a particular time zone then you need to set it accordingly. However, this should be done as a separate step after the initialisation (not using the third parameter of createFromFormat()) because of the reasons discussed above.
The setTimeZone() method can be used to accomplish this requirement.
http://php.net/manual/en/datetime.settimezone.php
As an example:
$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>';
Produces the following output:
10-29-2015 00:40:09.433818
10-29-2015 11:40:09.433818
Note that if you want to input into mysql, the time format needs to be:
format("Y-m-d H:i:s.u")
php.net says:
Microseconds (added in PHP 5.2.2). Note that date() will always generate 000000 since it takes an integer parameter, whereas DateTime::format() does support microseconds if DateTime was created with microseconds.
So use as simple:
$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>";
Recommended and use dateTime() class from referenced:
$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"
Note u is microseconds (1 seconds = 1000000 µs).
Another example from php.net:
$d2=new DateTime("2012-07-08 11:14:15.889342");
Reference of dateTime() on php.net
I've answered on question as short and simplify to author. Please see for more information to author: getting date format m-d-Y H:i:s.u from milliseconds
Here's a slightly shorter approach. Rather than work to create a high-precision numeric date/time, I convert the microsecond value to a string, remove the 0, and add it to the end of the date/time string. I can easily trim the number of decimals by adjusting the string length parameter; here I use 4 to get milliseconds, but you could use 7 to get microseconds.
$t = explode(" ",microtime());
echo date("m-d-y H:i:s",$t[1]).substr((string)$t[0],1,4);
For a microtime() value of 0.98236000 1407400573, this returns 08-07-14 01:08:13.982.
I'm use
echo date("Y-m-d H:i:s.").gettimeofday()["usec"];
output: 2017-09-05 17:04:57.555036
# PHP 8 type safe when using declare(strict_types=1);
echo date('m-d-Y H:i:s').substr((string) fmod(microtime(true), 1), 1, 4);
example output:
02-06-2019 16:45:03.53811192512512
If you have a need to limit the number of decimal places then the below line (credit mgutt) would be a good alternative. (With the code below, the 6 limits the number of decimal places to 6.)
echo date('m-d-Y H:i:').sprintf('%09.6f', date('s')+fmod(microtime(true), 1));
example output:
02-11-2019 15:33:03.624493
For PHP 8.0+
The bug has been recently fixed and now you can use UNIX timestamps with a fractional part.
$milliseconds = 1375010774123;
$d = new DateTime( '#'. $milliseconds/1000 );
print $d->format("m-d-Y H:i:s.u");
Output:
07-28-2013 11:26:14.123000
For PHP < 8.0
You need to specify the format of your UNIX timestamp before you can use it in the DateTime object. As noted in other answers, you can simply work around this bug by using createFromFormat() and number_format()
$milliseconds = 1375010774123;
$d = DateTime::createFromFormat('U.v', number_format($milliseconds/1000, 3, '.', ''));
print $d->format("m-d-Y H:i:s.u");
Output:
07-28-2013 11:26:14.123000
For PHP < 7.3
If you are still using PHP older than 7.3 you can replace U.v with U.u. It will not make any difference, but the millisecond format identifier is present only since PHP 7.3.
$milliseconds = 1375010774123;
// V - Use microseconds instead of milliseconds
$d = DateTime::createFromFormat('U.u', number_format($milliseconds/1000, 3, '.', ''));
print $d->format("m-d-Y H:i:s.u");
Output:
07-28-2013 11:26:14.123000
If you want to format a date like JavaScript's (new Date()).toISOString() for some reason, this is how you can do it in PHP:
$now = microtime(true);
gmdate('Y-m-d\TH:i:s', $now).sprintf('.%03dZ',round(($now-floor($now))*1000));
Sample output:
2016-04-27T18:25:56.696Z
Just to prove that subtracting off the whole number doesn't reduce the accuracy of the decimal portion:
>>> number_format(123.01234567890123456789,25)
=> "123.0123456789012408307826263"
>>> number_format(123.01234567890123456789-123,25)
=> "0.0123456789012408307826263"
PHP did round the decimal places, but it rounded them the same way in both cases.
This is based on answer from ArchCodeMonkey.
But just simplified, if you just want something quick that works.
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()));
}
So for me then
$now = DateTime_us();
$now->format("m-d-Y H:i:s.u");
As of PHP 7.1 you can simply do this:
$date = new DateTime( "NOW" );
echo $date->format( "m-d-Y H:i:s.u" );
It will display as:
04-11-2018 10:54:01.321688
Here is another method that I find slightly more elegant/simple:
echo date('Y-m-d-H:i:s.').preg_replace("/^.*\./i","", microtime(true));
// 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;
The documentation says the following:
Microseconds (added in PHP 5.2.2). Note that date() will always
generate 000000 since it takes an integer parameter, whereas
DateTime::format() does support microseconds.
I.e., use DateTime instead.
With PHP 7.0+ now here you can do the following:
$dateString = substr($millseconds_go_here,0,10);
$drawDate = new \DateTime(Date('Y-m-d H:i',$dateString));
$drawDate->setTimezone(new \DateTimeZone('UTC'));
This does the following in order:
Trims the last 4 zeros off the string so Date() can handle the date.
Uses date to format the milliseconds into a date time string that DateTime can understand.
DateTime() can then allow you to modify the time zone you are in, but ensure that date_default_timezone_set("Timezone"); is set before you use DateTime() functions and classes.
It is good practice to use a constructor in your classes to make sure your in the correct timezone when DateTime() classes or functions are used.
if you are using Carbon, you can use the defined spec "RFC3339_EXTENDED".
or customize it.
Carbon::RFC3339_EXTENDED = 'Y-m-d\TH:i:s.vP';
Based on #ArchCodeMonkey answer.
If you have declare(strict_types=1) you must cast second argument to string
This function work from php5.2 till php7.4. Here it is including test code:
#!/usr/bin/php
<?php
function dtfn ($t=null) // for filenames, date + time, year first, ms always 3 digits
{
if (!$t) $t = microtime(true);
$dtx = date('Y-m-d_H.i.s', $t);
$ms = sprintf("%03u", 1000 * fmod($t,1));
return "$dtx.$ms";
}
function xxx($t)
{
echo sprintf("%12s: %s\n", $t, dtfn($t));
}
xxx(1);
xxx(1.0);
xxx(1.01);
xxx(1.0101);
xxx(1.23456789);
results:
1: 1970-01-01_01.00.01.000
1: 1970-01-01_01.00.01.000
1.01: 1970-01-01_01.00.01.010
1.0101: 1970-01-01_01.00.01.010
1.23456789: 1970-01-01_01.00.01.234
Single line version (useful as function param) for php >= 7.3:
printf("%s",
(DateTime::createFromFormat('U.u', microtime(true)))
->setTimezone(new \DateTimeZone('UTC'))
->format("Y-m-d.H:i:s.v")
);
See v and u in formats
Simplest solution for me was:
date('c', substr($timestamp, 0, -3))