From: <mu...@us...> - 2008-09-01 10:29:41
|
Revision: 1398 http://jfreechart.svn.sourceforge.net/jfreechart/?rev=1398&view=rev Author: mungady Date: 2008-09-01 10:29:30 +0000 (Mon, 01 Sep 2008) Log Message: ----------- Synchronised with 1.0.x branch. Modified Paths: -------------- trunk/source/org/jfree/chart/util/RelativeDateFormat.java trunk/tests/org/jfree/chart/util/junit/RelativeDateFormatTests.java Modified: trunk/source/org/jfree/chart/util/RelativeDateFormat.java =================================================================== --- trunk/source/org/jfree/chart/util/RelativeDateFormat.java 2008-09-01 10:17:53 UTC (rev 1397) +++ trunk/source/org/jfree/chart/util/RelativeDateFormat.java 2008-09-01 10:29:30 UTC (rev 1398) @@ -6,22 +6,22 @@ * * Project Info: http://www.jfree.org/jfreechart/index.html * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * - * This library 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 Lesser General Public + * This library 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 Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. * - * [Java is a trademark or registered trademark of Sun Microsystems, Inc. + * [Java is a trademark or registered trademark of Sun Microsystems, Inc. * in the United States and other countries.] * * ----------------------- @@ -30,15 +30,17 @@ * (C) Copyright 2006-2008, by Object Refinery Limited and Contributors. * * Original Author: David Gilbert (for Object Refinery Limited); - * Contributor(s): -; + * Contributor(s): Michael Siemer; * * Changes: * -------- * 01-Nov-2006 : Version 1 (DG); - * 23-Nov-2006 : Added argument checks, updated equals(), added clone() and + * 23-Nov-2006 : Added argument checks, updated equals(), added clone() and * hashCode() (DG); - * 15-Feb-2008 : Applied patch 1873328 by elcaro01, with minor + * 15-Feb-2008 : Applied patch 1873328 by Michael Siemer, with minor * modifications (DG); + * 01-Sep-2008 : Added new fields for hour and minute formatting, based on + * patch 2033092 (DG); * */ @@ -60,56 +62,70 @@ * @since 1.0.3 */ public class RelativeDateFormat extends DateFormat { - + /** The base milliseconds for the elapsed time calculation. */ private long baseMillis; - + /** * A flag that controls whether or not a zero day count is displayed. */ private boolean showZeroDays; - + /** * A flag that controls whether or not a zero hour count is displayed. - * + * * @since 1.0.10 */ private boolean showZeroHours; - /** + /** * A formatter for the day count (most likely not critical until the - * day count exceeds 999). + * day count exceeds 999). */ private NumberFormat dayFormatter; /** - * A prefix prepended to the start of the format if the relative date is + * A prefix prepended to the start of the format if the relative date is * positive. * * @since 1.0.10 */ private String positivePrefix; - + /** * A string appended after the day count. */ private String daySuffix; - + /** + * A formatter for the hours. + * + * @since 1.0.11 + */ + private NumberFormat hourFormatter; + + /** * A string appended after the hours. */ private String hourSuffix; - + /** + * A formatter for the minutes. + * + * @since 1.0.11 + */ + private NumberFormat minuteFormatter; + + /** * A string appended after the minutes. */ private String minuteSuffix; - + /** * A formatter for the seconds (and milliseconds). */ private NumberFormat secondFormatter; - + /** * A string appended after the seconds. */ @@ -124,104 +140,106 @@ * A constant for the number of milliseconds in one day. */ private static long MILLISECONDS_IN_ONE_DAY = 24 * MILLISECONDS_IN_ONE_HOUR; - + /** - * Creates a new instance. + * Creates a new instance with base milliseconds set to zero. */ public RelativeDateFormat() { - this(0L); + this(0L); } - + /** * Creates a new instance. - * + * * @param time the date/time (<code>null</code> not permitted). */ public RelativeDateFormat(Date time) { this(time.getTime()); } - + /** * Creates a new instance. - * + * * @param baseMillis the time zone (<code>null</code> not permitted). */ public RelativeDateFormat(long baseMillis) { - super(); + super(); this.baseMillis = baseMillis; this.showZeroDays = false; this.showZeroHours = true; this.positivePrefix = ""; - this.dayFormatter = NumberFormat.getInstance(); + this.dayFormatter = NumberFormat.getNumberInstance(); this.daySuffix = "d"; + this.hourFormatter = NumberFormat.getNumberInstance(); this.hourSuffix = "h"; + this.minuteFormatter = NumberFormat.getNumberInstance(); this.minuteSuffix = "m"; this.secondFormatter = NumberFormat.getNumberInstance(); this.secondFormatter.setMaximumFractionDigits(3); this.secondFormatter.setMinimumFractionDigits(3); this.secondSuffix = "s"; - // we don't use the calendar or numberFormat fields, but equals(Object) + // we don't use the calendar or numberFormat fields, but equals(Object) // is failing without them being non-null this.calendar = new GregorianCalendar(); - this.numberFormat = new DecimalFormat("0"); + this.numberFormat = new DecimalFormat("0"); } - + /** - * Returns the base date/time used to calculate the elapsed time for + * Returns the base date/time used to calculate the elapsed time for * display. - * + * * @return The base date/time in milliseconds since 1-Jan-1970. - * + * * @see #setBaseMillis(long) */ public long getBaseMillis() { return this.baseMillis; } - + /** - * Sets the base date/time used to calculate the elapsed time for display. + * Sets the base date/time used to calculate the elapsed time for display. * This should be specified in milliseconds using the same encoding as * <code>java.util.Date</code>. - * + * * @param baseMillis the base date/time in milliseconds. - * + * * @see #getBaseMillis() */ public void setBaseMillis(long baseMillis) { this.baseMillis = baseMillis; } - + /** - * Returns the flag that controls whether or not zero day counts are + * Returns the flag that controls whether or not zero day counts are * shown in the formatted output. - * + * * @return The flag. - * + * * @see #setShowZeroDays(boolean) */ public boolean getShowZeroDays() { return this.showZeroDays; } - + /** * Sets the flag that controls whether or not zero day counts are shown * in the formatted output. - * + * * @param show the flag. - * + * * @see #getShowZeroDays() */ public void setShowZeroDays(boolean show) { this.showZeroDays = show; } - + /** - * Returns the flag that controls whether or not zero hour counts are + * Returns the flag that controls whether or not zero hour counts are * shown in the formatted output. - * + * * @return The flag. - * + * * @see #setShowZeroHours(boolean) * * @since 1.0.10 @@ -229,13 +247,13 @@ public boolean getShowZeroHours() { return this.showZeroHours; } - + /** * Sets the flag that controls whether or not zero hour counts are shown * in the formatted output. - * + * * @param show the flag. - * + * * @see #getShowZeroHours() * * @since 1.0.10 @@ -243,13 +261,13 @@ public void setShowZeroHours(boolean show) { this.showZeroHours = show; } - + /** * Returns the string that is prepended to the format if the relative time * is positive. - * + * * @return The string (never <code>null</code>). - * + * * @see #setPositivePrefix(String) * * @since 1.0.10 @@ -257,13 +275,13 @@ public String getPositivePrefix() { return this.positivePrefix; } - + /** - * Sets the string that is prepended to the format if the relative time is + * Sets the string that is prepended to the format if the relative time is * positive. - * + * * @param prefix the prefix (<code>null</code> not permitted). - * + * * @see #getPositivePrefix() * * @since 1.0.10 @@ -274,23 +292,37 @@ } this.positivePrefix = prefix; } - + /** + * Sets the formatter for the days. + * + * @param formatter the formatter (<code>null</code> not permitted). + * + * @since 1.0.11 + */ + public void setDayFormatter(NumberFormat formatter) { + if (formatter == null) { + throw new IllegalArgumentException("Null 'formatter' argument."); + } + this.dayFormatter = formatter; + } + + /** * Returns the string that is appended to the day count. - * + * * @return The string. - * + * * @see #setDaySuffix(String) */ public String getDaySuffix() { return this.daySuffix; } - + /** * Sets the string that is appended to the day count. - * + * * @param suffix the suffix (<code>null</code> not permitted). - * + * * @see #getDaySuffix() */ public void setDaySuffix(String suffix) { @@ -301,21 +333,35 @@ } /** + * Sets the formatter for the hours. + * + * @param formatter the formatter (<code>null</code> not permitted). + * + * @since 1.0.11 + */ + public void setHourFormatter(NumberFormat formatter) { + if (formatter == null) { + throw new IllegalArgumentException("Null 'formatter' argument."); + } + this.hourFormatter = formatter; + } + + /** * Returns the string that is appended to the hour count. - * + * * @return The string. - * + * * @see #setHourSuffix(String) */ public String getHourSuffix() { return this.hourSuffix; } - + /** * Sets the string that is appended to the hour count. - * + * * @param suffix the suffix (<code>null</code> not permitted). - * + * * @see #getHourSuffix() */ public void setHourSuffix(String suffix) { @@ -326,21 +372,35 @@ } /** + * Sets the formatter for the minutes. + * + * @param formatter the formatter (<code>null</code> not permitted). + * + * @since 1.0.11 + */ + public void setMinuteFormatter(NumberFormat formatter) { + if (formatter == null) { + throw new IllegalArgumentException("Null 'formatter' argument."); + } + this.minuteFormatter = formatter; + } + + /** * Returns the string that is appended to the minute count. - * + * * @return The string. - * + * * @see #setMinuteSuffix(String) */ public String getMinuteSuffix() { return this.minuteSuffix; } - + /** * Sets the string that is appended to the minute count. - * + * * @param suffix the suffix (<code>null</code> not permitted). - * + * * @see #getMinuteSuffix() */ public void setMinuteSuffix(String suffix) { @@ -352,20 +412,20 @@ /** * Returns the string that is appended to the second count. - * + * * @return The string. - * + * * @see #setSecondSuffix(String) */ public String getSecondSuffix() { return this.secondSuffix; } - + /** * Sets the string that is appended to the second count. - * + * * @param suffix the suffix (<code>null</code> not permitted). - * + * * @see #getSecondSuffix() */ public void setSecondSuffix(String suffix) { @@ -374,10 +434,10 @@ } this.secondSuffix = suffix; } - + /** * Sets the formatter for the seconds and milliseconds. - * + * * @param formatter the formatter (<code>null</code> not permitted). */ public void setSecondFormatter(NumberFormat formatter) { @@ -390,11 +450,11 @@ /** * Formats the given date as the amount of elapsed time (relative to the * base date specified in the constructor). - * + * * @param date the date. * @param toAppendTo the string buffer. * @param fieldPosition the field position. - * + * * @return The formatted date. */ public StringBuffer format(Date date, StringBuffer toAppendTo, @@ -405,11 +465,11 @@ if (elapsed < 0) { elapsed *= -1L; signPrefix = "-"; - } + } else { signPrefix = this.positivePrefix; } - + long days = elapsed / MILLISECONDS_IN_ONE_DAY; elapsed = elapsed - (days * MILLISECONDS_IN_ONE_DAY); long hours = elapsed / MILLISECONDS_IN_ONE_HOUR; @@ -423,31 +483,33 @@ toAppendTo.append(this.dayFormatter.format(days) + getDaySuffix()); } if (hours != 0 || this.showZeroHours) { - toAppendTo.append(String.valueOf(hours) + getHourSuffix()); + toAppendTo.append(this.hourFormatter.format(hours) + + getHourSuffix()); } - toAppendTo.append(String.valueOf(minutes) + getMinuteSuffix()); - toAppendTo.append(this.secondFormatter.format(seconds) + toAppendTo.append(this.minuteFormatter.format(minutes) + + getMinuteSuffix()); + toAppendTo.append(this.secondFormatter.format(seconds) + getSecondSuffix()); - return toAppendTo; + return toAppendTo; } /** * Parses the given string (not implemented). - * + * * @param source the date string. * @param pos the parse position. - * + * * @return <code>null</code>, as this method has not been implemented. */ public Date parse(String source, ParsePosition pos) { - return null; + return null; } /** * Tests this formatter for equality with an arbitrary object. - * + * * @param obj the object (<code>null</code> permitted). - * + * * @return A boolean. */ public boolean equals(Object obj) { @@ -485,20 +547,29 @@ if (!this.secondSuffix.equals(that.secondSuffix)) { return false; } + if (!this.dayFormatter.equals(that.dayFormatter)) { + return false; + } + if (!this.hourFormatter.equals(that.hourFormatter)) { + return false; + } + if (!this.minuteFormatter.equals(that.minuteFormatter)) { + return false; + } if (!this.secondFormatter.equals(that.secondFormatter)) { return false; } return true; } - + /** * Returns a hash code for this instance. - * + * * @return A hash code. */ public int hashCode() { int result = 193; - result = 37 * result + result = 37 * result + (int) (this.baseMillis ^ (this.baseMillis >>> 32)); result = 37 * result + this.positivePrefix.hashCode(); result = 37 * result + this.daySuffix.hashCode(); @@ -511,7 +582,7 @@ /** * Returns a clone of this instance. - * + * * @return A clone. */ public Object clone() { @@ -520,32 +591,32 @@ clone.secondFormatter = (NumberFormat) this.secondFormatter.clone(); return clone; } - + /** * Some test code. - * + * * @param args ignored. */ public static void main(String[] args) { GregorianCalendar c0 = new GregorianCalendar(2006, 10, 1, 0, 0, 0); GregorianCalendar c1 = new GregorianCalendar(2006, 10, 1, 11, 37, 43); c1.set(Calendar.MILLISECOND, 123); - + System.out.println("Default: "); RelativeDateFormat rdf = new RelativeDateFormat(c0.getTimeInMillis()); System.out.println(rdf.format(c1.getTime())); System.out.println(); - + System.out.println("Hide milliseconds: "); rdf.setSecondFormatter(new DecimalFormat("0")); - System.out.println(rdf.format(c1.getTime())); + System.out.println(rdf.format(c1.getTime())); System.out.println(); System.out.println("Show zero day output: "); rdf.setShowZeroDays(true); System.out.println(rdf.format(c1.getTime())); System.out.println(); - + System.out.println("Alternative suffixes: "); rdf.setShowZeroDays(false); rdf.setDaySuffix(":"); Modified: trunk/tests/org/jfree/chart/util/junit/RelativeDateFormatTests.java =================================================================== --- trunk/tests/org/jfree/chart/util/junit/RelativeDateFormatTests.java 2008-09-01 10:17:53 UTC (rev 1397) +++ trunk/tests/org/jfree/chart/util/junit/RelativeDateFormatTests.java 2008-09-01 10:29:30 UTC (rev 1398) @@ -6,22 +6,22 @@ * * Project Info: http://www.jfree.org/jfreechart/index.html * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * - * This library 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 Lesser General Public + * This library 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 Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. * - * [Java is a trademark or registered trademark of Sun Microsystems, Inc. + * [Java is a trademark or registered trademark of Sun Microsystems, Inc. * in the United States and other countries.] * * ---------------------------- @@ -36,6 +36,7 @@ * ------- * 23-Nov-2006 : Version 1 (DG); * 15-Feb-2008 : Added tests for negative dates (DG); + * 01-Sep-2008 : Added a test for hours and minutes with leading zeroes (DG); * */ @@ -73,53 +74,107 @@ public RelativeDateFormatTests(String name) { super(name); } - + /** + * Some checks for the formatting. + */ + public void testFormat() { + RelativeDateFormat rdf = new RelativeDateFormat(); + String s = rdf.format(new Date(2 * 60L * 60L * 1000L + 122500L)); + assertEquals("2h2m2.500s", s); + } + + /** + * Test that we can configure the RelativeDateFormat to show + * hh:mm:ss. + */ + public void test2033092() { + RelativeDateFormat rdf = new RelativeDateFormat(); + rdf.setShowZeroDays(false); + rdf.setShowZeroHours(false); + rdf.setMinuteSuffix(":"); + rdf.setHourSuffix(":"); + rdf.setSecondSuffix(""); + DecimalFormat hoursFormatter = new DecimalFormat(); + hoursFormatter.setMaximumFractionDigits(0); + hoursFormatter.setMaximumIntegerDigits(2); + hoursFormatter.setMinimumIntegerDigits(2); + rdf.setHourFormatter(hoursFormatter); + DecimalFormat minsFormatter = new DecimalFormat(); + minsFormatter.setMaximumFractionDigits(0); + minsFormatter.setMaximumIntegerDigits(2); + minsFormatter.setMinimumIntegerDigits(2); + rdf.setMinuteFormatter(minsFormatter); + DecimalFormat secondsFormatter = new DecimalFormat(); + secondsFormatter.setMaximumFractionDigits(0); + secondsFormatter.setMaximumIntegerDigits(2); + secondsFormatter.setMinimumIntegerDigits(2); + rdf.setSecondFormatter(secondsFormatter); + String s = rdf.format(new Date(2 * 60L * 60L * 1000L + 122500L)); + assertEquals("02:02:02", s); + } + + /** * Check that the equals() method can distinguish all fields. */ public void testEquals() { RelativeDateFormat df1 = new RelativeDateFormat(); RelativeDateFormat df2 = new RelativeDateFormat(); assertEquals(df1, df2); - + df1.setBaseMillis(123L); assertFalse(df1.equals(df2)); df2.setBaseMillis(123L); assertTrue(df1.equals(df2)); - + + df1.setDayFormatter(new DecimalFormat("0%")); + assertFalse(df1.equals(df2)); + df2.setDayFormatter(new DecimalFormat("0%")); + assertTrue(df1.equals(df2)); + df1.setDaySuffix("D"); assertFalse(df1.equals(df2)); df2.setDaySuffix("D"); assertTrue(df1.equals(df2)); - + + df1.setHourFormatter(new DecimalFormat("0%")); + assertFalse(df1.equals(df2)); + df2.setHourFormatter(new DecimalFormat("0%")); + assertTrue(df1.equals(df2)); + df1.setHourSuffix("H"); assertFalse(df1.equals(df2)); df2.setHourSuffix("H"); assertTrue(df1.equals(df2)); - + + df1.setMinuteFormatter(new DecimalFormat("0%")); + assertFalse(df1.equals(df2)); + df2.setMinuteFormatter(new DecimalFormat("0%")); + assertTrue(df1.equals(df2)); + df1.setMinuteSuffix("M"); assertFalse(df1.equals(df2)); df2.setMinuteSuffix("M"); assertTrue(df1.equals(df2)); - + df1.setSecondSuffix("S"); assertFalse(df1.equals(df2)); df2.setSecondSuffix("S"); assertTrue(df1.equals(df2)); - - df1.setShowZeroDays(!df1.getShowZeroDays()); + + df1.setShowZeroDays(!df1.getShowZeroDays()); assertFalse(df1.equals(df2)); - df2.setShowZeroDays(!df2.getShowZeroDays()); + df2.setShowZeroDays(!df2.getShowZeroDays()); assertTrue(df1.equals(df2)); - + df1.setSecondFormatter(new DecimalFormat("0.0")); assertFalse(df1.equals(df2)); df2.setSecondFormatter(new DecimalFormat("0.0")); assertTrue(df1.equals(df2)); } - + /** - * Two objects that are equal are required to return the same hashCode. + * Two objects that are equal are required to return the same hashCode. */ public void testHashCode() { RelativeDateFormat df1 = new RelativeDateFormat(123L); @@ -128,8 +183,8 @@ int h1 = df1.hashCode(); int h2 = df2.hashCode(); assertEquals(h1, h2); - } - + } + /** * Confirm that cloning works. */ @@ -142,12 +197,12 @@ assertTrue(df1 != df2); assertTrue(df1.getClass() == df2.getClass()); assertTrue(df1.equals(df2)); - + // is the clone independent nf.setMinimumFractionDigits(2); assertFalse(df1.equals(df2)); } - + /** * Some tests for negative dates. */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |