Last week I managed to get round to doing several items on the Web Tasklist (private wikipage) including sorting out all the JISC CETIS site news feeds. This covers the main feed from the front page, feeds organised by tag, and feeds from the events system. Needless to say they are now all validating nicely and easily locatable by all your favourite aggregators.
The real stick in the mud with producing the feeds turned out to be the precise formatting of dates. The ATOM 1.0 spec requires dates to be formatted according to RFC3339 and the various flavours of RSS require a variation of RFC822. All very well I think, I have the mighty Smarty templating engine running atop PHP. All I need to do is ask it to format the dates using the built-in date format conversion support, isn’t it. But no, that would be too easy.
Smarty has a useful modifier plugin called date_format which converts incoming dates (from php or mysql native date formats) into anything you might want. It is essentially a wrapper for the PHP strftime function, taking the same format instructions as the C function of the same name. So I start concocting format strings for the two RFCs in question and trying to get them to validate.
I also tried using PHP’s date() function – this takes a completely different syntax to produce the desired output including useful constants for such standard dates. Not that they were any help either!
Atom (rfc3339)
PHP Function | Format string | Sample output | Problem |
strftime() | %Y-%m-%dT%H:%M:%SZ | 2007-02-12T17:01:07Z | The Z is a fudge – the time might not actually be in the UTC timezone |
strftime() | %Y-%m-%dT%H:%M:%S%Z | 2007-02-12T17:01:07UTC | No – UTC is not valid… |
strftime() | %Y-%m-%dT%H:%M:%S%z | 2007-02-12T17:01:07+0000 | Using lowercase %z better but missing colon in time-zone |
date() | DATE_ATOM | 2007-02-12T17:01:07+00:00 | It’s right! |
RSS (rfc822)
PHP Function | Format string | Sample output | Problem |
strftime() | %a, %d %b %Y %H:%M:%S %Z | Thu, 15 Feb 2007 17:12:23 UTC | Produces ‘UTC’ as the time zone – this is not allowed in the rfc |
strftime() | %a, %d %b %Y %H:%M:%S %z | Thu, 15 Feb 2007 17:12:23 +0000 | Using the undocumented lowercase %z produces the right output! |
date() | DATE_RSS | Thu, 08 Feb 2007 13:05:37 UTC | NO NO NO Not UTC! It should be right for goodness sake! |
date() | D, d M y H:i:s O | Thu, 08 Feb 2007 13:05:37 +0000 | It’s right! |
I find this state of affairs pretty silly really – bunging some dates in standard formats into a feed should be a trivial nothing and not something that takes hours of faffing to get quite right. I ended up writing a new smarty wrapper for the date() function with support for the useful constants and correction for RSS and RFC822 dates. The smarty plugin is attached.
Download: Smarty plugin phpdate_format
And finally our feeds validate. Touch wood.
I wish I’d found this posting a few days ago. I’ve just been through the exact same process, however, I just modified the existing Smarty plugin so that I could just pass ‘rfc822′ as the ‘format’ parameter to get the correct format for my RSS feeds, although this isn’t ideal.
BTW, which version of PHP is this? Because in 5.2.1 at least, the DATE_RSS constant matches the DATE_RFC2822 constant, i.e. “D, d M y H:i:s O”, so I’d have thought this ‘should’ be correct.
Still, thank you for your summary of this issue. Maybe you get could the Smarty guys to use the constants in the same way as you have in the main date_format modifier as it seems to do just what is required, as having two date formatting plug-ins seems like overkill to me.
I’m on PHP 5.1.6 – which is probably in need of an update. You have a very good point about getting both the useful constants and possibly the alternate date() syntax integrated into the official smarty plugin. Definitely worth sending them an email…
Can you help me out?
I have a date in Atom format: 2007-07-18T19:32:00.001-07:00
And I want to convert it to: July 18th, 2007 7:32 PM
I tried looking it up online but nothing is helping very much. I want to do it using commands like date() and strftime() .. but it’s not working out for me.
Any help is greatly appreciated. I’m not sure if you can see my email or not, and I don’t want to post it, so if you can’t, please use this form: http://www.student.cs.uwaterloo.ca/~jmaerten/contact.html
Thank you SOO Much for your help!
Hmmm…. that’s a bit off topic really… You are basically needing to wrestle with the strtotime() function which can’t handle the time zone or millisecond info in the format you’ve got there. I’ve got other things to think about today though. Anyone else?
Hey there,
Just found a need for this, so thanks a lot for the effort involved, and for making it available for the rest of us. Great stuff!
Tony
Pingback: Whoila Blog » Blog Archive » Format date to RSS and ATOM using SMARTY