Index: /trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java	(revision 5716)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java	(revision 5717)
@@ -17,4 +17,5 @@
 import java.text.DateFormat;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.LinkedList;
 import java.util.List;
@@ -91,7 +92,7 @@
 
     /**
-     * returns a human readable string that shows the timespan of the given track
+     * returns minimum and maximum timestamps in the track
      */
-    public static String getTimespanForTrack(GpxTrack trk) {
+    public static Date[] getMinMaxTimeForTrack(GpxTrack trk) {
         WayPoint earliest = null, latest = null;
 
@@ -109,22 +110,50 @@
             }
         }
-
+        if (earliest==null || latest==null) return null;
+        return new Date[]{earliest.getTime(), latest.getTime()};
+    }
+    
+    /**
+    * returns minimum and maximum timestamps for all tracks
+    */
+    public Date[] getMinMaxTimeForAllTracks() {
+        double min=Double.MIN_VALUE, max=Double.MAX_VALUE, t;
+        for (GpxTrack trk: data.tracks) {
+            for (GpxTrackSegment seg : trk.getSegments()) {
+                for (WayPoint pnt : seg.getWayPoints()) {
+                    t = pnt.time;
+                    if (t!=0) {
+                        if (t>max) max=t;
+                        if (t<min) min=t;
+                    }
+                }
+            }
+        }
+        if (min==Double.MIN_VALUE || max==Double.MAX_VALUE) return null;
+        return new Date[]{new Date((long) (min * 1000)), new Date((long) (max * 1000)), };
+    }
+    
+    
+    /**
+     * returns a human readable string that shows the timespan of the given track
+     */
+    public static String getTimespanForTrack(GpxTrack trk) {
+        Date[] bounds = getMinMaxTimeForTrack(trk);
         String ts = "";
-
-        if (earliest != null && latest != null) {
+        if (bounds != null) {
             DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
-            String earliestDate = df.format(earliest.getTime());
-            String latestDate = df.format(latest.getTime());
+            String earliestDate = df.format(bounds[0]);
+            String latestDate = df.format(bounds[1]);
 
             if (earliestDate.equals(latestDate)) {
                 DateFormat tf = DateFormat.getTimeInstance(DateFormat.SHORT);
                 ts += earliestDate + " ";
-                ts += tf.format(earliest.getTime()) + " - " + tf.format(latest.getTime());
+                ts += tf.format(bounds[0]) + " - " + tf.format(bounds[1]);
             } else {
                 DateFormat dtf = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
-                ts += dtf.format(earliest.getTime()) + " - " + dtf.format(latest.getTime());
-            }
-
-            int diff = (int) (latest.time - earliest.time);
+                ts += dtf.format(bounds[0]) + " - " + dtf.format(bounds[1]);
+            }
+
+            int diff = (int) (bounds[1].getTime() - bounds[0].getTime());
             ts += String.format(" (%d:%02d)", diff / 3600, (diff % 3600) / 60);
         }
@@ -300,4 +329,18 @@
         else
             return true;
+    }
+    
+    public void filterTracksByDate(Date fromDate, Date toDate, boolean showWithoutDate) {
+        int i = 0;
+        long from = fromDate.getTime();
+        long to = toDate.getTime();
+        for (GpxTrack trk : data.tracks) {
+            Date[] t = GpxLayer.getMinMaxTimeForTrack(trk);
+            
+            if (t==null) continue;
+            long tm = t[1].getTime();
+            trackVisibility[i]= (tm==0 && showWithoutDate) || (from<=tm && tm <= to);
+            i++;
+        }
     }
 
@@ -839,3 +882,4 @@
         return SaveActionBase.createAndOpenSaveFileChooser(tr("Save GPX file"), GpxImporter.FILE_FILTER);
     }
+    
 }
Index: /trunk/src/org/openstreetmap/josm/gui/layer/gpx/ChooseTrackVisibilityAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/gpx/ChooseTrackVisibilityAction.java	(revision 5716)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/gpx/ChooseTrackVisibilityAction.java	(revision 5717)
@@ -9,12 +9,23 @@
 import java.awt.event.MouseEvent;
 import java.awt.event.MouseListener;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.GregorianCalendar;
 import java.util.Map;
 import javax.swing.AbstractAction;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
 import javax.swing.JComponent;
 import javax.swing.JLabel;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
+import javax.swing.JSlider;
+import javax.swing.JSpinner;
 import javax.swing.JTable;
 import javax.swing.ListSelectionModel;
+import javax.swing.SpinnerDateModel;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
 import javax.swing.event.ListSelectionEvent;
 import javax.swing.event.ListSelectionListener;
@@ -38,4 +49,10 @@
 public class ChooseTrackVisibilityAction extends AbstractAction {
     private final GpxLayer layer;
+ 
+    JTable table;
+    JDateWithSlider dateFrom = new JDateWithSlider(tr("From"));
+    JDateWithSlider dateTo = new JDateWithSlider(tr("To"));
+    JCheckBox checkBox  = new JCheckBox(tr("No timestamp"));
+    private boolean showNoTimestamp;
     
     public ChooseTrackVisibilityAction(final GpxLayer layer) {
@@ -114,7 +131,13 @@
         return t;
     }
-
+    
+    boolean noUpdates=false;
+    
+    private void filterTracksByDate() {
+        layer.filterTracksByDate(dateFrom.getDate(), dateTo.getDate(), checkBox.isSelected());
+    }
+    
     /** selects all rows (=tracks) in the table that are currently visible */
-    private void selectVisibleTracksInTable(JTable table) {
+    private void selectVisibleTracksInTable() {
         // don't select any tracks if the layer is not visible
         if (!layer.isVisible()) {
@@ -131,5 +154,5 @@
 
     /** listens to selection changes in the table and redraws the map */
-    private void listenToSelectionChanges(JTable table) {
+    private void listenToSelectionChanges() {
         table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
             @Override
@@ -138,27 +161,74 @@
                     return;
                 }
-                ListSelectionModel s = (ListSelectionModel) e.getSource();
-                for (int i = 0; i < layer.trackVisibility.length; i++) {
-                    layer.trackVisibility[i] = s.isSelectedIndex(i);
-                }
-                Main.map.mapView.preferenceChanged(null);
-                Main.map.repaint(100);
+                if (!noUpdates) updateVisibilityFromTable();
             }
         });
     }
-
+    
+    private void updateVisibilityFromTable() {
+        ListSelectionModel s = (ListSelectionModel) table.getSelectionModel();
+        for (int i = 0; i < layer.trackVisibility.length; i++) {
+            layer.trackVisibility[i] = s.isSelectedIndex(i);
+            System.out.printf("changed %d:=%s", i, ""+layer.trackVisibility[i]);
+        }
+        Main.map.mapView.preferenceChanged(null);
+        Main.map.repaint(100);
+    }
+    
+    private static final String PREF_DATE0 = "gpx.traces.showzerotimestamp";
+    private static final String PREF_DATE1 = "gpx.traces.mintime";
+    private static final String PREF_DATE2 = "gpx.traces.maxtime";
+    
     @Override
     public void actionPerformed(ActionEvent arg0) {
         final JPanel msg = new JPanel(new GridBagLayout());
+        
+        final Date startTime, endTime;
+        Date[] bounds = layer.getMinMaxTimeForAllTracks();
+        
+        startTime = (bounds==null) ? new GregorianCalendar(2000, 1, 1).getTime():bounds[0];
+        endTime = (bounds==null) ? new Date() : bounds[2];
+
+        long d1 = Main.pref.getLong(PREF_DATE1, 0);
+        if (d1==0) d1=new GregorianCalendar(2000, 1, 1).getTime().getTime();
+        long d2 = Main.pref.getLong(PREF_DATE2, 0);
+        if (d2==0) d2=System.currentTimeMillis();
+        
+        dateFrom.setValue(new Date(d1)); 
+        dateTo.setValue(new Date(d2)); 
+        dateFrom.setRange(startTime, endTime); 
+        dateTo.setRange(startTime, endTime); 
+        checkBox.setSelected(Main.pref.getBoolean(PREF_DATE0, true));
+        
+        JButton selectDate = new JButton();
+        msg.add(selectDate, GBC.std().grid(1,1).insets(0, 0, 20, 0));
+        msg.add(checkBox, GBC.std().grid(2,1).insets(0, 0, 20, 0));
+        msg.add(dateFrom, GBC.std().grid(3,1).fill(GBC.HORIZONTAL));
+        msg.add(dateTo, GBC.eol().grid(4,1).fill(GBC.HORIZONTAL));
         msg.add(new JLabel(tr("<html>Select all tracks that you want to be displayed. You can drag select a " + "range of tracks or use CTRL+Click to select specific ones. The map is updated live in the " + "background. Open the URLs by double clicking them.</html>")), GBC.eol().fill(GBC.HORIZONTAL));
         // build table
         final boolean[] trackVisibilityBackup = layer.trackVisibility.clone();
         final String[] headers = {tr("Name"), tr("Description"), tr("Timespan"), tr("Length"), tr("URL")};
-        final JTable table = buildTable(headers, buildTableContents());
-        selectVisibleTracksInTable(table);
-        listenToSelectionChanges(table);
+        table = buildTable(headers, buildTableContents());
+        selectVisibleTracksInTable();
+        listenToSelectionChanges();
         // make the table scrollable
         JScrollPane scrollPane = new JScrollPane(table);
         msg.add(scrollPane, GBC.eol().fill(GBC.BOTH));
+        
+        selectDate.setAction(new AbstractAction(tr("Select by date")) {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                Main.pref.putLong(PREF_DATE1, dateFrom.getDate().getTime());
+                Main.pref.putLong(PREF_DATE2, dateTo.getDate().getTime());
+                Main.pref.put(PREF_DATE0, checkBox.isSelected());
+                noUpdates = true;
+                filterTracksByDate();
+                selectVisibleTracksInTable();
+                noUpdates = false;
+                updateVisibilityFromTable();
+            }
+        });
+        
         // build dialog
         ExtendedDialog ed = new ExtendedDialog(Main.parent, tr("Set track visibility for {0}", layer.getName()), new String[]{tr("Show all"), tr("Show selected only"), tr("Cancel")});
@@ -191,3 +261,53 @@
     }
     
+    
+    public static class JDateWithSlider extends JPanel {
+        private JSpinner spinner;
+        private JSlider slider;
+        private Date dateMin;
+        private Date dateMax;
+        private static final int MAX_SLIDER=300;
+
+        public JDateWithSlider(String msg) {
+            super(new GridBagLayout());
+            spinner = new JSpinner( new SpinnerDateModel() );
+            String pattern = ((SimpleDateFormat)DateFormat.getDateInstance()).toPattern();
+            JSpinner.DateEditor timeEditor = new JSpinner.DateEditor(spinner,pattern);
+            spinner.setEditor(timeEditor);
+            slider = new JSlider(0,MAX_SLIDER);
+            slider.addChangeListener(new ChangeListener() {
+                public void stateChanged(ChangeEvent e) {
+                    spinner.setValue(dateFromInt(slider.getValue()));
+                }
+            });
+            add(new JLabel(msg),GBC.std());
+            add(spinner,GBC.std().insets(10,0,0,0));
+            add(slider,GBC.eol().insets(10,0,0,0).fill(GBC.HORIZONTAL));
+            
+            dateMin = new Date(0); dateMax =new Date();
+        }
+
+        private Date dateFromInt(int value) {
+            double k = 1.0*value/MAX_SLIDER;
+            return new Date((long)(dateMax.getTime()*k+ dateMin.getTime()*(1-k)));
+        }
+        private int intFromDate(Date date) {
+            return (int)(300.0*(date.getTime()-dateMin.getTime()) /
+                    (dateMax.getTime()-dateMin.getTime()));
+        }
+
+        private void setRange(Date dateMin, Date dateMax) {
+            this.dateMin = dateMin;
+            this.dateMax = dateMax;
+        }
+        
+        private void setValue(Date date) {
+            spinner.setValue(date);
+        }
+
+        private Date getDate() {
+            return (Date) spinner.getValue();
+        }
+    }
+   
 }
