Index: /trunk/src/org/openstreetmap/josm/data/osm/Changeset.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/Changeset.java	(revision 17716)
+++ /trunk/src/org/openstreetmap/josm/data/osm/Changeset.java	(revision 17717)
@@ -4,8 +4,8 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
@@ -17,5 +17,4 @@
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
-import org.openstreetmap.josm.tools.date.DateUtils;
 
 /**
@@ -34,7 +33,7 @@
     private User user;
     /** date this changeset was created at */
-    private Date createdAt;
+    private Instant createdAt;
     /** the date this changeset was closed at*/
-    private Date closedAt;
+    private Instant closedAt;
     /** indicates whether this changeset is still open or not */
     private boolean open;
@@ -104,5 +103,5 @@
         final Changeset changeset = new Changeset(primitive.getChangesetId());
         changeset.setUser(primitive.getUser());
-        changeset.setCreatedAt(primitive.getTimestamp()); // not accurate in all cases
+        changeset.setCreatedAt(primitive.getTimestamp().toInstant()); // not accurate in all cases
         return changeset;
     }
@@ -174,6 +173,6 @@
      * @return the changeset creation date
      */
-    public Date getCreatedAt() {
-        return DateUtils.cloneDate(createdAt);
+    public Instant getCreatedAt() {
+        return createdAt;
     }
 
@@ -182,6 +181,6 @@
      * @param createdAt changeset creation date
      */
-    public void setCreatedAt(Date createdAt) {
-        this.createdAt = DateUtils.cloneDate(createdAt);
+    public void setCreatedAt(Instant createdAt) {
+        this.createdAt = createdAt;
     }
 
@@ -190,6 +189,6 @@
      * @return the changeset closure date
      */
-    public Date getClosedAt() {
-        return DateUtils.cloneDate(closedAt);
+    public Instant getClosedAt() {
+        return closedAt;
     }
 
@@ -198,6 +197,6 @@
      * @param closedAt changeset closure date
      */
-    public void setClosedAt(Date closedAt) {
-        this.closedAt = DateUtils.cloneDate(closedAt);
+    public void setClosedAt(Instant closedAt) {
+        this.closedAt = closedAt;
     }
 
@@ -427,6 +426,6 @@
             return;
         this.user = other.user;
-        this.createdAt = DateUtils.cloneDate(other.createdAt);
-        this.closedAt = DateUtils.cloneDate(other.closedAt);
+        this.createdAt = other.createdAt;
+        this.closedAt = other.closedAt;
         this.open = other.open;
         this.min = other.min;
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/AbstractCellRenderer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/AbstractCellRenderer.java	(revision 17716)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/AbstractCellRenderer.java	(revision 17717)
@@ -5,6 +5,6 @@
 
 import java.awt.Font;
-import java.text.DateFormat;
-import java.util.Date;
+import java.time.Instant;
+import java.time.format.FormatStyle;
 
 import javax.swing.JComponent;
@@ -66,9 +66,9 @@
     }
 
-    protected void renderDate(Date d) {
+    protected void renderInstant(Instant d) {
         if (d == null) {
             setText("");
         } else {
-            setText(DateUtils.formatDateTime(d, DateFormat.SHORT, DateFormat.SHORT));
+            setText(DateUtils.getDateTimeFormatter(FormatStyle.SHORT, FormatStyle.SHORT).format(d));
         }
         setToolTipText(null);
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetCacheTableCellRenderer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetCacheTableCellRenderer.java	(revision 17716)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetCacheTableCellRenderer.java	(revision 17717)
@@ -62,6 +62,6 @@
         case 2: /* open/closed */ renderOpen(cs); break;
         case 3: /* user */ renderUser(cs.getUser()); break;
-        case 4: /* created at */ renderDate(cs.getCreatedAt()); break;
-        case 5: /* closed at */ renderDate(cs.getClosedAt()); break;
+        case 4: /* created at */ renderInstant(cs.getCreatedAt()); break;
+        case 5: /* closed at */ renderInstant(cs.getClosedAt()); break;
         case 6: /* changes */ renderChanges(cs); break;
         case 7: /* discussions */ renderDiscussions(cs); break;
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetDetailPanel.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetDetailPanel.java	(revision 17716)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetDetailPanel.java	(revision 17717)
@@ -13,7 +13,8 @@
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
-import java.text.DateFormat;
+import java.time.Instant;
+import java.time.format.DateTimeFormatter;
+import java.time.format.FormatStyle;
 import java.util.Collections;
-import java.util.Date;
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -228,8 +229,8 @@
         }
         tfUser.setText(msg);
-        DateFormat sdf = DateUtils.getDateTimeFormat(DateFormat.SHORT, DateFormat.SHORT);
-
-        Date createdDate = cs.getCreatedAt();
-        Date closedDate = cs.getClosedAt();
+        DateTimeFormatter sdf = DateUtils.getDateTimeFormatter(FormatStyle.SHORT, FormatStyle.SHORT);
+
+        Instant createdDate = cs.getCreatedAt();
+        Instant closedDate = cs.getClosedAt();
         tfCreatedOn.setText(createdDate == null ? "" : sdf.format(createdDate));
         tfClosedOn.setText(closedDate == null ? "" : sdf.format(closedDate));
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetDiscussionTableCellRenderer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetDiscussionTableCellRenderer.java	(revision 17716)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetDiscussionTableCellRenderer.java	(revision 17717)
@@ -3,5 +3,5 @@
 
 import java.awt.Component;
-import java.util.Date;
+import java.time.Instant;
 
 import javax.swing.JComponent;
@@ -27,5 +27,5 @@
         switch(column) {
         case 0:
-            renderDate((Date) value);
+            renderInstant((Instant) value);
             break;
         case 1:
Index: /trunk/src/org/openstreetmap/josm/gui/io/ChangesetCellRenderer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/io/ChangesetCellRenderer.java	(revision 17716)
+++ /trunk/src/org/openstreetmap/josm/gui/io/ChangesetCellRenderer.java	(revision 17717)
@@ -5,6 +5,6 @@
 
 import java.awt.Component;
-import java.text.DateFormat;
-import java.util.Date;
+import java.time.Instant;
+import java.time.format.FormatStyle;
 
 import javax.swing.ImageIcon;
@@ -38,8 +38,8 @@
         StringBuilder sb = new StringBuilder(64);
         sb.append("<html><strong>").append(tr("Changeset id:")).append("</strong>").append(cs.getId()).append("<br>");
-        Date createdDate = cs.getCreatedAt();
+        Instant createdDate = cs.getCreatedAt();
         if (createdDate != null) {
             sb.append("<strong>").append(tr("Created at:")).append("</strong>").append(
-                    DateUtils.formatDateTime(createdDate, DateFormat.SHORT, DateFormat.SHORT)).append("<br>");
+                    DateUtils.getDateTimeFormatter(FormatStyle.SHORT, FormatStyle.SHORT).format(createdDate)).append("<br>");
         }
         String comment = cs.getComment();
Index: /trunk/src/org/openstreetmap/josm/io/ChangesetUpdater.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/ChangesetUpdater.java	(revision 17716)
+++ /trunk/src/org/openstreetmap/josm/io/ChangesetUpdater.java	(revision 17717)
@@ -57,5 +57,5 @@
         List<Long> changesetIds = ChangesetCache.getInstance().getOpenChangesets().stream()
             .filter(x -> x.getCreatedAt() != null
-                && now - x.getCreatedAt().getTime() > TimeUnit.HOURS.toMillis(1))
+                && now - x.getCreatedAt().toEpochMilli() > TimeUnit.HOURS.toMillis(1))
             .map(Changeset::getId)
             .map(Integer::longValue)
Index: /trunk/src/org/openstreetmap/josm/io/DiffResultProcessor.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/DiffResultProcessor.java	(revision 17716)
+++ /trunk/src/org/openstreetmap/josm/io/DiffResultProcessor.java	(revision 17717)
@@ -6,4 +6,5 @@
 import java.io.IOException;
 import java.io.StringReader;
+import java.time.Instant;
 import java.util.Collection;
 import java.util.Collections;
@@ -151,5 +152,6 @@
                     p.setUser(cs.getUser());
                     // TODO is there a way to obtain the timestamp for non-closed changesets?
-                    p.setTimestamp(Utils.firstNonNull(cs.getClosedAt(), new Date()));
+                    Instant instant = Utils.firstNonNull(cs.getClosedAt(), Instant.now());
+                    p.setTimestamp(Date.from(instant));
                 }
             }
Index: /trunk/src/org/openstreetmap/josm/io/OsmChangesetParser.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/OsmChangesetParser.java	(revision 17716)
+++ /trunk/src/org/openstreetmap/josm/io/OsmChangesetParser.java	(revision 17717)
@@ -96,5 +96,5 @@
                 current.setCreatedAt(null);
             } else {
-                current.setCreatedAt(DateUtils.fromString(value));
+                current.setCreatedAt(DateUtils.parseInstant(value));
             }
 
@@ -104,5 +104,5 @@
                 current.setClosedAt(null);
             } else {
-                current.setClosedAt(DateUtils.fromString(value));
+                current.setClosedAt(DateUtils.parseInstant(value));
             }
 
Index: /trunk/src/org/openstreetmap/josm/io/OsmWriter.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/OsmWriter.java	(revision 17716)
+++ /trunk/src/org/openstreetmap/josm/io/OsmWriter.java	(revision 17717)
@@ -5,8 +5,8 @@
 
 import java.io.PrintWriter;
+import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Comparator;
-import java.util.Date;
 import java.util.List;
 import java.util.Map.Entry;
@@ -299,11 +299,11 @@
             out.print(" uid='"+cs.getUser().getId() +'\'');
         }
-        Date createdDate = cs.getCreatedAt();
+        Instant createdDate = cs.getCreatedAt();
         if (createdDate != null) {
-            out.print(" created_at='"+DateUtils.fromDate(createdDate) +'\'');
-        }
-        Date closedDate = cs.getClosedAt();
+            out.print(" created_at='"+ createdDate +'\'');
+        }
+        Instant closedDate = cs.getClosedAt();
         if (closedDate != null) {
-            out.print(" closed_at='"+DateUtils.fromDate(closedDate) +'\'');
+            out.print(" closed_at='"+ closedDate +'\'');
         }
         out.print(" open='"+ (cs.isOpen() ? "true" : "false") +'\'');
Index: /trunk/test/unit/org/openstreetmap/josm/data/osm/ChangesetTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/data/osm/ChangesetTest.java	(revision 17716)
+++ /trunk/test/unit/org/openstreetmap/josm/data/osm/ChangesetTest.java	(revision 17717)
@@ -8,7 +8,7 @@
 import static org.openstreetmap.josm.data.osm.Changeset.MAX_CHANGESET_TAG_LENGTH;
 
-import java.util.Calendar;
+import java.time.Duration;
+import java.time.Instant;
 import java.util.Collection;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
@@ -138,10 +138,4 @@
     }
 
-    private static Date yesterday() {
-        final Calendar cal = Calendar.getInstance();
-        cal.add(Calendar.DATE, -1);
-        return cal.getTime();
-    }
-
     /**
      * Unit test of method {@link Changeset#hasEqualSemanticAttributes}.
@@ -149,5 +143,6 @@
     @Test
     void testHasEqualSemanticAttributes() {
-        Date today = new Date();
+        Instant today = Instant.now();
+        Instant yesterday = today.minus(Duration.ofDays(1));
         Changeset cs1 = new Changeset();
         Changeset cs2 = new Changeset();
@@ -158,5 +153,5 @@
         cs2.setClosedAt(today);
         assertFalse(cs1.hasEqualSemanticAttributes(cs2));
-        cs1.setClosedAt(yesterday());
+        cs1.setClosedAt(yesterday);
         cs2.setClosedAt(today);
         assertFalse(cs1.hasEqualSemanticAttributes(cs2));
@@ -168,5 +163,5 @@
         cs2.setCreatedAt(today);
         assertFalse(cs1.hasEqualSemanticAttributes(cs2));
-        cs1.setCreatedAt(yesterday());
+        cs1.setCreatedAt(yesterday);
         cs2.setCreatedAt(today);
         assertFalse(cs1.hasEqualSemanticAttributes(cs2));
Index: /trunk/test/unit/org/openstreetmap/josm/gui/io/ChangesetCellRendererTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/gui/io/ChangesetCellRendererTest.java	(revision 17716)
+++ /trunk/test/unit/org/openstreetmap/josm/gui/io/ChangesetCellRendererTest.java	(revision 17717)
@@ -12,4 +12,6 @@
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
+import java.time.Instant;
 
 /**
@@ -31,4 +33,5 @@
         JList<Changeset> list = new JList<>();
         Changeset cs = new Changeset();
+        cs.setCreatedAt(Instant.EPOCH);
         ChangesetCellRenderer c = new ChangesetCellRenderer();
         assertEquals(c, c.getListCellRendererComponent(list, cs, 0, false, false));
Index: /trunk/test/unit/org/openstreetmap/josm/io/OsmWriterTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/io/OsmWriterTest.java	(revision 17716)
+++ /trunk/test/unit/org/openstreetmap/josm/io/OsmWriterTest.java	(revision 17717)
@@ -11,4 +11,5 @@
 import java.io.StringWriter;
 import java.nio.charset.StandardCharsets;
+import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -16,5 +17,7 @@
 import java.util.List;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.Changeset;
@@ -24,4 +27,5 @@
 import org.openstreetmap.josm.data.osm.UploadPolicy;
 import org.openstreetmap.josm.data.osm.User;
+import org.openstreetmap.josm.testutils.JOSMTestRules;
 
 /**
@@ -29,4 +33,11 @@
  */
 class OsmWriterTest {
+
+    /**
+     * Setup rule
+     */
+    @RegisterExtension
+    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
+    public JOSMTestRules test = new JOSMTestRules();
 
     /**
@@ -107,8 +118,9 @@
         cs.setMin(new LatLon(12., 34.));
         cs.setMax(new LatLon(56., 78.));
+        cs.setCreatedAt(Instant.EPOCH);
         try (StringWriter stringWriter = new StringWriter();
              OsmWriter osmWriter = OsmWriterFactory.createOsmWriter(new PrintWriter(stringWriter), true, OsmWriter.DEFAULT_API_VERSION)) {
             osmWriter.visit(cs);
-            assertEquals("  <changeset id='38038262' user='&lt;anonymous&gt;' uid='-1' open='false' " +
+            assertEquals("  <changeset id='38038262' user='&lt;anonymous&gt;' uid='-1' created_at='1970-01-01T00:00:00Z' open='false' " +
                             "min_lon='34.0' min_lat='12.0' max_lon='78.0' max_lat='56.0'>\n  </changeset>\n",
                     stringWriter.toString().replace("\r", ""));
