diff src/org/tmatesoft/hg/core/HgDate.java @ 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
children 4252faa556cd
line wrap: on
line diff
--- /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());
+		}
+	}
+}