[general] Ensure Changeset.date always has timezone information
This patch modifies all source backends to always set the tzinfo member of
every Changeset.date they create, and all target backends to make proper use
of it at commit time. This should solve all offset errors in dates for
commits, and making tailor robust with respect implementing a "timezone"
option for a project.
Summary of the needed changes:
+ vcpx:
- tzinfo.py: new file, taken from pytz sources. Provides definitions for
two basic tzinfo classes: UTC, and FixedOffset?.
- changes.py: make "date" member a property, with a setter function that
raises an exception if the provided date does not have a not-None tzinfo
member. Prefer this to silently setting it to UTC, which may be a wrong
assumption.
+ vcpx/repository:
- [source] cvs.py, cvsps.py darcs.py, monotone.py, svn.py: Changeset.date
was always created in UTC; explicitly set date.tzinfo to UTC from
tzinfo.py.
- [source] bzr.py, git.py, hg.py: an UTC date was created from timestamp
and offset; instead, create a date in the proper FixedOffset? timezone.
- [source] tla.py: an UTC date was created from the Standard-date header;
however, a Date header with the local date is also provided: add new
function parse_date() that can calculate the timezone from these two
headers, and use it.
- [target] cvs.py, cvsps.py: str(date) was assumed not to contain timezone
information; make date a tzinfo-less datetime prior to str()'ing it.
- [target] cdv.py, darcs.py, monotone.py, svn.py: Changeset.date was
assumed to be UTC; make the appropriate conversion prior to using it.
- [target] cg.py, git.py: include "%z" in the strftime format specifier
for GIT_AUTHOR_DATE.
- [target] bzr.py, hg.py: do not use time.mktime() to calculate the
timestamp, since it takes into account local timezone; use
calendar.timegm() instead, which gives an UTC timestamp. And provide an
appropriate timezone to the underlying commit() function.
+ vcpx/tests:
- cvs.py, cvsps.py, darcs.py, svn.py: set tzinfo=UTC in datetimes that get
created to be compared to cset.date.