diff --git a/todoman/cli.py b/todoman/cli.py
index e59f488..0703c85 100644
--- a/todoman/cli.py
+++ b/todoman/cli.py
@@ -304,7 +304,13 @@ def move(ctx, list, ids):
 @click.option('--reverse/--no-reverse', default=True,
               help='Sort tasks in reverse order (see --sort). '
               'Defaults to true.')
-def list(ctx, lists, all, urgent, location, category, grep, sort, reverse):
+@click.option('--due', default=None, help='Only show tasks due in DUE hours',
+              type=int)
+# TODO: we might want a `porcelain` flag here to print this is a
+# machine-friendly format that NEVER CHANGES!
+def list(
+    ctx, lists, all, urgent, location, category, grep, sort, reverse, due,
+         ):
     """
     List unfinished tasks.
 
@@ -323,6 +329,7 @@ def list(ctx, lists, all, urgent, location, category, grep, sort, reverse):
 
     db = ctx.obj['db']
     todos = db.todos(
+        due=due,
         all=all,
         category=category,
         grep=grep,
diff --git a/todoman/model.py b/todoman/model.py
index 91e515f..b9293bf 100644
--- a/todoman/model.py
+++ b/todoman/model.py
@@ -502,7 +502,7 @@ class Cache:
         )
 
     def todos(self, all=False, lists=[], urgent=False, location='',
-              category='', grep='', sort=[], reverse=True):
+              category='', grep='', sort=[], reverse=True, due=None):
         list_map = {list.name: list for list in self.lists()}
 
         extra_where = []
@@ -532,6 +532,10 @@ class Cache:
             # params.append(grep)
             extra_where.append('AND summary LIKE ?')
             params.append('%{}%'.format(grep))
+        if due:
+            max_due = datetime.now() + timedelta(hours=due)
+            extra_where.append('AND due IS NOT NULL AND due < ?')
+            params.append(max_due)
 
         if sort:
             order = []

diff --git a/tests/test_filtering.py b/tests/test_filtering.py
index c8bd520..c1a234f 100644
--- a/tests/test_filtering.py
+++ b/tests/test_filtering.py
@@ -1,4 +1,7 @@
+from datetime import datetime, timedelta
+
 from todoman.cli import cli
+from todoman.model import Database
 
 
 def test_all(tmpdir, runner, create):
@@ -154,3 +157,45 @@ def test_filtering_lists(tmpdir, runner, create):
     assert not result.exception
     assert len(result.output.splitlines()) == 1
     assert 'todo two' in result.output
+
+
+def test_due_aware(tmpdir, runner, create):
+    now = datetime.now()
+
+    for i in [1, 23, 25, 48]:
+        due = now + timedelta(hours=i)
+        create(
+            'test_{}.ics'.format(i),
+            'SUMMARY:{}\n'
+            'DUE;VALUE=DATE-TIME;TZID=CET:{}\n'.format(
+                i, due.strftime("%Y%m%dT%H%M%S"),
+            )
+        )
+
+    db = Database([tmpdir.join('default')], tmpdir.join('cache.sqlite'))
+    todos = list(db.todos(due=24))
+
+    assert len(todos) == 2
+    assert todos[0].summary == "23"
+    assert todos[1].summary == "1"
+
+
+def test_due_naive(tmpdir, runner, create):
+    now = datetime.now()
+
+    for i in [1, 23, 25, 48]:
+        due = now + timedelta(hours=i)
+        create(
+            'test_{}.ics'.format(i),
+            'SUMMARY:{}\n'
+            'DUE;VALUE=DATE-TIME:{}\n'.format(
+                i, due.strftime("%Y%m%dT%H%M%S"),
+            )
+        )
+
+    db = Database([tmpdir.join('default')], tmpdir.join('cache.sqlite'))
+    todos = list(db.todos(due=24))
+
+    assert len(todos) == 2
+    assert todos[0].summary == "23"
+    assert todos[1].summary == "1"

List by "today", "this week"
When I use `todo list` I get a very long list of all my tasks. I know I can filter by lists, but is it possible to filter by "this week", "today", "overdue"? I'd like to have a short list of today's (and overdue) tasks so I get a good feeling when I've done all for today :-)
tests/test_filtering.py::test_due_naive tests/test_filtering.py::test_due_aware