diff --git a/src/org/openstreetmap/josm/data/validation/tests/OpeningHourTest.java b/src/org/openstreetmap/josm/data/validation/tests/OpeningHourTest.java
index e57b473e8..709815720 100644
--- a/src/org/openstreetmap/josm/data/validation/tests/OpeningHourTest.java
+++ b/src/org/openstreetmap/josm/data/validation/tests/OpeningHourTest.java
@@ -11,8 +11,8 @@
 import java.util.Locale;
 import java.util.Objects;
 
+import ch.poole.openinghoursparser.OpeningHoursParseException;
 import ch.poole.openinghoursparser.OpeningHoursParser;
-import ch.poole.openinghoursparser.ParseException;
 import ch.poole.openinghoursparser.Rule;
 import ch.poole.openinghoursparser.Util;
 import org.openstreetmap.josm.command.ChangePropertyCommand;
@@ -68,7 +68,7 @@ private TestError createTestError(Severity severity, String message, String key,
      * @return a list of {@link TestError} or an empty list
      */
     public List<TestError> checkOpeningHourSyntax(final String key, final String value) {
-        return checkOpeningHourSyntax(key, value, null, Locale.getDefault());
+        return checkOpeningHourSyntax(key, value, null, Locale.getDefault(), false);
     }
 
     /**
@@ -78,9 +78,10 @@ private TestError createTestError(Severity severity, String message, String key,
      * @param value the opening hour value to be checked.
      * @param p the primitive to check/fix.
      * @param locale the locale code used for localizing messages
+     * @param useHTML use HTML code for formatting the test error description
      * @return a list of {@link TestError} or an empty list
      */
-    List<TestError> checkOpeningHourSyntax(final String key, final String value, OsmPrimitive p, Locale locale) {
+    List<TestError> checkOpeningHourSyntax(final String key, final String value, OsmPrimitive p, Locale locale, boolean useHTML) {
         if (value == null || value.isEmpty()) {
             return Collections.emptyList();
         }
@@ -94,8 +95,13 @@ private TestError createTestError(Severity severity, String message, String key,
                 // parse again in strict mode for detailed message
                 new OpeningHoursParser(new StringReader(value)).rules(true);
             }
-        } catch (ParseException e) {
-            return Collections.singletonList(createTestError(Severity.WARNING, e.getMessage(), key, prettifiedValue, p));
+        } catch (OpeningHoursParseException e) {
+            String message = e.getMessage();
+            final int column = e.getColumn() - 1;
+            if (useHTML && column >= 0) {
+                message = "<html>" + value.substring(0, column) + "<span color='red'>" + value.substring(column) + "</span> – " + e.getMessage();
+            }
+            return Collections.singletonList(createTestError(Severity.WARNING, message, key, prettifiedValue, p));
         }
 
         if (!includeOtherSeverityChecks() || Objects.equals(value, prettifiedValue) || p == null) {
@@ -109,7 +115,7 @@ private TestError createTestError(Severity severity, String message, String key,
     @Override
     public void check(final OsmPrimitive p) {
         for (String key : KEYS_TO_CHECK) {
-            errors.addAll(checkOpeningHourSyntax(key, p.get(key), p, Locale.getDefault()));
+            errors.addAll(checkOpeningHourSyntax(key, p.get(key), p, Locale.getDefault(), true));
         }
     }
 }
diff --git a/test/unit/org/openstreetmap/josm/data/validation/tests/OpeningHourTestTest.java b/test/unit/org/openstreetmap/josm/data/validation/tests/OpeningHourTestTest.java
index 1d45c0804..0f20fa529 100644
--- a/test/unit/org/openstreetmap/josm/data/validation/tests/OpeningHourTestTest.java
+++ b/test/unit/org/openstreetmap/josm/data/validation/tests/OpeningHourTestTest.java
@@ -87,9 +87,9 @@ public void testI18n() {
         assertEquals("Encountered:  \".\" \". \" at line 0, column 0\nWas expecting: <EOF>",
                 checkOpeningHourSyntax(key, value, Locale.ENGLISH).get(0).getDescription());
         value = "Mon-Thu 12-18";
-        assertEquals("Wochentag mit 3 Buchstaben in Zeile 1, Zeichen 4",
+        assertEquals("<html>Mon-<span color=red>Thu 12-18</span> – Wochentag mit 3 Buchstaben in Zeile 1, Zeichen 4",
                 checkOpeningHourSyntax(key, value, Locale.GERMAN).get(0).getDescription());
-        assertEquals("Three character weekday at line 1, column 4",
+        assertEquals("<html>Mon-<span color=red>Thu 12-18</span> – Three character weekday at line 1, column 4",
                 checkOpeningHourSyntax(key, value, Locale.ENGLISH).get(0).getDescription());
     }
 
@@ -102,7 +102,7 @@ public void testCheckOpeningHourSyntax2() {
         final List<TestError> errors = checkOpeningHourSyntax(key, "Mo-Tue");
         assertThat(errors, hasSize(1));
         assertFixEquals("Mo-Tu", errors.get(0));
-        assertEquals("Three character weekday at line 1, column 6", errors.get(0).getDescription());
+        assertEquals("<html>Mo-Tue<span color=red></span> – Three character weekday at line 1, column 6", errors.get(0).getDescription());
         assertEquals(Severity.WARNING, errors.get(0).getSeverity());
     }
 
@@ -115,7 +115,7 @@ public void testCheckOpeningHourSyntax3() {
         final List<TestError> errors = checkOpeningHourSyntax(key, "Sa-Su 10.00-20.00");
         assertThat(errors, hasSize(1));
         assertFixEquals("Sa-Su 10:00-20:00", errors.get(0));
-        assertEquals("Invalid minutes at line 1, column 12", errors.get(0).getDescription());
+        assertEquals("<html>Sa-Su 10.00-<span color=red>20.00</span> – Invalid minutes at line 1, column 12", errors.get(0).getDescription());
         assertEquals(Severity.WARNING, errors.get(0).getSeverity());
     }
 
@@ -142,7 +142,8 @@ public void testCheckOpeningHourSyntax5() {
         assertEquals("Encountered:  <UNEXPECTED_CHAR> \"b \" at line 0, column 0\nWas expecting: <EOF>",
                 checkOpeningHourSyntax(key, "badtext").get(0).getDescription().trim());
         assertThat(checkOpeningHourSyntax(key, "5.00 p.m-11.00 p.m"), hasSize(1));
-        assertEquals("Encountered:  <UNEXPECTED_CHAR> \"p \" at line 1, column 2\nWas expecting: <EOF>",
+        assertEquals("<html>5.<span color=red>00 p.m-11.00 p.m</span> – " +
+                        "Encountered:  <UNEXPECTED_CHAR> \"p \" at line 1, column 2\nWas expecting: <EOF>",
                 checkOpeningHourSyntax(key, "5.00 p.m-11.00 p.m").get(0).getDescription());
     }
 
@@ -233,7 +234,7 @@ public void testPresetValues() {
         }
         for (final Tag t : values) {
             final List<TestError> errors = checkOpeningHourSyntax(t.getKey(), t.getValue());
-            if (!errors.isEmpty() && errors.get(0).getDescription().startsWith("Holiday after weekday")) {
+            if (!errors.isEmpty() && errors.get(0).getDescription().contains("Holiday after weekday")) {
                 continue;
             }
             assertThat(t + " is valid", errors, isEmpty());
@@ -254,7 +255,7 @@ public void testTicket17932() {
         final Node node = new Node(LatLon.ZERO);
         node.put(key, value);
         new DataSet(node);
-        return openingHourTest.checkOpeningHourSyntax(key, value, node, locale);
+        return openingHourTest.checkOpeningHourSyntax(key, value, node, locale, true);
     }
 
     private static void assertFixEquals(String value, TestError error) {
