Index: stamper/stamper.py
===================================================================
--- stamper/stamper.py	(revision 61)
+++ stamper/stamper.py	(revision 63)
@@ -1,7 +1,6 @@
 
 import json
-import re
 import os.path
-from datetime import datetime, date, timedelta
+from datetime import datetime, timedelta
 from os import symlink, remove, makedirs
 from collections import OrderedDict
@@ -11,4 +10,5 @@
 from .http import HTTPClient
 from .config import Config
+from .filters import DateFilter
 
 
@@ -29,4 +29,5 @@
         self.ensure_charts_dir()
         self.stamps = []
+        self.date_filter = DateFilter(self.date_format)
 
     def __json_load(self, filename):
@@ -93,81 +94,4 @@
                     datetime.strptime(start, self.datetime_format))
         return worktime.seconds
-
-    def validate_filter(self, stamp_filter):
-        """
-        Validate a given filter. Filters can have the following notation:
-
-        - %Y-%m-%d: Times recorded at a given date
-
-        - %Y-%m-%d--%Y-%m-%d: Times recorded between two dates
-
-        - *%Y-%m-%d: Times recorded up to a  given date
-
-        - %Y-%m-%d*: Times recorded from a given date
-
-        - N...N[d|w|m|y]: Times recorded N...N days/weeks/months/years ago
-
-        Important: all date comparisons are made on datetime objects, using
-        00:00 as the time (first second of the given day). This means that
-        for range filters, the first day is included, but the second day is not
-        """
-        filter_from = None
-        filter_to = None
-
-        if stamp_filter is None:
-            return filter_from, filter_to
-
-        if '--' in stamp_filter:
-            filter_from, filter_to = stamp_filter.split('--')
-            filter_from = datetime.strptime(filter_from, self.date_format)
-            filter_to = datetime.strptime(filter_to, self.date_format)
-
-        elif stamp_filter.startswith('*'):
-            filter_to = datetime.strptime(stamp_filter, '*'+self.date_format)
-            filter_to = filter_to.replace(hour=0, minute=0, second=0)
-
-        elif stamp_filter.endswith('*'):
-            filter_from = datetime.strptime(stamp_filter, self.date_format+'*')
-            filter_from = filter_from.replace(hour=0, minute=0, second=0)
-
-        elif re.search(r'(\d+[dD]{1})', stamp_filter):
-            number = int(stamp_filter.lower().replace('d', ''))
-            delta = timedelta(days=number)
-            filter_from = datetime.today() - delta
-            filter_from = filter_from.replace(hour=0, minute=0, second=0)
-
-        elif re.search(r'(\d+[wW]{1})', stamp_filter):
-            number = int(stamp_filter.lower().replace('w', '')) * 7
-            delta = timedelta(days=number)
-            filter_from = datetime.today() - delta
-            filter_from = filter_from.replace(hour=0, minute=0, second=0)
-
-        elif re.search(r'(\d+[mM]{1})', stamp_filter):
-            number = int(stamp_filter.lower().replace('m', ''))
-            past = date.today()
-            # start travelling in time, back to N months ago
-            for n in range(number):
-                past = past.replace(day=1) - timedelta(days=1)
-            # Now use the year/month from the past + the current day to set
-            # the proper date
-            filter_from = datetime(past.year, past.month, date.today().day)
-
-        elif re.search(r'(\d+[yY]{1})', stamp_filter):
-            number = int(stamp_filter.lower().replace('y', ''))
-            today = date.today()
-            filter_from = datetime(today.year - number, today.month, today.day)
-
-        else:
-            # maybe they are giving us a fixed date
-            try:
-                filter_from = datetime.strptime(stamp_filter, self.date_format)
-            except:
-                # nothing to be used as a filter, go on, printing a warning
-                print('[warning] invalid date filter: ' + stamp_filter)
-            else:
-                filter_from = filter_from.replace(hour=0, minute=0, second=0)
-                filter_to = filter_from + timedelta(days=1)
-
-        return filter_from, filter_to
 
     @property
@@ -252,5 +176,5 @@
 
     def timeline(self, customer=None, stamp_filter=None, filter_descr=None):
-        filter_from, filter_to = self.validate_filter(stamp_filter)
+        filter_from, filter_to = self.date_filter.validate(stamp_filter)
         for stamp in self.stamps:
             start = datetime.strptime(stamp['start'], self.datetime_format)
@@ -283,5 +207,5 @@
         Generate charts with information from the stamps
         """
-        filter_from, filter_to = self.validate_filter(stamp_filter)
+        filter_from, filter_to = self.date_filter.validate(stamp_filter)
         chart = pygal.Bar(title='Work hours per day',
                           range=(0, self.hours_day),
@@ -333,5 +257,5 @@
     def show_stamps(self, customer=None, stamp_filter=None, verbose=False,
         sum=False, filter_descr=None):
-        filter_from, filter_to = self.validate_filter(stamp_filter)
+        filter_from, filter_to = self.date_filter.validate(stamp_filter)
 
         # If the user asks for verbose information, show it before the
@@ -441,5 +365,5 @@
 
     def push_stamps(self, customer=None, stamp_filter=None, filter_descr=None):
-        filter_from, filter_to = self.validate_filter(stamp_filter)
+        filter_from, filter_to = self.date_filter.validate(stamp_filter)
 
         stamps = []
