Mercurial > jhg
view src/org/tmatesoft/hg/core/HgDate.java @ 677:1c49c0cee540
Report line number at the first appearance, like 'hg annotate -l' does
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Thu, 18 Jul 2013 18:47:45 +0200 |
parents | 4252faa556cd |
children |
line wrap: on
line source
/* * 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 // // /* * The approach with available-short didn't work out as final timezone still relied * on daylight saving settings (and added/substracted hour shift according to date supplied) * E.g. 1218917104000 in zone GMT+2 (hello sample, changeset #2), results in EET timezone and 23 hours instead of 22 * String[] available = TimeZone.getAvailableIDs(-timezone * 1000); assert available != null && available.length > 0 : String.valueOf(timezone); // this is sort of hack, 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); */ int tz_hours = -timezone/3600; int tz_mins = timezone % 3600; String customId = String.format("GMT%+02d:%02d", tz_hours, tz_mins); TimeZone tz = TimeZone.getTimeZone(customId); 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()); } } }