Index: /trunk/src/org/openstreetmap/josm/actions/relation/ExportRelationToGpxAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/relation/ExportRelationToGpxAction.java	(revision 14433)
+++ /trunk/src/org/openstreetmap/josm/actions/relation/ExportRelationToGpxAction.java	(revision 14434)
@@ -21,4 +21,5 @@
 import java.util.Set;
 import java.util.Stack;
+import java.util.concurrent.TimeUnit;
 
 import org.openstreetmap.josm.actions.GpxExportAction;
@@ -174,5 +175,5 @@
         GpxData gpxData = new GpxData();
         String layerName = " (GPX export)";
-        long time = System.currentTimeMillis()-24*3600*1000;
+        long time = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()) - 24*3600;
 
         if (!flat.isEmpty()) {
@@ -197,6 +198,8 @@
                             Relation r = Way.getParentRelations(Arrays.asList(flat.get(i).getWay()))
                                     .stream().filter(relsFound::contains).findFirst().orElseGet(null);
-                            if (r != null)
+                            if (r != null) {
                                 trkAttr.put("name", r.getName() != null ? r.getName() : r.getId());
+                                trkAttr.put("desc", tr("based on osm route relation data, timestamps are synthetic"));
+                            }
                             GpxData.ensureUniqueName(trkAttr, names);
                         }
@@ -205,6 +208,6 @@
                             Collections.reverse(ln);
                         for (Node n: ln) {
-                            trkseg.add(OsmDataLayer.nodeToWayPoint(n, time));
-                            time += 1000;
+                            trkseg.add(OsmDataLayer.nodeToWayPoint(n, TimeUnit.SECONDS.toMillis(time)));
+                            time += 1;
                         }
                     }
Index: /trunk/src/org/openstreetmap/josm/data/gpx/WayPoint.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/gpx/WayPoint.java	(revision 14433)
+++ /trunk/src/org/openstreetmap/josm/data/gpx/WayPoint.java	(revision 14434)
@@ -129,5 +129,5 @@
 
     /**
-     * Sets the {@link #time} field as well as the {@link #PT_TIME} attribute to the specified time
+     * Sets the {@link #time} field as well as the {@link #PT_TIME} attribute to the specified time.
      *
      * @param time the time to set
@@ -140,6 +140,9 @@
 
     /**
-     * Convert the time stamp of the waypoint into seconds from the epoch
-     */
+     * Convert the time stamp of the waypoint into seconds from the epoch.
+     *
+     * @deprecated call {@link #setTimeFromAttribute()} directly if you need this
+     */
+    @Deprecated
     public void setTime() {
         setTimeFromAttribute();
@@ -147,10 +150,23 @@
 
     /**
-     * Set the the time stamp of the waypoint into seconds from the epoch,
-     * @param time millisecond from the epoch
+     * Sets the {@link #time} field as well as the {@link #PT_TIME} attribute to the specified time.
+     *
+     * @param ts seconds from the epoch
      * @since 13210
      */
-    public void setTime(long time) {
-        this.time = time / 1000.;
+    public void setTime(long ts) {
+        this.time = ts;
+        this.attr.put(PT_TIME, DateUtils.fromTimestamp(ts));
+    }
+
+    /**
+     * Sets the {@link #time} field as well as the {@link #PT_TIME} attribute to the specified time.
+     *
+     * @param ts milliseconds from the epoch
+     * @since 14434
+     */
+    public void setTimeInMillis(long ts) {
+        this.time = ts / 1000.;
+        this.attr.put(PT_TIME, DateUtils.fromTimestampInMillis(ts));
     }
 
Index: /trunk/src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java	(revision 14433)
+++ /trunk/src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java	(revision 14434)
@@ -193,4 +193,8 @@
     protected int changesetId;
 
+    /**
+     * A time value, measured in seconds from the epoch, or in other words,
+     * a number of seconds that have passed since 1970-01-01T00:00:00Z
+     */
     protected int timestamp;
 
@@ -327,5 +331,5 @@
     @Override
     public Date getTimestamp() {
-        return new Date(TimeUnit.SECONDS.toMillis(timestamp));
+        return new Date(TimeUnit.SECONDS.toMillis(Integer.toUnsignedLong(timestamp)));
     }
 
Index: /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 14433)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 14434)
@@ -781,10 +781,10 @@
      */
     public static WayPoint nodeToWayPoint(Node n) {
-        return nodeToWayPoint(n, 0);
+        return nodeToWayPoint(n, Long.MIN_VALUE);
     }
 
     /**
      * @param n the {@code Node} to convert
-     * @param time a time value in milliseconds from the epoch.
+     * @param time a timestamp value in milliseconds from the epoch.
      * @return {@code WayPoint} object
      * @since 13210
@@ -798,13 +798,10 @@
 
         try {
-            if (time > 0) {
-                wpt.put(GpxConstants.PT_TIME, DateUtils.fromTimestamp(time));
-                wpt.setTime(time);
+            if (time > Long.MIN_VALUE) {
+                wpt.setTimeInMillis(time);
             } else if (n.hasKey(GpxConstants.PT_TIME)) {
-                wpt.put(GpxConstants.PT_TIME, DateUtils.fromString(n.get(GpxConstants.PT_TIME)));
-                wpt.setTime();
+                wpt.setTime(DateUtils.fromString(n.get(GpxConstants.PT_TIME)));
             } else if (!n.isTimestampEmpty()) {
-                wpt.put(GpxConstants.PT_TIME, DateUtils.fromTimestamp(n.getRawTimestamp()));
-                wpt.setTime();
+                wpt.setTime(Integer.toUnsignedLong(n.getRawTimestamp()));
             }
         } catch (UncheckedParseException e) {
Index: /trunk/src/org/openstreetmap/josm/io/GpxReader.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/GpxReader.java	(revision 14433)
+++ /trunk/src/org/openstreetmap/josm/io/GpxReader.java	(revision 14434)
@@ -445,5 +445,5 @@
                 case "desc":
                     currentWayPoint.put(localName, accumulator.toString());
-                    currentWayPoint.setTime();
+                    currentWayPoint.setTimeFromAttribute();
                     break;
                 case "rtept":
Index: /trunk/src/org/openstreetmap/josm/io/nmea/NmeaReader.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/nmea/NmeaReader.java	(revision 14433)
+++ /trunk/src/org/openstreetmap/josm/io/nmea/NmeaReader.java	(revision 14434)
@@ -525,5 +525,5 @@
             if (ps.pWp != currentwp) {
                 if (ps.pWp != null) {
-                    ps.pWp.setTime();
+                    ps.pWp.setTimeFromAttribute();
                 }
                 ps.pWp = currentwp;
Index: /trunk/src/org/openstreetmap/josm/tools/date/DateUtils.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/tools/date/DateUtils.java	(revision 14433)
+++ /trunk/src/org/openstreetmap/josm/tools/date/DateUtils.java	(revision 14434)
@@ -153,6 +153,16 @@
      * @since 14055
      */
-    public static synchronized String fromTimestamp(long timestamp) {
-        final ZonedDateTime temporal = Instant.ofEpochMilli(TimeUnit.SECONDS.toMillis(timestamp)).atZone(ZoneOffset.UTC);
+    public static String fromTimestamp(long timestamp) {
+        return fromTimestampInMillis(TimeUnit.SECONDS.toMillis(timestamp));
+    }
+
+    /**
+     * Formats a date to the XML UTC format regardless of current locale.
+     * @param timestamp number of milliseconds since the epoch
+     * @return The formatted date
+     * @since 14434
+     */
+    public static synchronized String fromTimestampInMillis(long timestamp) {
+        final ZonedDateTime temporal = Instant.ofEpochMilli(timestamp).atZone(ZoneOffset.UTC);
         return DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(temporal);
     }
@@ -164,5 +174,5 @@
      */
     public static synchronized String fromTimestamp(int timestamp) {
-        return fromTimestamp((long) timestamp);
+        return fromTimestamp(Integer.toUnsignedLong(timestamp));
     }
 
