Index: trunk/src/org/openstreetmap/josm/actions/search/SearchAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/search/SearchAction.java	(revision 4678)
+++ trunk/src/org/openstreetmap/josm/actions/search/SearchAction.java	(revision 4679)
@@ -229,5 +229,6 @@
             /* I18n: don't translate the bold text keyword */ descriptionText.appendItem(tr("<b>tags:</b>... - objects with given number of tags (<b>tags:</b>count, <b>tags:</b>min-max, <b>tags:</b>min- or <b>tags:</b>-max)"));
             /* I18n: don't translate the bold text keyword */ descriptionText.appendItem(tr("<b>role:</b>... - objects with given role in a relation"));
-            /* I18n: don't translate the bold text keyword */ descriptionText.appendItem(tr("<b>timestamp:</b>... - objects with this timestamp (2009-11-12T14:51:09Z, 2009-11-12 or T14:51 ...)"));
+            /* I18n: don't translate the bold text keyword */ descriptionText.appendItem(tr("<b>timestamp:</b>timestamp - objects with this last modification timestamp (2009-11-12T14:51:09Z, 2009-11-12 or T14:51 ...)"));
+            /* I18n: don't translate the bold text keyword */ descriptionText.appendItem(tr("<b>timestamp:</b>min/max - objects with last modification within range"));
             /* I18n: don't translate the bold text keyword */ descriptionText.appendItem(tr("<b>areasize:</b>... - closed ways with given area in m\u00b2 (<b>areasize:</b>min-max or <b>areasize:</b>max)"));
             /* I18n: don't translate the bold text keyword */ descriptionText.appendItem(tr("<b>modified</b> - all changed objects"));
Index: trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java	(revision 4678)
+++ trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java	(revision 4679)
@@ -9,4 +9,5 @@
 import java.text.Normalizer;
 import java.util.Collection;
+import java.util.Date;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -550,13 +551,13 @@
     private abstract static class CountRange extends Match {
 
-        private int minCount;
-        private int maxCount;
-
-        public CountRange(int minCount, int maxCount) {
+        private long minCount;
+        private long maxCount;
+
+        public CountRange(long minCount, long maxCount) {
             this.minCount = Math.min(minCount, maxCount);
             this.maxCount = Math.max(minCount, maxCount);
         }
 
-        protected abstract Integer getCount(OsmPrimitive osm);
+        protected abstract Long getCount(OsmPrimitive osm);
 
         protected abstract String getCountString();
@@ -564,5 +565,5 @@
         @Override
         public boolean match(OsmPrimitive osm) {
-            Integer count = getCount(osm);
+            Long count = getCount(osm);
             if (count == null)
                 return false;
@@ -581,14 +582,14 @@
     private static class NodeCountRange extends CountRange {
 
-        public NodeCountRange(int minCount, int maxCount) {
+        public NodeCountRange(long minCount, long maxCount) {
             super(minCount, maxCount);
         }
 
         @Override
-        protected Integer getCount(OsmPrimitive osm) {
+        protected Long getCount(OsmPrimitive osm) {
             if (!(osm instanceof Way))
                 return null;
             else
-                return ((Way) osm).getNodesCount();
+                return (long) ((Way) osm).getNodesCount();
         }
 
@@ -601,11 +602,11 @@
     private static class TagCountRange extends CountRange {
 
-        public TagCountRange(int minCount, int maxCount) {
+        public TagCountRange(long minCount, long maxCount) {
             super(minCount, maxCount);
         }
 
         @Override
-        protected Integer getCount(OsmPrimitive osm) {
-            return osm.getKeys().size();
+        protected Long getCount(OsmPrimitive osm) {
+            return (long) osm.getKeys().size();
         }
 
@@ -614,4 +615,22 @@
             return "tags";
         }
+    }
+
+    private static class TimestampRange extends CountRange {
+
+        public TimestampRange(long minCount, long maxCount) {
+            super(minCount, maxCount);
+        }
+
+        @Override
+        protected Long getCount(OsmPrimitive osm) {
+            return osm.getTimestamp().getTime();
+        }
+
+        @Override
+        protected String getCountString() {
+            return "timestamp";
+        }
+
     }
 
@@ -725,14 +744,14 @@
     private static class Area extends CountRange {
 
-        public Area(int minCount, int maxCount) {
+        public Area(long minCount, long maxCount) {
             super(minCount, maxCount);
         }
 
         @Override
-        protected Integer getCount(OsmPrimitive osm) {
+        protected Long getCount(OsmPrimitive osm) {
             if (!(osm instanceof Way && ((Way) osm).isClosed()))
                 return null;
             Way way = (Way) osm;
-            return (int) Geometry.closedWayArea(way);
+            return (long) Geometry.closedWayArea(way);
         }
 
@@ -873,11 +892,25 @@
                 else if ("tags".equals(key)) {
                     Range range = tokenizer.readRange(tr("Range of numbers expected"));
-                    return new TagCountRange((int)range.getStart(), (int)range.getEnd());
+                    return new TagCountRange(range.getStart(), range.getEnd());
                 } else if ("nodes".equals(key)) {
                     Range range = tokenizer.readRange(tr("Range of numbers expected"));
-                    return new NodeCountRange((int)range.getStart(), (int)range.getEnd());
+                    return new NodeCountRange(range.getStart(), range.getEnd());
                 } else if ("areasize".equals(key)) {
                     Range range = tokenizer.readRange(tr("Range of numbers expected"));
-                    return new Area((int)range.getStart(), (int)range.getEnd());
+                    return new Area(range.getStart(), range.getEnd());
+                } else if ("timestamp".equals(key)) {
+                    String rangeS = " " + tokenizer.readTextOrNumber() + " "; // add leading/trailing space in order to get expected split (e.g. "a--" => {"a", ""})
+                    String[] rangeA = rangeS.split("/");
+                    if (rangeA.length == 1) {
+                        return new KeyValue(key, rangeS, regexSearch, caseSensitive);
+                    } else if (rangeA.length == 2) {
+                        String rangeA1 = rangeA[0].trim();
+                        String rangeA2 = rangeA[1].trim();
+                        long minDate = DateUtils.fromString(rangeA1.isEmpty() ? "1980" : rangeA1).getTime(); // if min timestap is empty: use lowest possible date
+                        long maxDate = rangeA2.isEmpty() ? new Date().getTime() : DateUtils.fromString(rangeA2).getTime(); // if max timestamp is empty: use "now"
+                        return new TimestampRange(minDate, maxDate);
+                    } else {
+                        throw new ParseError(tr("Expecting <i>min</i>/<i>max</i>'' after ''timestamp2''"));
+                    }
                 } else if ("changeset".equals(key))
                     return new ChangesetId(tokenizer.readNumber(tr("Changeset id expected")));
