Index: trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java	(revision 9741)
+++ trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java	(revision 9742)
@@ -35,4 +35,5 @@
 import java.util.Hashtable;
 import java.util.List;
+import java.util.Locale;
 import java.util.Objects;
 import java.util.TimeZone;
@@ -869,19 +870,8 @@
         public void actionPerformed(ActionEvent arg0) {
 
-            long diff = delta.getSeconds() + Math.round(timezone.getHours() * 60 * 60);
-
-            double diffInH = (double) diff/(60*60);    // hours
-
-            // Find day difference
-            final int dayOffset = (int) Math.round(diffInH / 24); // days
-            double tmz = diff - dayOffset*24*60*60L;  // seconds
-
-            // In hours, rounded to two decimal places
-            tmz = (double) Math.round(tmz*100/(60*60)) / 100;
-
-            // Due to imprecise clocks we might get a "+3:28" timezone, which should obviously be 3:30 with
-            // -2 minutes offset. This determines the real timezone and finds offset.
-            double fixTimezone = (double) Math.round(tmz * 2)/2; // hours, rounded to one decimal place
-            int offset = (int) Math.round(diff - fixTimezone*60*60) - dayOffset*24*60*60; // seconds
+            final Offset offset = Offset.milliseconds(
+                    delta.getMilliseconds() + Math.round(timezone.getHours() * 60 * 60 * 1000));
+            final int dayOffset = offset.getDayOffset();
+            final Pair<Timezone, Offset> timezoneOffsetPair = offset.withoutDayOffset().splitOutTimezone();
 
             // Info Labels
@@ -895,9 +885,7 @@
             Dictionary<Integer, JLabel> labelTable = new Hashtable<>();
             // CHECKSTYLE.OFF: ParenPad
-            labelTable.put(-24, new JLabel("-12:00"));
-            labelTable.put(-12, new JLabel( "-6:00"));
-            labelTable.put(  0, new JLabel(  "0:00"));
-            labelTable.put( 12, new JLabel(  "6:00"));
-            labelTable.put( 24, new JLabel( "12:00"));
+            for (int i = -12; i <= 12; i += 6) {
+                labelTable.put(i * 2, new JLabel(new Timezone(i).formatTimezone()));
+            }
             // CHECKSTYLE.ON: ParenPad
             sldTimezone.setLabelTable(labelTable);
@@ -911,7 +899,14 @@
             // Seconds slider
             final JLabel lblSeconds = new JLabel();
-            final JSlider sldSeconds = new JSlider(-60, 60, 0);
+            final JSlider sldSeconds = new JSlider(-600, 600, 0);
             sldSeconds.setPaintLabels(true);
-            sldSeconds.setMajorTickSpacing(30);
+            labelTable = new Hashtable<>();
+            // CHECKSTYLE.OFF: ParenPad
+            for (int i = -60; i <= 60; i += 30) {
+                labelTable.put(i * 10, new JLabel(Offset.seconds(i).formatOffset()));
+            }
+            // CHECKSTYLE.ON: ParenPad
+            sldSeconds.setLabelTable(labelTable);
+            sldSeconds.setMajorTickSpacing(300);
 
             // This is called whenever one of the sliders is moved.
@@ -920,23 +915,13 @@
                 @Override
                 public void stateChanged(ChangeEvent e) {
-                    // parse slider position into real timezone
-                    double tz = Math.abs(sldTimezone.getValue());
-                    String zone = tz % 2 == 0
-                    ? (int) Math.floor(tz/2) + ":00"
-                            : (int) Math.floor(tz/2) + ":30";
-                    if (sldTimezone.getValue() < 0) {
-                        zone = '-' + zone;
-                    }
-
-                    lblTimezone.setText(tr("Timezone: {0}", zone));
+                    timezone = new Timezone(sldTimezone.getValue() / 2.);
+
+                    lblTimezone.setText(tr("Timezone: {0}", timezone.formatTimezone()));
                     lblMinutes.setText(tr("Minutes: {0}", sldMinutes.getValue()));
-                    lblSeconds.setText(tr("Seconds: {0}", sldSeconds.getValue()));
-
-                    try {
-                        timezone = Timezone.parseTimezone(zone);
-                    } catch (ParseException pe) {
-                        throw new RuntimeException(pe);
-                    }
-                    delta = Offset.seconds(sldMinutes.getValue() * 60 + sldSeconds.getValue() + 24 * 60 * 60L * dayOffset); // add the day offset
+                    lblSeconds.setText(tr("Seconds: {0}", Offset.milliseconds(100 * sldSeconds.getValue()).formatOffset()));
+
+                    delta = Offset.milliseconds(100 * sldSeconds.getValue()
+                            + 1000L * 60 * sldMinutes.getValue()
+                            + 1000L * 60 * 60 * 24 * dayOffset);
 
                     tfTimezone.getDocument().removeDocumentListener(statusBarUpdater);
@@ -972,7 +957,8 @@
             // and inform the user about it.
             try {
-                sldTimezone.setValue((int) (fixTimezone*2));
-                sldMinutes.setValue(offset / 60);
-                sldSeconds.setValue(offset % 60);
+                sldTimezone.setValue((int) (timezoneOffsetPair.a.getHours() * 2));
+                sldMinutes.setValue((int) (timezoneOffsetPair.b.getSeconds() / 60));
+                final long deciSeconds = timezoneOffsetPair.b.getMilliseconds() / 100;
+                sldSeconds.setValue((int) (deciSeconds % 60));
             } catch (Exception e) {
                 JOptionPane.showMessageDialog(Main.parent,
@@ -1016,5 +1002,5 @@
 
         // Init variables
-        long firstExifDate = imgs.get(0).getExifTime().getTime() / 1000;
+        long firstExifDate = imgs.get(0).getExifTime().getTime();
 
         long firstGPXDate = -1;
@@ -1026,5 +1012,5 @@
                         final Date parsedTime = curWp.setTimeFromAttribute();
                         if (parsedTime != null) {
-                            firstGPXDate = parsedTime.getTime() / 1000;
+                            firstGPXDate = parsedTime.getTime();
                             break outer;
                         }
@@ -1040,21 +1026,5 @@
         }
 
-        // seconds
-        long diff = firstExifDate - firstGPXDate;
-
-        double diffInH = (double) diff / (60 * 60);    // hours
-
-        // Find day difference
-        int dayOffset = (int) Math.round(diffInH / 24); // days
-        double tz = diff - dayOffset * 24 * 60 * 60L;  // seconds
-
-        // In hours, rounded to two decimal places
-        tz = (double) Math.round(tz * 100 / (60 * 60)) / 100;
-
-        // Due to imprecise clocks we might get a "+3:28" timezone, which should obviously be 3:30 with
-        // -2 minutes offset. This determines the real timezone and finds offset.
-        final double timezone = (double) Math.round(tz * 2) / 2; // hours, rounded to one decimal place
-        final long delta = Math.round(diff - timezone * 60 * 60); // seconds
-        return Pair.create(new Timezone(timezone), Offset.seconds(delta));
+        return Offset.milliseconds(firstExifDate - firstGPXDate).splitOutTimezone();
     }
 
@@ -1470,5 +1440,11 @@
 
         String formatOffset() {
-            return Long.toString(milliseconds / 1000);
+            if (milliseconds % 1000 == 0) {
+                return Long.toString(milliseconds / 1000);
+            } else if (milliseconds % 100 == 0) {
+                return String.format(Locale.ENGLISH, "%.1f", milliseconds / 1000.);
+            } else {
+                return String.format(Locale.ENGLISH, "%.3f", milliseconds / 1000.);
+            }
         }
 
@@ -1481,5 +1457,5 @@
                         offset = offset.substring(1);
                     }
-                    return Offset.seconds(Long.parseLong(offset));
+                    return Offset.milliseconds(Math.round(Double.parseDouble(offset) * 1000));
                 } catch (NumberFormatException nfe) {
                     throw new ParseException(error, 0);
@@ -1488,4 +1464,26 @@
                 return Offset.ZERO;
             }
+        }
+
+        int getDayOffset() {
+            final double diffInH = (double) getMilliseconds() / 1000. / 60 / 60; // hours
+
+            // Find day difference
+            return (int) Math.round(diffInH / 24);
+        }
+
+        Offset withoutDayOffset() {
+            return milliseconds(getMilliseconds() - getDayOffset() * 24 * 60 * 60 * 1000);
+        }
+
+        Pair<Timezone, Offset> splitOutTimezone() {
+            // In hours, rounded to two decimal places
+            double tz = (double) Math.round(withoutDayOffset().getSeconds() * 100 / (60 * 60)) / 100;
+
+            // Due to imprecise clocks we might get a "+3:28" timezone, which should obviously be 3:30 with
+            // -2 minutes offset. This determines the real timezone and finds offset.
+            final double timezone = (double) Math.round(tz * 2) / 2; // hours, rounded to one decimal place
+            final long delta = Math.round(getMilliseconds() - timezone * 60 * 60 * 1000); // milliseconds
+            return Pair.create(new Timezone(timezone), Offset.milliseconds(delta));
         }
 
