Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmChangeTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmChangeTask.java	(revision 17748)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmChangeTask.java	(revision 17749)
@@ -4,4 +4,5 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+import java.time.Instant;
 import java.util.Arrays;
 import java.util.Date;
@@ -112,11 +113,11 @@
                 // A changeset does not contain all referred primitives, this is the map of incomplete ones
                 // For each incomplete primitive, we'll have to get its state at date it was referred
-                Map<OsmPrimitive, Date> toLoad = new HashMap<>();
+                Map<OsmPrimitive, Instant> toLoad = new HashMap<>();
                 for (OsmPrimitive p : downloadedData.allNonDeletedPrimitives()) {
                     if (p.isIncomplete()) {
-                        Date timestamp = p.getReferrers().stream()
+                        Instant timestamp = p.getReferrers().stream()
                                 .filter(ref -> !ref.isTimestampEmpty())
                                 .findFirst()
-                                .map(AbstractPrimitive::getTimestamp)
+                                .map(AbstractPrimitive::getInstant)
                                 .orElse(null);
                         toLoad.put(p, timestamp);
@@ -138,7 +139,7 @@
     private static final class HistoryLoaderAndListener extends HistoryLoadTask implements HistoryDataSetListener {
 
-        private final Map<OsmPrimitive, Date> toLoad;
-
-        private HistoryLoaderAndListener(Map<OsmPrimitive, Date> toLoad) {
+        private final Map<OsmPrimitive, Instant> toLoad;
+
+        private HistoryLoaderAndListener(Map<OsmPrimitive, Instant> toLoad) {
             this.toLoad = toLoad;
             this.setChangesetDataNeeded(false);
@@ -150,14 +151,14 @@
         @Override
         public void historyUpdated(HistoryDataSet source, PrimitiveId id) {
-            Map<OsmPrimitive, Date> toLoadNext = new HashMap<>();
-            for (Iterator<Entry<OsmPrimitive, Date>> it = toLoad.entrySet().iterator(); it.hasNext();) {
-                Entry<OsmPrimitive, Date> entry = it.next();
+            Map<OsmPrimitive, Instant> toLoadNext = new HashMap<>();
+            for (Iterator<Entry<OsmPrimitive, Instant>> it = toLoad.entrySet().iterator(); it.hasNext();) {
+                Entry<OsmPrimitive, Instant> entry = it.next();
                 OsmPrimitive p = entry.getKey();
                 History history = source.getHistory(p.getPrimitiveId());
-                Date date = entry.getValue();
+                Instant date = entry.getValue();
                 // If the history has been loaded and a timestamp is known
                 if (history != null && date != null) {
                     // Lookup for the primitive version at the specified timestamp
-                    HistoryOsmPrimitive hp = history.getByDate(date);
+                    HistoryOsmPrimitive hp = history.getByDate(Date.from(date));
                     if (hp != null) {
                         PrimitiveData data;
Index: trunk/src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java	(revision 17748)
+++ trunk/src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java	(revision 17749)
@@ -5,4 +5,5 @@
 
 import java.text.MessageFormat;
+import java.time.Instant;
 import java.util.Arrays;
 import java.util.Collection;
@@ -297,4 +298,5 @@
     }
 
+    @Deprecated
     @Override
     public void setTimestamp(Date timestamp) {
@@ -303,11 +305,22 @@
 
     @Override
+    public void setInstant(Instant timestamp) {
+        this.timestamp = (int) timestamp.getEpochSecond();
+    }
+
+    @Override
     public void setRawTimestamp(int timestamp) {
         this.timestamp = timestamp;
     }
 
+    @Deprecated
     @Override
     public Date getTimestamp() {
-        return new Date(TimeUnit.SECONDS.toMillis(Integer.toUnsignedLong(timestamp)));
+        return Date.from(getInstant());
+    }
+
+    @Override
+    public Instant getInstant() {
+        return Instant.ofEpochSecond(Integer.toUnsignedLong(timestamp));
     }
 
Index: trunk/src/org/openstreetmap/josm/data/osm/Changeset.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/Changeset.java	(revision 17748)
+++ trunk/src/org/openstreetmap/josm/data/osm/Changeset.java	(revision 17749)
@@ -103,5 +103,5 @@
         final Changeset changeset = new Changeset(primitive.getChangesetId());
         changeset.setUser(primitive.getUser());
-        changeset.setCreatedAt(primitive.getTimestamp().toInstant()); // not accurate in all cases
+        changeset.setCreatedAt(primitive.getInstant()); // not accurate in all cases
         return changeset;
     }
Index: trunk/src/org/openstreetmap/josm/data/osm/IPrimitive.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/IPrimitive.java	(revision 17748)
+++ trunk/src/org/openstreetmap/josm/data/osm/IPrimitive.java	(revision 17749)
@@ -2,4 +2,5 @@
 package org.openstreetmap.josm.data.osm;
 
+import java.time.Instant;
 import java.util.Date;
 import java.util.List;
@@ -276,5 +277,7 @@
      * @return date of last modification
      * @see #setTimestamp
-     */
+     * @deprecated Use {@link #getInstant}
+     */
+    @Deprecated
     Date getTimestamp();
 
@@ -284,4 +287,14 @@
      * used to check against edit conflicts.
      *
+     * @return date of last modification
+     * @see #getInstant
+     */
+    Instant getInstant();
+
+    /**
+     * Time of last modification to this object. This is not set by JOSM but
+     * read from the server and delivered back to the server unmodified. It is
+     * used to check against edit conflicts.
+     *
      * @return last modification as timestamp
      * @see #setRawTimestamp
@@ -293,6 +306,15 @@
      * @param timestamp date of last modification
      * @see #getTimestamp
-     */
+     * @deprecated Use {@link #setInstant}
+     */
+    @Deprecated
     void setTimestamp(Date timestamp);
+
+    /**
+     * Sets time of last modification to this object
+     * @param timestamp date of last modification
+     * @see #getInstant
+     */
+    void setInstant(Instant timestamp);
 
     /**
Index: trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 17748)
+++ trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 17749)
@@ -301,4 +301,5 @@
     }
 
+    @Deprecated
     @Override
     public void setTimestamp(Date timestamp) {
Index: trunk/src/org/openstreetmap/josm/data/osm/history/HistoryOsmPrimitive.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/history/HistoryOsmPrimitive.java	(revision 17748)
+++ trunk/src/org/openstreetmap/josm/data/osm/history/HistoryOsmPrimitive.java	(revision 17749)
@@ -96,5 +96,5 @@
      */
     protected HistoryOsmPrimitive(OsmPrimitive p) {
-        this(p.getId(), p.getVersion(), p.isVisible(), p.getUser(), p.getChangesetId(), p.getTimestamp());
+        this(p.getId(), p.getVersion(), p.isVisible(), p.getUser(), p.getChangesetId(), Date.from(p.getInstant()));
     }
 
@@ -364,5 +364,5 @@
             Logging.log(Logging.LEVEL_ERROR, "Cannot change visibility for "+data+':', e);
         }
-        data.setTimestamp(timestamp);
+        data.setInstant(timestamp.toInstant());
         data.setKeys(tags);
         data.setOsmId(id, (int) version);
Index: trunk/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java	(revision 17748)
+++ trunk/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java	(revision 17749)
@@ -741,5 +741,5 @@
             String mv;
             if ("timestamp".equals(key) && osm instanceof OsmPrimitive) {
-                mv = DateUtils.fromTimestamp(((OsmPrimitive) osm).getRawTimestamp());
+                mv = ((OsmPrimitive) osm).getInstant().toString();
             } else {
                 mv = osm.get(key);
@@ -1493,5 +1493,5 @@
             try {
                 // if min timestamp is empty: use lowest possible date
-                minDate = DateUtils.fromString(rangeA1.isEmpty() ? "1980" : rangeA1).getTime();
+                minDate = DateUtils.parseInstant(rangeA1.isEmpty() ? "1980" : rangeA1).toEpochMilli();
             } catch (UncheckedParseException | DateTimeException ex) {
                 throw new SearchParseError(tr("Cannot parse timestamp ''{0}''", rangeA1), ex);
@@ -1499,5 +1499,5 @@
             try {
                 // if max timestamp is empty: use "now"
-                maxDate = rangeA2.isEmpty() ? System.currentTimeMillis() : DateUtils.fromString(rangeA2).getTime();
+                maxDate = rangeA2.isEmpty() ? System.currentTimeMillis() : DateUtils.parseInstant(rangeA2).toEpochMilli();
             } catch (UncheckedParseException | DateTimeException ex) {
                 throw new SearchParseError(tr("Cannot parse timestamp ''{0}''", rangeA2), ex);
@@ -1508,5 +1508,5 @@
         @Override
         protected Long getNumber(OsmPrimitive osm) {
-            return osm.getTimestamp().getTime();
+            return osm.getInstant().toEpochMilli();
         }
 
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDataText.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDataText.java	(revision 17748)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDataText.java	(revision 17749)
@@ -154,5 +154,5 @@
         add(tr("Data Set: "), Integer.toHexString(o.getDataSet().hashCode()));
         add(tr("Edited at: "), o.isTimestampEmpty() ? tr("<new object>")
-                : DateUtils.fromTimestamp(o.getRawTimestamp()));
+                : o.getInstant().toString());
         add(tr("Edited by: "), o.getUser() == null ? tr("<new object>")
                 : getNameAndId(o.getUser().getName(), o.getUser().getId()));
Index: trunk/src/org/openstreetmap/josm/gui/history/VersionInfoPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/history/VersionInfoPanel.java	(revision 17748)
+++ trunk/src/org/openstreetmap/josm/gui/history/VersionInfoPanel.java	(revision 17749)
@@ -236,5 +236,6 @@
      */
     public void update(final OsmPrimitive primitive, final boolean isLatest) {
-        update(Changeset.fromPrimitive(primitive), isLatest, primitive.getTimestamp(), primitive.getVersion(), primitive.getPrimitiveId());
+        Date timestamp = Date.from(primitive.getInstant());
+        update(Changeset.fromPrimitive(primitive), isLatest, timestamp, primitive.getVersion(), primitive.getPrimitiveId());
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 17748)
+++ trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 17749)
@@ -24,5 +24,4 @@
 import java.io.IOException;
 import java.time.DateTimeException;
-import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -877,7 +876,7 @@
                 wpt.setTimeInMillis(time);
             } else if ((v = gpxVal(n, GpxConstants.PT_TIME)) != null) {
-                wpt.setTimeInMillis(DateUtils.tsFromString(v));
+                wpt.setInstant(DateUtils.parseInstant(v));
             } else if (!n.isTimestampEmpty()) {
-                wpt.setInstant(Instant.ofEpochSecond(Integer.toUnsignedLong(n.getRawTimestamp())));
+                wpt.setInstant(n.getInstant());
             }
         } catch (UncheckedParseException | DateTimeException e) {
Index: trunk/src/org/openstreetmap/josm/gui/layer/gpx/ConvertFromGpxLayerAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/gpx/ConvertFromGpxLayerAction.java	(revision 17748)
+++ trunk/src/org/openstreetmap/josm/gui/layer/gpx/ConvertFromGpxLayerAction.java	(revision 17749)
@@ -9,5 +9,4 @@
 import java.time.Instant;
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -135,5 +134,5 @@
                     p.put(GpxConstants.GPX_PREFIX + key, String.valueOf(date));
                 }
-                p.setTimestamp(Date.from(date));
+                p.setInstant(date);
             }
         }
Index: trunk/src/org/openstreetmap/josm/io/AbstractReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/AbstractReader.java	(revision 17748)
+++ trunk/src/org/openstreetmap/josm/io/AbstractReader.java	(revision 17749)
@@ -431,5 +431,5 @@
         }
         try {
-            int timestamp = timestampCache.computeIfAbsent(time, t -> (int) (DateUtils.tsFromString(t) / 1000));
+            int timestamp = timestampCache.computeIfAbsent(time, t -> (int) (DateUtils.parseInstant(t).getEpochSecond()));
             current.setRawTimestamp(timestamp);
         } catch (UncheckedParseException | DateTimeException e) {
Index: trunk/src/org/openstreetmap/josm/io/DiffResultProcessor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/DiffResultProcessor.java	(revision 17748)
+++ trunk/src/org/openstreetmap/josm/io/DiffResultProcessor.java	(revision 17749)
@@ -9,5 +9,4 @@
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -153,5 +152,5 @@
                     // TODO is there a way to obtain the timestamp for non-closed changesets?
                     Instant instant = Utils.firstNonNull(cs.getClosedAt(), Instant.now());
-                    p.setTimestamp(Date.from(instant));
+                    p.setInstant(instant);
                 }
             }
Index: trunk/src/org/openstreetmap/josm/io/OsmWriter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmWriter.java	(revision 17748)
+++ trunk/src/org/openstreetmap/josm/io/OsmWriter.java	(revision 17749)
@@ -366,5 +366,5 @@
             }
             if (!osm.isTimestampEmpty()) {
-                out.print(" timestamp='"+DateUtils.fromTimestamp(osm.getRawTimestamp())+'\'');
+                out.print(" timestamp='"+osm.getInstant()+'\'');
             }
             // user and visible added with 0.4 API
