TimeValue has a time field and a timezone field. AS per , the time field is defined to be in ISO 8601 format, (which, per spec, includes a time zone offset). The current code of TimeValue and related classes expects the ISO time string to always end in Z, indicating the time is in UTC. So, the local time actually represented by the TimeValue would be the timestamp plus the minutes in the timezone field. The corresponding conversion has to be done by all parsers and formatters.
It would probably be easier (and more consistent with out handling of quantities) to store the time as an ISO date in the time zone specified by the user, so the timezone field would only be needed to derive the UTC time (which we really need only to build the query index). This would mean much fewer occasions that require conversion, and would thus be less error prone and easier to maintain. It would also be consistent with the idea to "save what the source sais".
If we go that route, we should remove the time zone info from the time field of TimeValue, and rely on the separate timezone field to provide an offset. We could even have a special value there (e.g. false) for indicating an unknown time zone (would be treated like UTC for conversion, but not for display).
Whiteboard: u=dev c=backend p=0