Ticket #16995: josm-ticket-16995-corrupt-timestamps-when-using-ExportRelationToGpxAction-fix__without-y2038-fix.patch

File josm-ticket-16995-corrupt-timestamps-when-using-ExportRelationToGpxAction-fix__without-y2038-fix.patch, 8.7 KB (added by cmuelle8, 6 years ago)

josm-ticket-16995-corrupt-timestamps-when-using-ExportRelationToGpxAction-fixwithout-y2038-fix.patch

  • src/org/openstreetmap/josm/actions/relation/ExportRelationToGpxAction.java

     
    2020import java.util.Map;
    2121import java.util.Set;
    2222import java.util.Stack;
     23import java.util.concurrent.TimeUnit;
    2324
    2425import org.openstreetmap.josm.actions.GpxExportAction;
    2526import org.openstreetmap.josm.actions.IPrimitiveAction;
     
    173174
    174175        GpxData gpxData = new GpxData();
    175176        String layerName = " (GPX export)";
    176         long time = System.currentTimeMillis()-24*3600*1000;
     177        long time = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()) - 24*3600;
    177178
    178179        if (!flat.isEmpty()) {
    179180            Map<String, Object> trkAttr = new HashMap<>();
     
    196197                        if (trkAttr.isEmpty()) {
    197198                            Relation r = Way.getParentRelations(Arrays.asList(flat.get(i).getWay()))
    198199                                    .stream().filter(relsFound::contains).findFirst().orElseGet(null);
    199                             if (r != null)
     200                            if (r != null) {
    200201                                trkAttr.put("name", r.getName() != null ? r.getName() : r.getId());
     202                                trkAttr.put("desc", tr("based on osm route relation data, timestamps are synthetic"));
     203                            }
    201204                            GpxData.ensureUniqueName(trkAttr, names);
    202205                        }
    203206                        List<Node> ln = flat.get(i).getWay().getNodes();
    204207                        if (wct.get(i).direction == WayConnectionType.Direction.BACKWARD)
    205208                            Collections.reverse(ln);
    206209                        for (Node n: ln) {
    207                             trkseg.add(OsmDataLayer.nodeToWayPoint(n, time));
    208                             time += 1000;
     210                            trkseg.add(OsmDataLayer.nodeToWayPoint(n, TimeUnit.SECONDS.toMillis(time)));
     211                            time += 1;
    209212                        }
    210213                    }
    211214                }
  • src/org/openstreetmap/josm/data/gpx/WayPoint.java

     
    128128    }
    129129
    130130    /**
    131      * Sets the {@link #time} field as well as the {@link #PT_TIME} attribute to the specified time
     131     * Sets the {@link #time} field as well as the {@link #PT_TIME} attribute to the specified time.
    132132     *
    133133     * @param time the time to set
    134134     * @since 9383
     
    139139    }
    140140
    141141    /**
    142      * Convert the time stamp of the waypoint into seconds from the epoch
     142     * Sets the {@link #time} field as well as the {@link #PT_TIME} attribute to the specified time.
     143     *
     144     * @param ts seconds from the epoch
     145     * @since 13210
    143146     */
    144     public void setTime() {
    145         setTimeFromAttribute();
     147    public void setTime(long ts) {
     148        this.time = ts;
     149        this.attr.put(PT_TIME, DateUtils.fromTimestamp(ts));
    146150    }
    147151
    148152    /**
    149      * Set the the time stamp of the waypoint into seconds from the epoch,
    150      * @param time millisecond from the epoch
    151      * @since 13210
     153     * Sets the {@link #time} field as well as the {@link #PT_TIME} attribute to the specified time.
     154     *
     155     * @param ts milliseconds from the epoch
     156     * @since xxx
    152157     */
    153     public void setTime(long time) {
    154         this.time = time / 1000.;
     158    public void setTimeInMillis(long ts) {
     159        this.time = ts / 1000.;
     160        this.attr.put(PT_TIME, DateUtils.fromTimestampInMillis(ts));
     161    }
     162
     163    /**
     164     * Convert the time stamp of the waypoint into seconds from the epoch.
     165     *
     166     * @deprecated call {@link #setTimeFromAttribute()} directly if you need this
     167     */
     168    @Deprecated
     169    public void setTime() {
     170        setTimeFromAttribute();
    155171    }
    156172
    157173    /**
  • src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java

     
    192192     */
    193193    protected int changesetId;
    194194
     195    /**
     196     * A time value, measured in seconds from the epoch, or in other words,
     197     * a number of seconds that have passed since 1970-01-01T00:00:00Z
     198     */
    195199    protected int timestamp;
    196200
    197201    /**
  • src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java

     
    779779     * @since 13210
    780780     */
    781781    public static WayPoint nodeToWayPoint(Node n) {
    782         return nodeToWayPoint(n, 0);
     782        return nodeToWayPoint(n, Long.MIN_VALUE);
    783783    }
    784784
    785785    /**
    786786     * @param n the {@code Node} to convert
    787      * @param time a time value in milliseconds from the epoch.
     787     * @param ts a timestamp value, in milliseconds from the epoch
    788788     * @return {@code WayPoint} object
    789789     * @since 13210
    790790     */
    791     public static WayPoint nodeToWayPoint(Node n, long time) {
     791    public static WayPoint nodeToWayPoint(Node n, long ts) {
    792792        WayPoint wpt = new WayPoint(n.getCoor());
    793793
    794794        // Position info
    795795
    796796        addDoubleIfPresent(wpt, n, GpxConstants.PT_ELE);
    797797
    798         if (time > 0) {
    799             wpt.put(GpxConstants.PT_TIME, DateUtils.fromTimestamp(time));
    800             wpt.setTime(time);
     798        if (ts != Long.MIN_VALUE) {
     799            wpt.setTimeInMillis(ts);
    801800        } else if (n.hasKey(GpxConstants.PT_TIME)) {
    802             wpt.put(GpxConstants.PT_TIME, DateUtils.fromString(n.get(GpxConstants.PT_TIME)));
    803             wpt.setTime();
     801            wpt.setTime(DateUtils.fromString(n.get(GpxConstants.PT_TIME)));
    804802        } else if (!n.isTimestampEmpty()) {
    805             wpt.put(GpxConstants.PT_TIME, DateUtils.fromTimestamp(n.getRawTimestamp()));
    806             wpt.setTime();
     803            wpt.setTime(n.getRawTimestamp());
    807804        }
    808805
    809806        addDoubleIfPresent(wpt, n, GpxConstants.PT_MAGVAR);
  • src/org/openstreetmap/josm/io/GpxReader.java

     
    444444                case "cmt":
    445445                case "desc":
    446446                    currentWayPoint.put(localName, accumulator.toString());
    447                     currentWayPoint.setTime();
     447                    currentWayPoint.setTimeFromAttribute();
    448448                    break;
    449449                case "rtept":
    450450                    currentState = states.pop();
  • src/org/openstreetmap/josm/io/nmea/NmeaReader.java

     
    524524            ps.pDate = currentDate;
    525525            if (ps.pWp != currentwp) {
    526526                if (ps.pWp != null) {
    527                     ps.pWp.setTime();
     527                    ps.pWp.setTimeFromAttribute();
    528528                }
    529529                ps.pWp = currentwp;
    530530                ps.waypoints.add(currentwp);
  • src/org/openstreetmap/josm/tools/date/DateUtils.java

     
    152152     * @return The formatted date
    153153     * @since 14055
    154154     */
    155     public static synchronized String fromTimestamp(long timestamp) {
    156         final ZonedDateTime temporal = Instant.ofEpochMilli(TimeUnit.SECONDS.toMillis(timestamp)).atZone(ZoneOffset.UTC);
     155    public static String fromTimestamp(long timestamp) {
     156        return fromTimestampInMillis(TimeUnit.SECONDS.toMillis(timestamp));
     157    }
     158
     159    /**
     160     * Formats a date to the XML UTC format regardless of current locale.
     161     * @param timestamp number of milliseconds since the epoch
     162     * @return The formatted date
     163     * @since xxx
     164     */
     165    public static synchronized String fromTimestampInMillis(long timestamp) {
     166        final ZonedDateTime temporal = Instant.ofEpochMilli(timestamp).atZone(ZoneOffset.UTC);
    157167        return DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(temporal);
    158168    }
    159169