# HG changeset patch # User Artem Tikhomirov # Date 1304037472 -7200 # Node ID 644ee58c9f16743104d02dbebe0ee3a1f36b4dd3 # Parent 6a24818664913afe9bedcf9549bebb04f1bc048d Compound HgDate object to provide flexible access to change date/time information diff -r 6a2481866491 -r 644ee58c9f16 cmdline/org/tmatesoft/hg/console/ChangesetDumpHandler.java --- a/cmdline/org/tmatesoft/hg/console/ChangesetDumpHandler.java Thu Apr 28 03:55:23 2011 +0200 +++ b/cmdline/org/tmatesoft/hg/console/ChangesetDumpHandler.java Fri Apr 29 02:37:52 2011 +0200 @@ -109,7 +109,7 @@ int mx = repo.getManifest().getLocalRevision(cset.getManifestRevision()); f.format("parent: %d:%s\nparent: %d:%s\nmanifest: %d:%s\n", p1x, p1, p2x, p2, mx, cset.getManifestRevision()); } - f.format("user: %s\ndate: %s\n", cset.getUser(), cset.getDate()); + f.format("user: %s\ndate: %s\n", cset.getUser(), cset.getDate().toString()); if (!complete && verbose) { final List files = cset.getAffectedFiles(); sb.append("files: "); diff -r 6a2481866491 -r 644ee58c9f16 src/org/tmatesoft/hg/core/HgChangeset.java --- a/src/org/tmatesoft/hg/core/HgChangeset.java Thu Apr 28 03:55:23 2011 +0200 +++ b/src/org/tmatesoft/hg/core/HgChangeset.java Fri Apr 29 02:37:52 2011 +0200 @@ -95,8 +95,12 @@ public String getBranch() { return changeset.branch(); } - public String getDate() { - return changeset.dateString(); + + /** + * @return used to be String, now {@link HgDate}, use {@link HgDate#toString()} to get same result as before + */ + public HgDate getDate() { + return new HgDate(changeset.date().getTime(), changeset.timezone()); } public Nodeid getManifestRevision() { return changeset.manifest(); diff -r 6a2481866491 -r 644ee58c9f16 src/org/tmatesoft/hg/core/HgDate.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/org/tmatesoft/hg/core/HgDate.java Fri Apr 29 02:37:52 2011 +0200 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2011 TMate Software Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For information on how to redistribute this software under + * the terms of a license other than GNU General Public License + * contact TMate Software at support@hg4j.com + */ +package org.tmatesoft.hg.core; + +import java.util.Calendar; +import java.util.Formatter; +import java.util.Locale; +import java.util.TimeZone; + +/** + * Compound object to keep time and time zone of a change. Time zone is not too useful unless you'd like to indicate where + * the change was made (original hg shows date of a change in its original time zone) + * + * @author Artem Tikhomirov + * @author TMate Software Ltd. + */ +public final class HgDate implements Comparable, Cloneable { + private final long time; + private final TimeZone tzone; + + + /** + * @param millis UTC, milliseconds + * @param timezone zone offset in seconds, UTC - local == timezone. I.e. positive in the Western Hemisphere. + */ + public HgDate(long millis, int timezone) { + time = millis; + // @see http://pydoc.org/2.5.1/time.html time.timezone -- difference in seconds between UTC and local standard time + // UTC - local = timezone. local = UTC - timezone + // In Java, timezone is positive right of Greenwich, UTC+timezone = local + String[] available = TimeZone.getAvailableIDs(-timezone * 1000); + assert available != null && available.length > 0 : String.valueOf(timezone); + // this is sort of hach, I don't know another way how to get + // abbreviated name from zone offset (other than to have own mapping) + // And I can't use any id, because e.g. zone with id "US/Mountain" + // gives incorrect (according to hg cmdline) result, unlike MST or US/Arizona (all ids for zone -0700) + // use 1125044450000L to see the difference + String shortID = TimeZone.getTimeZone(available[0]).getDisplayName(false, TimeZone.SHORT); + // XXX in fact, might need to handle daylight saving time, but not sure how, + // getTimeZone(GMT-timezone*1000).inDaylightTime()? + TimeZone tz = TimeZone.getTimeZone(shortID); + tzone = tz; + } + + public long getRawTime() { + return time; + } + + /** + * @return zone object by reference, do not alter it (make own copy by {@link TimeZone#clone()}, to modify). + */ + public TimeZone getTimeZone() { + return tzone; + } + + @Override + public String toString() { + // format the same way hg does + return toString(Locale.US); + } + + public String toString(Locale l) { + Calendar c = Calendar.getInstance(getTimeZone()); + c.setTimeInMillis(getRawTime()); + Formatter f = new Formatter(new StringBuilder(), l); + f.format("%ta %> 32); + } + + @Override + protected Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException ex) { + throw new InternalError(ex.toString()); + } + } +} diff -r 6a2481866491 -r 644ee58c9f16 src/org/tmatesoft/hg/repo/HgChangelog.java --- a/src/org/tmatesoft/hg/repo/HgChangelog.java Thu Apr 28 03:55:23 2011 +0200 +++ b/src/org/tmatesoft/hg/repo/HgChangelog.java Fri Apr 29 02:37:52 2011 +0200 @@ -140,16 +140,23 @@ public Date date() { return time; } + + /** + * @return time zone value, as is, positive for Western Hemisphere. + */ + public int timezone() { + return timezone; + } public String dateString() { // XXX keep once formatted? Perhaps, there's faster way to set up calendar/time zone? StringBuilder sb = new StringBuilder(30); Formatter f = new Formatter(sb, Locale.US); - TimeZone tz = TimeZone.getTimeZone("GMT"); + TimeZone tz = TimeZone.getTimeZone(TimeZone.getAvailableIDs(timezone * 1000)[0]); // apparently timezone field records number of seconds time differs from UTC, // i.e. value to substract from time to get UTC time. Calendar seems to add // timezone offset to UTC, instead, hence sign change. - tz.setRawOffset(timezone * -1000); +// tz.setRawOffset(timezone * -1000); Calendar c = Calendar.getInstance(tz, Locale.US); c.setTime(time); f.format("%ta %