Solved

Format time to ISO 8601 time with fractional seconds in PHP

Posted on 2008-10-27
9
2,331 Views
Last Modified: 2008-10-29
I've tried using the date('c', $theTime) and it returns an ISO 8601 formatted time, but removes the fractional seconds from the time.

Here's what I'm using:
<?php
    $theTime = '2008-08-18 17:59:15.27172';
    $date = date('c', strtotime($theTime));
   
    echo ($date);
 ?>

It simply prints:
2008-08-18T17:59:15-06:00

The time format is correct, accept I want to keep in the fractional seconds.  It does not seem to be the call to date() that does it, it's the strtotime call that removes the fractional seconds from what I can tell.  Is there an alternative to this?

"It can't be done" is an acceptable aswer if you can show me some documentation somewhere where it states/implies that.
0
Comment
Question by:AngryLoop
  • 4
  • 3
  • 2
9 Comments
 
LVL 3

Expert Comment

by:DarkFish
ID: 22815745
Off the top of my head I can't say why that wouldn't work, as I don't think it's the strtotime() call that is the issue. As you can, the date() format by default (using the "c" param) does not actually have a micro time before the -06:00 bit.

Instead, you would need to construct your own date / time and use the "u" param in addition to the other params to give yourself your desired time format.

For example, this should work (it will take the current timestamp as I have not given it a second param):

echo date("o\-m\-d\TH\:i\:s\.uP");

However, it gives the following output:

2008-10-27T15:04:30.000000-04:00

As you can see it's not actually giving you the micro seconds for some reason, which I am not entirely sure about. The PHP documentation on date() does say that the "u" param should work if you're PHP version is 5.2.2 or later, which mine is.

So the simple answer to your question is, it should work, but unfortunately somewhere in the date() function or (possibly, though unlikely) in the strtotime() function that microsecond value is getting lost.

Sorry that I couldn't be of more help :(
echo date("o\-m\-d\TH\:i\:s\.uP");

Open in new window

0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 22816099
ISO8601 time does not have microseconds, but this code snippet might be useful.  Note that time() does not return fractional seconds.

Man Pages here:
http://us2.php.net/manual/en/function.date.php
http://us2.php.net/manual/en/function.microtime.php

HTH, ~Ray
<?php 

$now = microtime();

$date = date("Y-m-d\tH:i:s\.u", $now);

echo $date;

Open in new window

0
 

Author Comment

by:AngryLoop
ID: 22816664
Ray_Paseur:
ISO8601 does have microseconds..  It has several different formats, but one of them includes "fractional" seconds.  See http://www.w3.org/TR/NOTE-datetime

That aside, microtime() doesn't help me in this instance, because I'm getting a time from a database so I can't use the current time.  The date/time is formatted like: 2008-08-19 08:52:03.12371

DarkFish:
The reason I said strtotime() is that if you call just that (meaning not the date function) and echo it, it removes the fractional seconds.

Your solution works by adding in ".000000" after the seconds.  It removes any fractional seconds.  Is there a conversion method which does NOT remove fractional seconds?
0
 
LVL 3

Accepted Solution

by:
DarkFish earned 250 total points
ID: 22816777
The point I was making was that even if you could get strtotime() to return a timestamp with fractional microseconds included, the date() function doesn't want to work with it anyway.

I don't know of any native PHP function that can handle microseconds correctly and convert it to a valid timestamp and then format that into a date. Neither do I know of an external PHP library that can handle date and time formatting with microseconds included, though I'm sure there is one somewhere.

However, that said you can write your own code to format your date using RegEx; for instance, over at the PHP documentation page for date() ( http://uk2.php.net/manual/en/function.date.php ) one member has given this some thought (please see code snippet.)

The original can be found at in the comments section by "Cortexd" on "27-Aug-2008 06:47".

Hope that helps,
Cortexd

27-Aug-2008 06:47

a date function supporting the milliseconds format character
 

<?php

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

echo udate('H:i:s.u', 654532123.04546); // 16:28:43.45460

Open in new window

0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 108

Assisted Solution

by:Ray Paseur
Ray Paseur earned 250 total points
ID: 22816839
Sorry - I should have said PHP's implementation of ISO8601, as shown in the date() functions that cover ISO 8601 date (added in PHP 5) - c, r, and u - do not have microseconds.  As I recall, the ISO standard has tenths and hundredths of seconds, but not microseconds.

However if you are getting the value from a data base in that format, you can explode the date/time with the delimiter '.' then take the seconds via strtotime on explode[0] and the milliseconds on explode[1]

Then if you wanted to get it back to the way it looked coming out of the data base, you could use something like the code snippet.

If you are doing math with these values you will probably need to keep the seconds and microseconds in separate computations.

~Ray
<?php 

$now = {string from DB as shown in original post};

$explode = explode('.', $now);

$isodate = explode[0];

$usecond = explode[1];

$date = date("Y-m-d\TH:i:s", strtotime($isodate));

$date .= ".$usecond";

echo $date;

Open in new window

0
 

Author Comment

by:AngryLoop
ID: 22817071
So it sounds like it's not directly supported in PHP.  The solution would be to use the built in functions to get close, and then I'd have to add in the fractional time information myself via regex or something similar.
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 22817376
Not sure I understand what you are trying to do. Give us a little more information about the app.  The examples posted above teach how to carry, extract and recombine the fields.  What are we missing?
0
 

Author Comment

by:AngryLoop
ID: 22817573
I'm not really sure what more relevant information I can give.

What I'm trying to do is take the time I've got and convert it to ISO 8601 without losing fractional seconds.

My hope by posting it here was to find a different way to pass the information to the built in functions date() or strtotime(), or a different function altogether.

From your posts, what I'm finding is that PHP does not seem to support it directly in that I can't use date('c', $unixTime); or any other built in function and maintain the fractional seconds (ISO 8601 date (added in PHP 5) - c, r, and u - do not have microseconds).

If I use the method you provided, it drops the time zone information - understandably so, as it would require a little more parsing effort to get the microseconds in the right place while including the timezone info (using date('c', $unixTime)).

That is why I was drawing the conclusion that it's a matter of manipulating the date/time given by the built in function date() since date() time does not include microseconds.

I just wanted to most elegant approach, but it sounds like the best I can do is add in a hack to add the fractional seconds back in to the date/time after it's been converted to ISO 8601.
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 22820794
You might want to give this information to the folks at PHP as a suggestion - you can also write your own PHP functions (easy way: use PHP; sophisticated way: use C++).  I think if you extend DarkFish's code example to add the date portion, you've got a foundation.

If you are looking for ways to do arithmetic with the ISO-Plus-Microtime values, it would be easy enough to integrate a few basic math calls, but that would be a different question.

In any case, good luck with your project. ~Ray
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Paypal 502 Error 3 70
simplest php form 3 61
unset shopping cart session 15 31
Intermittent Error on Page Loading 4 15
Both Easy and Powerful How easy is PHP? http://lmgtfy.com?q=how+easy+is+php (http://lmgtfy.com?q=how+easy+is+php)  Very easy.  It has been described as "a programming language even my grandmother can use." How powerful is PHP?  http://en.wikiped…
Author Note: Since this E-E article was originally written, years ago, formal testing has come into common use in the world of PHP.  PHPUnit (http://en.wikipedia.org/wiki/PHPUnit) and similar technologies have enjoyed wide adoption, making it possib…
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn how to count occurrences of each item in an array.

910 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now