Index: trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java	(revision 17843)
+++ trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java	(revision 17845)
@@ -33,4 +33,5 @@
 import org.openstreetmap.josm.tools.ListenerList;
 import org.openstreetmap.josm.tools.ListeningCollection;
+import org.openstreetmap.josm.tools.date.Interval;
 
 /**
@@ -718,7 +719,7 @@
      * returns minimum and maximum timestamps in the track
      * @param trk track to analyze
-     * @return  minimum and maximum dates in array of 2 elements
-     */
-    public static Instant[] getMinMaxTimeForTrack(IGpxTrack trk) {
+     * @return minimum and maximum as interval
+     */
+    public static Optional<Interval> getMinMaxTimeForTrack(IGpxTrack trk) {
         final LongSummaryStatistics statistics = trk.getSegments().stream()
                 .flatMap(seg -> seg.getWayPoints().stream())
@@ -726,6 +727,6 @@
                 .summaryStatistics();
         return statistics.getCount() == 0 || (statistics.getMin() == 0 && statistics.getMax() == 0)
-                ? null
-                : new Instant[]{Instant.ofEpochMilli(statistics.getMin()), Instant.ofEpochMilli(statistics.getMax())};
+                ? Optional.empty()
+                : Optional.of(new Interval(Instant.ofEpochMilli(statistics.getMin()), Instant.ofEpochMilli(statistics.getMax())));
     }
 
@@ -734,8 +735,8 @@
     * Warning: there are lot of track with broken timestamps,
     * so we just ignore points from future and from year before 1970 in this method
-    * @return minimum and maximum dates in array of 2 elements
+    * @return minimum and maximum as interval
     * @since 7319
     */
-    public synchronized Instant[] getMinMaxTimeForAllTracks() {
+    public synchronized Optional<Interval> getMinMaxTimeForAllTracks() {
         long now = System.currentTimeMillis();
         final LongSummaryStatistics statistics = tracks.stream()
@@ -746,6 +747,6 @@
                 .summaryStatistics();
         return statistics.getCount() == 0
-                ? new Instant[0]
-                : new Instant[]{Instant.ofEpochMilli(statistics.getMin()), Instant.ofEpochMilli(statistics.getMax())};
+                ? Optional.empty()
+                : Optional.of(new Interval(Instant.ofEpochMilli(statistics.getMin()), Instant.ofEpochMilli(statistics.getMax())));
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java	(revision 17843)
+++ trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java	(revision 17845)
@@ -40,5 +40,5 @@
 import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
-import org.openstreetmap.josm.tools.date.DateUtils;
+import org.openstreetmap.josm.tools.date.Interval;
 
 import javax.swing.AbstractAction;
@@ -53,6 +53,4 @@
 import java.io.File;
 import java.time.Instant;
-import java.time.format.DateTimeFormatter;
-import java.time.format.FormatStyle;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -157,30 +155,5 @@
      */
     public static String getTimespanForTrack(IGpxTrack trk) {
-        Instant[] bounds = GpxData.getMinMaxTimeForTrack(trk);
-        return bounds != null ? formatTimespan(bounds) : "";
-    }
-
-    /**
-     * Formats the timespan of the given track as a human readable string
-     * @param bounds The bounds to format, i.e., an array containing the min/max date
-     * @return The timespan as a string
-     */
-    public static String formatTimespan(Instant[] bounds) {
-        String ts = "";
-        DateTimeFormatter df = DateUtils.getDateFormatter(FormatStyle.SHORT);
-        String earliestDate = df.format(bounds[0]);
-        String latestDate = df.format(bounds[1]);
-
-        if (earliestDate.equals(latestDate)) {
-            DateTimeFormatter tf = DateUtils.getTimeFormatter(FormatStyle.SHORT);
-            ts += earliestDate + ' ';
-            ts += tf.format(bounds[0]) + " \u2013 " + tf.format(bounds[1]);
-        } else {
-            DateTimeFormatter dtf = DateUtils.getDateTimeFormatter(FormatStyle.SHORT, FormatStyle.MEDIUM);
-            ts += dtf.format(bounds[0]) + " \u2013 " + dtf.format(bounds[1]);
-        }
-
-        ts += String.format(" (%s)", Utils.getDurationString(bounds[1].toEpochMilli() - bounds[0].toEpochMilli()));
-        return ts;
+        return GpxData.getMinMaxTimeForTrack(trk).map(Interval::format).orElse("");
     }
 
@@ -354,8 +327,8 @@
         long to = toDate.toEpochMilli();
         for (IGpxTrack trk : data.getTracks()) {
-            Instant[] t = GpxData.getMinMaxTimeForTrack(trk);
+            Interval t = GpxData.getMinMaxTimeForTrack(trk).orElse(null);
 
             if (t == null) continue;
-            long tm = t[1].toEpochMilli();
+            long tm = t.getEnd().toEpochMilli();
             trackVisibility[i] = (tm == 0 && showWithoutDate) || (from <= tm && tm <= to);
             i++;
Index: trunk/src/org/openstreetmap/josm/gui/layer/gpx/ChooseTrackVisibilityAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/gpx/ChooseTrackVisibilityAction.java	(revision 17843)
+++ trunk/src/org/openstreetmap/josm/gui/layer/gpx/ChooseTrackVisibilityAction.java	(revision 17845)
@@ -54,4 +54,5 @@
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.OpenBrowser;
+import org.openstreetmap.josm.tools.date.Interval;
 
 /**
@@ -88,5 +89,5 @@
             String name = (String) Optional.ofNullable(attr.get(GpxConstants.GPX_NAME)).orElse("");
             String desc = (String) Optional.ofNullable(attr.get(GpxConstants.GPX_DESC)).orElse("");
-            Instant[] time = GpxData.getMinMaxTimeForTrack(trk);
+            Interval time = GpxData.getMinMaxTimeForTrack(trk).orElse(null);
             String url = (String) Optional.ofNullable(attr.get("url")).orElse("");
             tracks[i] = new Object[]{name, desc, time, trk.length(), url, trk};
@@ -140,5 +141,5 @@
         t.setRowSorter(rowSorter);
         rowSorter.setModel(model);
-        rowSorter.setComparator(2, Comparator.comparing((Instant[] d) -> d == null ? Instant.MIN : d[0]));
+        rowSorter.setComparator(2, Comparator.comparing((Interval d) -> d == null ? Instant.MIN : d.getStart()));
         rowSorter.setComparator(3, Comparator.comparingDouble(length -> (double) length));
         // default column widths
@@ -150,6 +151,6 @@
             public Component getTableCellRendererComponent(
                     JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
-                if (value instanceof Instant[]) {
-                    value = GpxLayer.formatTimespan(((Instant[]) value));
+                if (value instanceof Interval) {
+                    value = ((Interval) value).format();
                 }
                 return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
@@ -327,5 +328,5 @@
                 JComponent jc = (JComponent) c;
                 Object value = getValueAt(row, col);
-                jc.setToolTipText(col == 2 ? Arrays.toString((Instant[]) value) : String.valueOf(value));
+                jc.setToolTipText(String.valueOf(value));
                 if (content.length > row
                         && content[row].length > 5
Index: trunk/src/org/openstreetmap/josm/gui/layer/gpx/DateFilterPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/gpx/DateFilterPanel.java	(revision 17843)
+++ trunk/src/org/openstreetmap/josm/gui/layer/gpx/DateFilterPanel.java	(revision 17845)
@@ -20,4 +20,5 @@
 import org.openstreetmap.josm.spi.preferences.Config;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.date.Interval;
 
 /**
@@ -51,18 +52,10 @@
         this.layer = layer;
 
-        final Instant startTime, endTime;
-        Instant[] bounds = layer.data.getMinMaxTimeForAllTracks();
-        if (bounds.length == 0) {
-            startTime = ZonedDateTime.of(2000, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()).toInstant();
-            endTime = Instant.now();
-        } else {
-            startTime = bounds[0];
-            endTime = bounds[1];
-        }
-
-        dateFrom.setDate(startTime);
-        dateTo.setDate(endTime);
-        dateFrom.setRange(startTime, endTime);
-        dateTo.setRange(startTime, endTime);
+        Interval interval = layer.data.getMinMaxTimeForAllTracks()
+                .orElseGet(() -> new Interval(ZonedDateTime.of(2000, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()).toInstant(), Instant.now()));
+        dateFrom.setDate(interval.getStart());
+        dateTo.setDate(interval.getEnd());
+        dateFrom.setRange(interval.getStart(), interval.getEnd());
+        dateTo.setRange(interval.getStart(), interval.getEnd());
 
         add(noTimestampCb, GBC.std().grid(1, 1).insets(0, 0, 5, 0));
Index: trunk/src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java	(revision 17843)
+++ trunk/src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java	(revision 17845)
@@ -60,4 +60,5 @@
 import org.openstreetmap.josm.tools.Stopwatch;
 import org.openstreetmap.josm.tools.Utils;
+import org.openstreetmap.josm.tools.date.Interval;
 
 /**
@@ -565,12 +566,7 @@
         double now = System.currentTimeMillis()/1000.0;
         if (colored == ColorMode.TIME) {
-            Instant[] bounds = data.getMinMaxTimeForAllTracks();
-            if (bounds.length >= 2) {
-                minval = bounds[0].getEpochSecond();
-                maxval = bounds[1].getEpochSecond();
-            } else {
-                minval = 0;
-                maxval = now;
-            }
+            Interval interval = data.getMinMaxTimeForAllTracks().orElse(new Interval(Instant.EPOCH, Instant.now()));
+            minval = interval.getStart().getEpochSecond();
+            maxval = interval.getEnd().getEpochSecond();
             dateScale.setRange(minval, maxval);
         }
Index: trunk/src/org/openstreetmap/josm/tools/date/Interval.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/date/Interval.java	(revision 17845)
+++ trunk/src/org/openstreetmap/josm/tools/date/Interval.java	(revision 17845)
@@ -0,0 +1,76 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.tools.date;
+
+import org.openstreetmap.josm.tools.Utils;
+
+import java.time.Instant;
+import java.time.format.DateTimeFormatter;
+import java.time.format.FormatStyle;
+import java.util.Objects;
+
+/**
+ * A timespan defined by a start and end instant.
+ */
+public final class Interval {
+
+    private final Instant start;
+    private final Instant end;
+
+    public Interval(Instant start, Instant end) {
+        this.start = start;
+        this.end = end;
+    }
+
+    /**
+     * Returns an ISO 8601 compatible string
+     * @return an ISO 8601 compatible string
+     */
+    @Override
+    public String toString() {
+        return start + "/" + end;
+    }
+
+    /**
+     * Formats the interval of the given track as a human readable string
+     * @return The interval as a string
+     */
+    public String format() {
+        String ts = "";
+        DateTimeFormatter df = DateUtils.getDateFormatter(FormatStyle.SHORT);
+        String earliestDate = df.format(getStart());
+        String latestDate = df.format(getEnd());
+
+        if (earliestDate.equals(latestDate)) {
+            DateTimeFormatter tf = DateUtils.getTimeFormatter(FormatStyle.SHORT);
+            ts += earliestDate + ' ';
+            ts += tf.format(getStart()) + " \u2013 " + tf.format(getEnd());
+        } else {
+            DateTimeFormatter dtf = DateUtils.getDateTimeFormatter(FormatStyle.SHORT, FormatStyle.MEDIUM);
+            ts += dtf.format(getStart()) + " \u2013 " + dtf.format(getEnd());
+        }
+
+        ts += String.format(" (%s)", Utils.getDurationString(getEnd().toEpochMilli() - getStart().toEpochMilli()));
+        return ts;
+    }
+
+    public Instant getStart() {
+        return start;
+    }
+
+    public Instant getEnd() {
+        return end;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof Interval)) return false;
+        Interval interval = (Interval) o;
+        return Objects.equals(start, interval.start) && Objects.equals(end, interval.end);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(start, end);
+    }
+}
