Unless I'm missing something, it appears that while the time zone is being set in the associated NSCalendar instance, it is the timeZone set in the NSDateFormatter instance which is actually being used to format the time. Since the passed-in time zone is used to append the "Z" or the numeric time zone offset, the actual time seen can be a mismatch with the time zone. It appears as though the systemTimeZone or localTimeZone is being used by default.
The following program will print out different time values, even though they both appear to be using a UTC time zone, and both end up with a "Z" time zone in the string. The NSDateFormatter result is correct; ISO8601DateFormatter prints out an incorrect time (unless actually being run in a zero-offset time zone).
Unless I'm missing something, it appears that while the time zone is being set in the associated NSCalendar instance, it is the timeZone set in the NSDateFormatter instance which is actually being used to format the time. Since the passed-in time zone is used to append the "Z" or the numeric time zone offset, the actual time seen can be a mismatch with the time zone. It appears as though the systemTimeZone or localTimeZone is being used by default.
The following program will print out different time values, even though they both appear to be using a UTC time zone, and both end up with a "Z" time zone in the string. The NSDateFormatter result is correct; ISO8601DateFormatter prints out an incorrect time (unless actually being run in a zero-offset time zone).
The problem is fixed if you set unparsingFormatter.timeZone to the same value as unparsingCalendar.timeZone in the code.
This is running on MacOS 10.7; problem also observed using iOS 5.x.