php function to convert "04-05-2012" to "04/05/2012? - php

I have tried using date("m/d/Y", strtotime("04-05-2012")) but I will get "05/04/2012" or on some other dates for example "03-30-2012" I will get "12/31/1969" (which makes sense because it it mixing up the month and day and there is no 30th month. So how should I do this? I also want to then convert the value into a UNIX time so that I can search it against MySQL db.

You can use the DateTime object and createFromFormat static method to do it :
$date = DateTime::createFromFormat('m-d-Y',"03-30-2012");
$date->format('m/d/Y');

If you know for certain that the format you start with is DD-MM-YYY when why not use a simple replace?
e.g. $newDate = str_replace('-', '/', '04-05-2012');

One way to do it would be using explode() and mktime():
$inDate = '03-30-2012';
list($m, $d, $y) = explode('-', $inDate);
$outDate = date('m/d/Y', mktime(0, 0, 0, $m, $d, $y));
This assumes the format is somehow dynamic, though. Otherwise, str_replace() is your best option, as others pointed out.

This isn't so much a date format question as a string manipulation question.
But it's still good to know that strtotime() exists.
[ghoti#pc ~]$ cat transdate.php
#!/usr/local/bin/php
<?php
$olddate = "04-05-2012"; // assuming mm-dd-YYYY
// Get the date parts into an array
$parts = explode("-", $olddate);
// Switch to YYYY-mm-dd, which will be interpreted consistently
$neworder = sprintf("%s-%s-%s", $parts[2], $parts[0], $parts[1]);
printf("New order: %s\n", $neworder);
// Set your timezone, or PHP will whine and complain
date_default_timezone_set('America/Toronto');
// Convert your reordered date to an epoch second (unix timestamp)
$epoch = strtotime($neworder);
// At a terminal, `man strftime` (or read the PHP function's docs) for details.
print "Alternate formats:\n";
printf("\t%s\n", strftime("%D", $epoch));
printf("\t%s\n", strftime("%F", $epoch));
printf("\t%s\n", strftime("%A %B %e, %Y (week %U)", $epoch));
[ghoti#pc ~]$ ./transdate.php
New order: 2012-04-05
Alternate formats:
04/05/12
2012-04-05
Thursday April 5, 2012 (week 14)
[ghoti#pc ~]$
This will work in PHP 5.1.6. Heck, it should work in PHP 4, except for date_default_timezone_set().

Related

validate date with milliseconds [duplicate]

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

How can i increase time in miliseconds using a loop in PHP? [duplicate]

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

Getting date format m-d-Y H:i:s.u from milliseconds

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

What is this date format called and how do I parse it?

I have a weird date format in some files I'm parsing. Here are some examples:
1954203
2012320
2010270
The first four digits are the year and the next three digits are day of year. For example, the first date is the 203rd day of 1954, or 7/22/1954.
My questions are:
What's this date format called?
Is there a pre-canned way to parse it? I don't want to reinvent the wheel here.
Edit: Sorry, I forgot to mention my language. PHP.
Try:
$oDate = DateTime::createFromFormat('Yz', 201026);
echo $oDate->format('Y-m-d');
For Java, see SimpleDateFormat. You want yyyyDDD as the format (year, then day in year).
Assuming you get it as a string in C#...
DateTime GetDate(string input)
{
int year = Int32.Parse(input.Substring(0,4));
int day = Int32.Parse(input.Substring(4,3));
return (new DateTime(year,1,1)).AddDays(day - 1);
}
(Note the -1 offset for the day number, since you are already starting at day 1)
In PHP to format the date:
echo date_parse_from_format("Yz", $date);
You can also use
DateTime::createFromFormat("YZ", $date);
or it's alias
date_create_from_format("Yz", $date)
which returns a DateTime object
Turns out what I wanted was this:
$date = '1954203';
$year = substr($date, 0, 4);
$day = substr($date, 4, 3);
$new_date = date("Y-m-d", mktime(1, 1, 1, 1, $day, $year));

date_create_from_format equivalent for PHP 5.2 (or lower)

I'm working with PHP 5.3 on my local machine and needed to parse a UK date format (dd/mm/yyyy). I found that strtotime didn't work with that date format, so I used date_create_from_format instead - which works great.
Now, my problem is that my staging server is running PHP 5.2, and date_create_from_format doesn't work on that version. (It's a shared server, and wouldn't have a clue how to upgrade it to PHP 5.3)
So is there a similar function to date_create_from_format that I can use? Bespoke or PHP native?
If strptime is not available to you, then here is a different idea. It is similar to Col. Shrapnel's approach but instead uses sscanf to parse the date-part values into variables and uses those to construct a new DateTime object.
list($day, $month, $year) = sscanf('12/04/2010', '%02d/%02d/%04d');
$datetime = new DateTime("$year-$month-$day");
echo $datetime->format('r');
Try strptime() which is available in PHP 5.1 and above.
include this code:
function DEFINE_date_create_from_format()
{
function date_create_from_format( $dformat, $dvalue )
{
$schedule = $dvalue;
$schedule_format = str_replace(array('Y','m','d', 'H', 'i','a'),array('%Y','%m','%d', '%I', '%M', '%p' ) ,$dformat);
// %Y, %m and %d correspond to date()'s Y m and d.
// %I corresponds to H, %M to i and %p to a
$ugly = strptime($schedule, $schedule_format);
$ymd = sprintf(
// This is a format string that takes six total decimal
// arguments, then left-pads them with zeros to either
// 4 or 2 characters, as needed
'%04d-%02d-%02d %02d:%02d:%02d',
$ugly['tm_year'] + 1900, // This will be "111", so we need to add 1900.
$ugly['tm_mon'] + 1, // This will be the month minus one, so we add one.
$ugly['tm_mday'],
$ugly['tm_hour'],
$ugly['tm_min'],
$ugly['tm_sec']
);
$new_schedule = new DateTime($ymd);
return $new_schedule;
}
}
if( !function_exists("date_create_from_format") )
DEFINE_date_create_from_format();
If you need to parse only one particular format, it's elementary string operation.
list($d,$m,$y)=explode("/",$datestr);
use format DD-MM-YY and timestamp, I think it will be easier for you
$date="31-11-2015";
$timestamp=strtotime($date);
$dateConvert=date('d-m-Y', $timestamp);
echo $dateConvert;
I've used it

Categories