From 1b49305b6af43772d002da9a4fd81d58f067dd86 Mon Sep 17 00:00:00 2001 From: Tim Molter <tim.molter@gmail.com> Date: Mon, 14 Jan 2013 09:42:22 +0100 Subject: [PATCH] cleaned up date formatting --- .../xeiam/xchart/demo/charts/Example4.java | 2 + .../src/main/java/com/xeiam/xchart/Chart.java | 14 +++++- .../xchart/internal/chartpart/AxisTick.java | 8 +++- .../internal/misc/AxisValueFormatterUtil.java | 39 ++++++++-------- .../com/xeiam/xchart/ValueFormatTest.java | 45 +++++++++---------- 5 files changed, 64 insertions(+), 44 deletions(-) diff --git a/xchart-examples/src/main/java/com/xeiam/xchart/demo/charts/Example4.java b/xchart-examples/src/main/java/com/xeiam/xchart/demo/charts/Example4.java index 7c03d352..433e9bf1 100644 --- a/xchart-examples/src/main/java/com/xeiam/xchart/demo/charts/Example4.java +++ b/xchart-examples/src/main/java/com/xeiam/xchart/demo/charts/Example4.java @@ -21,6 +21,7 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Date; +import java.util.TimeZone; import com.xeiam.xchart.Chart; import com.xeiam.xchart.Series; @@ -67,6 +68,7 @@ public class Example4 implements ExampleChart { chart.setTitle("Example4"); chart.setXAxisTitle("time of day"); chart.setYAxisTitle("gigawatts"); + chart.setTimezone(TimeZone.getTimeZone("UTC")); Series series = chart.addDateSeries("value", xData, yData); diff --git a/xchart/src/main/java/com/xeiam/xchart/Chart.java b/xchart/src/main/java/com/xeiam/xchart/Chart.java index fc76c8b4..9d2edcbc 100644 --- a/xchart/src/main/java/com/xeiam/xchart/Chart.java +++ b/xchart/src/main/java/com/xeiam/xchart/Chart.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.Locale; +import java.util.TimeZone; import com.xeiam.xchart.internal.chartpart.AxisPair; import com.xeiam.xchart.internal.chartpart.ChartTitle; @@ -462,7 +463,7 @@ public class Chart { /** * Set the locale to use for rendering the chart * - * @param locale - the locale to use when drawing the chart + * @param locale - the locale to use when formatting Strings and dates for the axis tick labels */ public void setLocale(Locale locale) { @@ -470,4 +471,15 @@ public class Chart { this.axisPair.yAxis.axisTick.locale = locale; } + /** + * Set the timezone to use for formatting Date axis tick labels + * + * @param timezone the timezone to use when formatting date data + */ + public void setTimezone(TimeZone timezone) { + + this.axisPair.xAxis.axisTick.timezone = timezone; + this.axisPair.yAxis.axisTick.timezone = timezone; + } + } diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTick.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTick.java index dd2f5a2c..69689e57 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTick.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTick.java @@ -21,6 +21,7 @@ import java.math.BigDecimal; import java.util.LinkedList; import java.util.List; import java.util.Locale; +import java.util.TimeZone; import com.xeiam.xchart.internal.chartpart.Axis.AxisType; import com.xeiam.xchart.internal.chartpart.Axis.Direction; @@ -59,9 +60,12 @@ public class AxisTick implements IChartPart, IHideable { private int workingSpace; - /** the Locale for Date tick labels */ + /** the Locale for tick labels */ public Locale locale; + /** the TimeZone for Date tick labels */ + public TimeZone timezone; + public String normalDecimalPattern = null; public String scientificDecimalPattern = null; public String datePattern = null; @@ -254,7 +258,7 @@ public class AxisTick implements IChartPart, IHideable { } else { - return AxisValueFormatterUtil.formatDateValue(value, axis.min, axis.max, datePattern, locale); + return AxisValueFormatterUtil.formatDateValue(value, axis.min, axis.max, datePattern, locale, timezone); } } diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/misc/AxisValueFormatterUtil.java b/xchart/src/main/java/com/xeiam/xchart/internal/misc/AxisValueFormatterUtil.java index 1a6c184a..554adf9f 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/misc/AxisValueFormatterUtil.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/misc/AxisValueFormatterUtil.java @@ -26,6 +26,8 @@ import java.text.DecimalFormat; import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.Locale; +import java.util.TimeZone; +import java.util.concurrent.TimeUnit; /** * @author timmolter @@ -36,14 +38,15 @@ public class AxisValueFormatterUtil { private static final String SCIENTIFIC_DECIMAL_PATTERN = "0.##E0"; private static final String DATE_PATTERN = "HHmmss"; private static final Locale LOCALE = Locale.getDefault(); + private static final TimeZone TIMEZONE = TimeZone.getDefault(); - private static final BigDecimal SEC_SCALE = new BigDecimal(1000L); - private static final BigDecimal MIN_SCALE = new BigDecimal(1000L * 60); - private static final BigDecimal HOUR_SCALE = new BigDecimal(1000L * 60 * 60); - private static final BigDecimal DAY_SCALE = new BigDecimal(1000L * 60 * 60 * 24); - private static final BigDecimal WEEK_SCALE = new BigDecimal(1000L * 60 * 60 * 24 * 7); - private static final BigDecimal MONTH_SCALE = new BigDecimal(1000L * 60 * 60 * 24 * 31); - private static final BigDecimal YEAR_SCALE = new BigDecimal(1000L * 60 * 60 * 24 * 365); + private static final long SEC_SCALE = TimeUnit.SECONDS.toMillis(1L); + private static final long MIN_SCALE = TimeUnit.MINUTES.toMillis(1L); + private static final long HOUR_SCALE = TimeUnit.HOURS.toMillis(1L); + private static final long DAY_SCALE = TimeUnit.DAYS.toMillis(1L); + private static final long WEEK_SCALE = TimeUnit.DAYS.toMillis(1L) * 7; + private static final long MONTH_SCALE = TimeUnit.DAYS.toMillis(1L) * 31; + private static final long YEAR_SCALE = TimeUnit.DAYS.toMillis(1L) * 365; /** * Constructor @@ -93,27 +96,27 @@ public class AxisValueFormatterUtil { * @param localeOverride * @return the formatted date value as a String */ - public static String formatDateValue(BigDecimal value, BigDecimal min, BigDecimal max, String datePatternOverride, Locale localeOverride) { + public static String formatDateValue(BigDecimal value, BigDecimal min, BigDecimal max, String datePatternOverride, Locale localeOverride, TimeZone timeZoneOverride) { // intelligently set datepattern if none is given String datePattern = datePatternOverride; if (datePatternOverride == null) { datePattern = DATE_PATTERN; - BigDecimal diff = max.subtract(min); + long diff = max.subtract(min).longValue(); - if (diff.compareTo(SEC_SCALE) == -1) { + if (diff < SEC_SCALE) { datePattern = "ss:S"; - } else if (diff.compareTo(MIN_SCALE) == -1) { + } else if (diff < MIN_SCALE) { datePattern = "mm:ss"; - } else if (diff.compareTo(HOUR_SCALE) == -1) { + } else if (diff < HOUR_SCALE) { datePattern = "HH:mm"; - } else if (diff.compareTo(DAY_SCALE) == -1) { - datePattern = "dd:HH"; - } else if (diff.compareTo(WEEK_SCALE) == -1) { + } else if (diff < DAY_SCALE) { + datePattern = "EEE HH:mm"; + } else if (diff < WEEK_SCALE) { datePattern = "EEE"; - } else if (diff.compareTo(MONTH_SCALE) == -1) { + } else if (diff < MONTH_SCALE) { datePattern = "MMM-dd"; - } else if (diff.compareTo(YEAR_SCALE) == -1) { + } else if (diff < YEAR_SCALE) { datePattern = "yyyy:MMM"; } else { datePattern = "yyyy"; @@ -122,9 +125,9 @@ public class AxisValueFormatterUtil { } SimpleDateFormat simpleDateformat = new SimpleDateFormat(datePattern, localeOverride == null ? LOCALE : localeOverride); + simpleDateformat.setTimeZone(timeZoneOverride == null ? TIMEZONE : timeZoneOverride); simpleDateformat.applyPattern(datePattern); return simpleDateformat.format(value.longValueExact()); } - } diff --git a/xchart/src/test/java/com/xeiam/xchart/ValueFormatTest.java b/xchart/src/test/java/com/xeiam/xchart/ValueFormatTest.java index c8a99093..b1919546 100644 --- a/xchart/src/test/java/com/xeiam/xchart/ValueFormatTest.java +++ b/xchart/src/test/java/com/xeiam/xchart/ValueFormatTest.java @@ -26,6 +26,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import java.math.BigDecimal; import java.util.Locale; +import java.util.TimeZone; import org.junit.Test; @@ -36,9 +37,6 @@ import com.xeiam.xchart.internal.misc.AxisValueFormatterUtil; */ public class ValueFormatTest { - // private final String normalDecimalPattern = "#.####"; - // private final String scientificDecimalPattern = "0.##E0"; - // private final String datePattern = "HHmmss"; private final Locale locale = Locale.US; @Test @@ -115,61 +113,62 @@ public class ValueFormatTest { @Test public void testDateFormatting() { + TimeZone timeZone = TimeZone.getTimeZone("UTC"); + // ms BigDecimal value = new BigDecimal(1358108105531L); BigDecimal min = new BigDecimal(1358108105100L); BigDecimal max = new BigDecimal(1358108105900L); - String stringValue = AxisValueFormatterUtil.formatDateValue(value, min, max, null, locale); + String stringValue = AxisValueFormatterUtil.formatDateValue(value, min, max, null, locale, timeZone); assertThat(stringValue, equalTo("05:531")); // sec value = new BigDecimal(1358108105000L); min = new BigDecimal(1358108101000L); max = new BigDecimal(1358108109000L); - stringValue = AxisValueFormatterUtil.formatDateValue(value, min, max, null, locale); + stringValue = AxisValueFormatterUtil.formatDateValue(value, min, max, null, locale, timeZone); assertThat(stringValue, equalTo("15:05")); - // TODO this fails on a server in a different timezone. how to fix? - // // min - // value = new BigDecimal(1358111750000L); - // min = new BigDecimal(1358111690000L); - // max = new BigDecimal(1358111870000L); - // stringValue = AxisValueFormatterUtil.formatDateValue(value, min, max, null, locale); - // assertThat(stringValue, equalTo("22:15")); - // - // // hour - // value = new BigDecimal(1358111870000L); - // min = new BigDecimal(1358101070000L); - // max = new BigDecimal(1358115470000L); - // stringValue = AxisValueFormatterUtil.formatDateValue(value, min, max, null, locale); - // assertThat(stringValue, equalTo("13:22")); + // min + value = new BigDecimal(1358111750000L); + min = new BigDecimal(1358111690000L); + max = new BigDecimal(1358111870000L); + stringValue = AxisValueFormatterUtil.formatDateValue(value, min, max, null, locale, timeZone); + assertThat(stringValue, equalTo("21:15")); + + // hour + value = new BigDecimal(1358111870000L); + min = new BigDecimal(1358101070000L); + max = new BigDecimal(1358115470000L); + stringValue = AxisValueFormatterUtil.formatDateValue(value, min, max, null, locale, timeZone); + assertThat(stringValue, equalTo("Sun 21:17")); // day value = new BigDecimal(1358112317000L); min = new BigDecimal(1357939517000L); max = new BigDecimal(1358285117000L); - stringValue = AxisValueFormatterUtil.formatDateValue(value, min, max, null, locale); + stringValue = AxisValueFormatterUtil.formatDateValue(value, min, max, null, locale, timeZone); assertThat(stringValue, equalTo("Sun")); // week value = new BigDecimal(1358112317000L); min = new BigDecimal(1357075517000L); max = new BigDecimal(1359149117000L); - stringValue = AxisValueFormatterUtil.formatDateValue(value, min, max, null, locale); + stringValue = AxisValueFormatterUtil.formatDateValue(value, min, max, null, locale, timeZone); assertThat(stringValue, equalTo("Jan-13")); // month value = new BigDecimal(1358112838000L); min = new BigDecimal(1354397638000L); max = new BigDecimal(1361223238000L); - stringValue = AxisValueFormatterUtil.formatDateValue(value, min, max, null, locale); + stringValue = AxisValueFormatterUtil.formatDateValue(value, min, max, null, locale, timeZone); assertThat(stringValue, equalTo("2013:Jan")); // year value = new BigDecimal(1358113402000L); min = new BigDecimal(1263419002000L); max = new BigDecimal(1421185402000L); - stringValue = AxisValueFormatterUtil.formatDateValue(value, min, max, null, locale); + stringValue = AxisValueFormatterUtil.formatDateValue(value, min, max, null, locale, timeZone); assertThat(stringValue, equalTo("2013")); } -- GitLab