changeset 211:644ee58c9f16

Compound HgDate object to provide flexible access to change date/time information
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Fri, 29 Apr 2011 02:37:52 +0200
parents 6a2481866491
children edb2e2829352 4252faa556cd
files cmdline/org/tmatesoft/hg/console/ChangesetDumpHandler.java src/org/tmatesoft/hg/core/HgChangeset.java src/org/tmatesoft/hg/core/HgDate.java src/org/tmatesoft/hg/repo/HgChangelog.java
diffstat 4 files changed, 127 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- 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<Path> files = cset.getAffectedFiles();
 			sb.append("files:      ");
--- 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();
--- /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 <em>hg</em> shows date of a change in its original time zone) 
+ *
+ * @author Artem Tikhomirov
+ * @author TMate Software Ltd.
+ */
+public final class HgDate implements Comparable<HgDate>, 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 %<tb %<td %<tH:%<tM:%<tS %<tY %<tz", c);
+		return f.out().toString();
+	}
+
+	public int compareTo(HgDate o) {
+		return (int) (time - o.time);
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (false == obj instanceof HgDate) {
+			return false;
+		}
+		HgDate other = (HgDate) obj;
+		return compareTo(other) == 0;
+	}
+	
+	@Override
+	public int hashCode() {
+		// copied from java.util.Datge
+		return (int) time ^ (int) (time >> 32);
+	}
+
+	@Override
+	protected Object clone() {
+		try {
+			return super.clone();
+		} catch (CloneNotSupportedException ex) {
+			throw new InternalError(ex.toString());
+		}
+	}
+}
--- 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 %<tb %<td %<tH:%<tM:%<tS %<tY %<tz", c);