diff --git a/examples/timeline/other/customTimeBarsSnap.html b/examples/timeline/other/customTimeBarsSnap.html
new file mode 100644
index 0000000000..ac0acde1cb
--- /dev/null
+++ b/examples/timeline/other/customTimeBarsSnap.html
@@ -0,0 +1,93 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Timeline | other | Show current and custom time bars with snapping</title>
+
+  <style type="text/css">
+    body, html {
+      font-family: sans-serif;
+      font-size: 11pt;
+    }
+  </style>
+
+  <script src="../../../standalone/umd/vis-timeline-graph2d.min.js"></script>
+  <link href="../../../styles/vis-timeline-graph2d.min.css" rel="stylesheet" type="text/css" />
+  
+</head>
+<body>
+
+<p>
+  The Timeline has functions to add multiple custom time bars which can be dragged by the user.
+</p>
+<p>
+  <input type="button" id="add" value="Add custom vertical bar">
+  <input type="text" id="barId" placeholder="custom bar ID">
+</p>
+<p>
+  <input type="button" id="remove" value="Remove custom vertical bar">
+  <input type="text" id="barIndex" value="t1" placeholder="custom bar ID">
+</p>
+<p>
+  <code><strong>timechange</strong></code> event, index: <span id="timechangeBar"></span>, time: <span id="timechangeEvent"></span>
+</p>
+<p>
+  <code><strong>timechanged</strong></code> event, index: <span id="timechangedBar"></span>, time: <span id="timechangedEvent"></span>
+</p><br>
+
+<div id="visualization"></div>
+
+<script type="text/javascript">
+  var container = document.getElementById('visualization');
+  var items = new vis.DataSet();
+  var customDate = new Date();
+  var options = {
+    showCurrentTime: true,
+    start: new Date(Date.now() - 1000 * 60 * 60 * 24),
+    end: new Date(Date.now() + 1000 * 60 * 60 * 24 * 6),
+    snap: function (date, scale, step) {
+            const hour = 60 * 1000;
+            return Math.round(date / hour) * hour;
+    }
+  };
+  var timeline = new vis.Timeline(container, items, options);
+
+  // Set first time bar
+  customDate = new Date(customDate.getFullYear(), customDate.getMonth(), customDate.getDate() + 1);
+  timeline.addCustomTime(customDate, 't1');
+
+  document.getElementById('add').onclick = function () {
+    try {
+      customDate = new Date(customDate.getFullYear(), customDate.getMonth(), customDate.getDate() + 1);
+      var barId = document.getElementById('barId').value || undefined;
+      timeline.addCustomTime(customDate, barId);
+      document.getElementById('barId').value = '';
+    }
+    catch (err) {
+      console.log(err);
+      alert(err);
+    }
+  };
+
+  document.getElementById('remove').onclick = function () {
+    try {
+      timeline.removeCustomTime(document.getElementById('barIndex').value);
+      document.getElementById('barIndex').value = '';
+    }
+    catch (err) {
+      console.log(err);
+      alert(err);
+    }
+  };
+
+  timeline.on('timechange', function (properties) {
+    document.getElementById('timechangeBar').innerHTML = properties.id;
+    document.getElementById('timechangeEvent').innerHTML = properties.time;
+  });
+  timeline.on('timechanged', function (properties) {
+    document.getElementById('timechangedBar').innerHTML = properties.id;
+    document.getElementById('timechangedEvent').innerHTML = properties.time;
+  });
+
+</script>
+</body>
+</html>
diff --git a/lib/timeline/Core.js b/lib/timeline/Core.js
index 9772a0bf7c..347af0d2dd 100644
--- a/lib/timeline/Core.js
+++ b/lib/timeline/Core.js
@@ -669,7 +669,8 @@ class Core {
 
     const customTime = new CustomTime(this.body, util.extend({}, this.options, {
       time : timestamp,
-      id
+      id,
+      snap: this.itemSet.options.snap
     }));
 
     this.customTimes.push(customTime);
diff --git a/lib/timeline/component/CustomTime.js b/lib/timeline/component/CustomTime.js
index 5ba5cdc287..7759ed9a46 100644
--- a/lib/timeline/component/CustomTime.js
+++ b/lib/timeline/component/CustomTime.js
@@ -63,7 +63,7 @@ class CustomTime extends Component {
   setOptions(options) {
     if (options) {
       // copy all options that we know
-      util.selectiveExtend(['moment', 'locale', 'locales', 'id', 'title', 'rtl'], this.options, options);
+      util.selectiveExtend(['moment', 'locale', 'locales', 'id', 'title', 'rtl', 'snap'], this.options, options);
     }
   }
 
@@ -260,7 +260,13 @@ class CustomTime extends Component {
     const x = this.body.util.toScreen(this.eventParams.customTime) + deltaX;
     const time = this.body.util.toTime(x);
 
-    this.setCustomTime(time);
+    const scale = this.body.util.getScale();
+    const step = this.body.util.getStep();
+    const snap = this.options.snap;
+
+    const snappedTime = snap ? snap(time, scale, step) : time;
+
+    this.setCustomTime(snappedTime);
 
     // fire a timechange event
     this.body.emitter.emit('timechange', {