Patch does not seem to fix the issue for me (var_dump( date_i18n( 'c' ) ); still produces invalid result). Could you elaborate a bit on it? I have trouble following what are you trying to do with time zone.

As per my description of the issue I think this is the problem with WP not recognizing shorthand time format, rather than with applying time zone (which works fine for other formats).

What I have done in the patch: Wordpress calls date_timezone_set to the UTC/GMT globally. Therefore date() (which is used in date_i18n()) and similar functions don’t care about your time zone set in the Wordpress settings. My patch basically makes a call like date() but cares about the time zone (take a look at ​PHP’s DateTime class). While doing that no time zone conversations are done!

Worked with my patch. Cannot find an issue :-( Used functions.php.2.patch

Yes, the timezone works with your patch. See how day and month are different? This is because of same issue with parsing formats, which your patch doesn't address because it only tries to fix timezone.

Yes, however it seems other (not compound) formats are all (?) already supported by date_i18n(). As above I have two issues left here - is "unpacking" them good enough of a solution and doing bit of a testing to be sure which other formats might need to be handled.

As you can see translation for 'S' (and 'e' too?) is still missing (needs extension of WP_Locale class). I think date_i18n() needs more testing. If you compare the patch with the old date_i18n(), you will see that there are no regular expressions any more. Some other improvements should boost performance too. By reviewing the the old date_i18n() I recognised that escaping of literals in the date format string was not handled properly (regex are wrong). Can some please check this too? What do you think about my patch?

Replying to Rarst:
I will mark the ticket as "dev-feedback". I do not exactly know the procedure to get a patch accepted. Therefore a trusted developer should review the ticket/patch, right?

Anyway, the original date_i18n() is not implemented very well – there are the mentioned bugs, the bad performance (regex), few comments and it’s not very readable. So rewriting this function is necessary in my opinion.

Someone really should review my code and fix possible issues. I will create further tests for my patch …

Edit: Fixing the slashes issues in original date_i18n() might be bad because one needs more complex regex (something like /(?<!\\)(?:\\\\)*D/ which has negative look-behind).

Edit: 'S' should not be translated. It’s just the English ordinal suffix (st, nd, rd or th) for the day of the month (simple translation is not enough, so it has to be implemented completely new. See ​http://en.wikipedia.org/wiki/Ordinal_indicator)

Summary
changed from date_i18n() produces invalid output for shorthand formats to date_i18n() is wrong for certain formats, escapes sequences and daylight saving time

Beside the format and escaping issue I found another issue maybe:

/*
* Test is called in time zone Europe/Berlin at a date where daylight saving time is off!
* (Daylight saving time in Europe/Berlin was switched off at 2013-10-27)
*/
// results 2013-10-29T22:15:03+01:00 while daylight saving time (Europe/Berlin) is off; result is correct
echo(date_i18n('Y-m-d\TH:i:sP', 1383084903));
// results 2013-10-11T19:37:20+01:00 while daylight saving time (Europe/Berlin) is on; result is wrong! should be +02:00!
echo(date_i18n('Y-m-d\TH:i:sP', 1381520240));

As you can see the time zone offset is sometimes wrong. Actually it depends on the current daylight saving time.

Is issue comes from wordpress\wp-includes\functions.php:127 in date_i18n():

$date_object = date_create( null, $timezone_object );

The date object created with the current time stamp ("null = now"). This is wrong. It has to be created with the time stamp from date_i18n() parameter $unixtimestamp.

For now we have 3 issues at date_i18n() which is annoying (at least for my German blogs). I set the severity of this ticket to "major" and changed the summary according the 3 issues.

I tested the daylight saving time issue with my patch. It worked! I think some core developer really should have a look at this ticket. And it would be nice if other people could test my patch. Thx!

This bug has been around for at least 4 years now. Is there any chance at least the fix for 'c' could be added to core? Wanting to output an ISO 8601 date string for a post is very common (structured data, metadata, etc), and it's strange that in order to do so anywhere within WordPress, you need to use 'Y-m-d\TH:i:sP' instead of 'c' (and only after lots of debugging / searching, as the Wordpress documentation itself says to use 'c':