How to display a date as iso 8601 format with PHP

125,258

Solution 1

The second argument of date is a UNIX timestamp, not a database timestamp string.

You need to convert your database timestamp with strtotime.

<?= date("c", strtotime($post[3])) ?>

Solution 2

Using the DateTime class available in PHP version 5.2 it would be done like this:

$datetime = new DateTime('17 Oct 2008');
echo $datetime->format('c');

As of PHP 5.4 you can do this as a one-liner:

echo (new DateTime('17 Oct 2008'))->format('c');

Solution 3

Procedural style :

echo date_format(date_create('17 Oct 2008'), 'c');
// Output : 2008-10-17T00:00:00+02:00

Object oriented style :

$formatteddate = new DateTime('17 Oct 2008');
echo $datetime->format('c');
// Output : 2008-10-17T00:00:00+02:00

Hybrid 1 :

echo date_format(new DateTime('17 Oct 2008'), 'c');
// Output : 2008-10-17T00:00:00+02:00

Hybrid 2 :

echo date_create('17 Oct 2008')->format('c');
// Output : 2008-10-17T00:00:00+02:00

Notes :

1) You could also use 'Y-m-d\TH:i:sP' as an alternative to 'c' for your format.

2) The default time zone of your input is the time zone of your server. If you want the input to be for a different time zone, you need to set your time zone explicitly. This will also impact your output, however :

echo date_format(date_create('17 Oct 2008 +0800'), 'c');
// Output : 2008-10-17T00:00:00+08:00

3) If you want the output to be for a time zone different from that of your input, you can set your time zone explicitly :

echo date_format(date_create('17 Oct 2008')->setTimezone(new DateTimeZone('America/New_York')), 'c');
// Output : 2008-10-16T18:00:00-04:00

Solution 4

Here is the good function for pre PHP 5: I added GMT difference at the end, it's not hardcoded.

function iso8601($time=false) {
    if ($time === false) $time = time();
    $date = date('Y-m-d\TH:i:sO', $time);
    return (substr($date, 0, strlen($date)-2).':'.substr($date, -2));
}

Solution 5

For pre PHP 5:

function iso8601($time=false) {
    if(!$time) $time=time();
    return date("Y-m-d", $time) . 'T' . date("H:i:s", $time) .'+00:00';
}
Share:
125,258
Matthew James Taylor
Author by

Matthew James Taylor

Artist, designer, web developer

Updated on June 25, 2021

Comments

  • Matthew James Taylor
    Matthew James Taylor almost 3 years

    I'm trying to display a datetime from my MySQL database as an iso 8601 formated string with PHP but it's coming out wrong.

    17 Oct 2008 is coming out as: 1969-12-31T18:33:28-06:00 which is clearly not correct (the year should be 2008 not 1969)

    This is the code I'm using:

    <?= date("c", $post[3]) ?>
    

    $post[3] is the datetime (CURRENT_TIMESTAMP) from my MySQL database.

    Any ideas what's going wrong?

  • gregor
    gregor over 13 years
    why not escape T sign ... and the !$time condition is not necesary, as current time is used when no time parameter is given or null: date('Y-m-d\TH:i:s\Z', $time);//Z represents current time zone
  • German Latorre
    German Latorre almost 11 years
    Please, use classes! Take a look at @John Conde solution, ;)
  • Christian
    Christian over 10 years
    The date() function decreases accuracy, use John's solution instead!
  • Yifan
    Yifan almost 6 years
    @Christian what is 'The date() function decreases accuracy' ?
  • Christian
    Christian almost 6 years
    It does not handle milliseconds (and smaller units) properly.
  • Sherbieny
    Sherbieny over 3 years
    For anyone coming here to find a solution between Swift ISO8601DateFormatter and your PHP server date formatting - the working one above is $dt->format('Y-m-d\TH:i:s.').substr($dt->format('u'),0,3).'Z‌​'; Thank you man!!!
  • ADJenks
    ADJenks over 3 years
    @Christian The 'c' format doesn't include fractions of seconds and John's answer currently only uses the 'c' format, so John's answer is not an improvement. You're right that DateTime() allows for a higher resolution, but it doesn't help you unless you're using a custom 8601 format with higher res. So, if you're only using 'c' format and you like functional programming, then I think this solution is good. For those that want higher resolution, Clary's answer provides some examples.
  • Christian
    Christian over 3 years
    @ADJenks as far as I remember, it's not about the 'c' parameter but rather that date requires a timestamp in seconds as an integer - whereas the DateTime object supports smaller units. In other words, I'm concerned with the storage part, not the formatting part.
  • ADJenks
    ADJenks over 3 years
    Yes of course @Christian, I said you were right about DateTime storing time at higher resolution. I would recommend using DateTime if you need that extra resolution, but neither John Conde or John Slegers use the resolution anywhere. I don't think a more powerful thing is better unless you need the power. You might argue that they may use it elsewhere later, sure, but John doesn't. So perhaps I would say "Use DateTime() instead of date() if you need to store time in higher resolution than seconds." but I wouldn't say "use John's solution instead", since they both successfully display ISO 8601.