diff --git a/apachedex/__init__.py b/apachedex/__init__.py
index 2cc0ff96cc7fee2332b16acfb22c6ad2414ba3df..1ca626edaf13ef8e966a0b9d005ae8f9a3c2146c 100755
--- a/apachedex/__init__.py
+++ b/apachedex/__init__.py
@@ -114,6 +114,7 @@ INPUT_ENCODING_ERROR_HANDLER = 'replace'
 MONTH_VALUE_DICT = dict((y, x) for (x, y) in enumerate(('Jan', 'Feb', 'Mar',
   'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'), 1))
 
+MS_PER_S = 10 ** 3
 US_PER_S = 10 ** 6
 
 N_HOTTEST_PAGES_DEFAULT = 20
@@ -806,6 +807,7 @@ class ERP5SiteStats(GenericSiteStats):
       attribute[value_date].accumulateFrom(apdex)
 
 DURATION_US_FORMAT = '%D'
+DURATION_MS_FORMAT = '%{ms}T'
 DURATION_S_FORMAT = '%T'
 
 server_name_group_dict = {
@@ -826,6 +828,7 @@ logformat_dict = {
   '%{REMOTE_USER}i': r'(?P<remote_user>[^"]*)', # XXX: expected to be enclosed in "
   '%{User-Agent}i': r'(?P<agent>[^"]*)', # XXX: expected to be enclosed in "
   DURATION_US_FORMAT: r'(?P<duration>[0-9]*)',
+  DURATION_MS_FORMAT: r'(?P<duration_ms>[0-9]*)',
   DURATION_S_FORMAT: r'(?P<duration_s>[0-9]*)',
   '%%': r'%',
   '%v': r'(?P<servername>[^ ]*)',
@@ -1369,6 +1372,8 @@ def main():
                  'must be specified.')
   if DURATION_US_FORMAT in args.logformat:
     getDuration = lambda x: int(x.group('duration'))
+  elif DURATION_MS_FORMAT in args.logformat:
+    getDuration = lambda x: int(x.group('duration_ms')) * MS_PER_S
   elif DURATION_S_FORMAT in args.logformat:
     getDuration = lambda x: int(x.group('duration_s')) * US_PER_S
   else:
diff --git a/apachedex/tests.py b/apachedex/tests.py
index dd20ccd0c45ab0dabd8840eea21215715b5c3454..17ec41654bd4c12ff80d684d32267132758fd39c 100644
--- a/apachedex/tests.py
+++ b/apachedex/tests.py
@@ -100,3 +100,42 @@ else:
   class TestLzmaEncoding(ApacheDEXTestCase):
     def test(self):
       self.skipTest("lzma not available")
+
+
+class TestTimeEnconding(ApacheDEXTestCase):
+
+  def test_seconds_timing(self):
+    with tempfile.NamedTemporaryFile() as fout:
+      sys.argv = ['apachedex', '--base=/', '-', '--logformat', '%h %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i" %T', '-f', 'json', '-o', fout.name]
+      sys.stdin = StringIO(
+      '''127.0.0.1 - - [14/Jul/2017:09:41:41 +0200] "GET / HTTP/1.1" 200 7499 "https://example.org/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" 1''')
+
+      apachedex.main()
+
+      fout.seek(0)
+      state = json.load(fout)
+      self.assertEqual(state[0][1]['apdex']['2017/07/14 09:41']['duration_max'], 1000000)
+
+  def test_milliseconds_timing(self):
+    with tempfile.NamedTemporaryFile() as fout:
+      sys.argv = ['apachedex', '--base=/', '-', '--logformat', '%h %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i" %D', '-f', 'json', '-o', fout.name]
+      sys.stdin = StringIO(
+      '''127.0.0.1 - - [14/Jul/2017:09:41:41 +0200] "GET / HTTP/1.1" 200 7499 "https://example.org/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" 1000000''')
+
+      apachedex.main()
+
+      fout.seek(0)
+      state = json.load(fout)
+      self.assertEqual(state[0][1]['apdex']['2017/07/14 09:41']['duration_max'], 1000000)
+
+  def test_microseconds_timing(self):
+    with tempfile.NamedTemporaryFile() as fout:
+      sys.argv = ['apachedex', '--base=/', '-', '--logformat', '%h %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i" %{ms}T', '-f', 'json', '-o', fout.name]
+      sys.stdin = StringIO(
+      '''127.0.0.1 - - [14/Jul/2017:09:41:41 +0200] "GET / HTTP/1.1" 200 7499 "https://example.org/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" 1000
+      ''')
+
+      apachedex.main()
+      fout.seek(0)
+      state = json.load(fout)
+      self.assertEqual(state[0][1]['apdex']['2017/07/14 09:41']['duration_max'], 1000000)