Repository: falconry/falcon

Issue:
Add a helper to the Request class for getting a param as a date



Discussion:
May be related to #254?

I'll work on this


Resolving patch:
diff --git a/falcon/request.py b/falcon/request.py
--- a/falcon/request.py
+++ b/falcon/request.py
@@ -869,6 +869,44 @@ def get_param_as_list(self, name,
 
         raise HTTPMissingParam(name)
 
+    def get_param_as_date(self, name, format_string='%Y-%m-%d',
+                          required=False, store=None):
+        """
+        Args:
+            name (str): Parameter name, case-sensitive (e.g., 'ids').
+            format_string (str): String used to parse the param value into a
+                date.
+                Any format recognized by strptime() is supported.
+                (default ``"%Y-%m-%d"``)
+            required (bool, optional): Set to ``True`` to raise
+                ``HTTPBadRequest`` instead of returning ``None`` when the
+                parameter is not found (default ``False``).
+            store (dict, optional): A ``dict``-like object in which to place
+                the value of the param, but only if the param is found (default
+                ``None``).
+        Returns:
+            datetime.date
+
+        Raises:
+            HTTPBadRequest: A required param is missing from the request.
+            HTTPInvalidParam: A tranform function raised an instance of
+                ``ValueError``.
+        """
+        param_value = self.get_param(name, required=required)
+
+        if param_value is None:
+            return None
+
+        try:
+            date = datetime.strptime(param_value, format_string).date()
+        except ValueError:
+            msg = "The date value does not match the required format"
+            raise HTTPInvalidParam(msg, name)
+
+        if store is not None:
+            store[name] = date
+        return date
+
     # TODO(kgriffs): Use the nocover pragma only for the six.PY3 if..else
     def log_error(self, message):  # pragma: no cover
         """Write an error message to the server's log.


Test patch:
diff --git a/tests/test_query_params.py b/tests/test_query_params.py
--- a/tests/test_query_params.py
+++ b/tests/test_query_params.py
@@ -1,7 +1,10 @@
+from datetime import date
+
 import ddt
 
 import falcon
 import falcon.testing as testing
+from falcon.errors import HTTPInvalidParam
 
 
 @ddt.ddt
@@ -414,6 +417,49 @@ def test_multiple_form_keys_as_list(self):
         # There are three 'cat' keys; order is preserved.
         self.assertEqual(req.get_param_as_list('cat'), ['6', '5', '4'])
 
+    def test_get_date_valid(self):
+        date_value = "2015-04-20"
+        query_string = "thedate={0}".format(date_value)
+        self.simulate_request("/", query_string=query_string)
+        req = self.resource.req
+        self.assertEqual(req.get_param_as_date("thedate"),
+                         date(2015, 4, 20))
+
+    def test_get_date_missing_param(self):
+        query_string = "notthedate=2015-04-20"
+        self.simulate_request("/", query_string=query_string)
+        req = self.resource.req
+        self.assertEqual(req.get_param_as_date("thedate"),
+                         None)
+
+    def test_get_date_valid_with_format(self):
+        date_value = "20150420"
+        query_string = "thedate={0}".format(date_value)
+        format_string = "%Y%m%d"
+        self.simulate_request("/", query_string=query_string)
+        req = self.resource.req
+        self.assertEqual(req.get_param_as_date("thedate",
+                         format_string=format_string),
+                         date(2015, 4, 20))
+
+    def test_get_date_store(self):
+        date_value = "2015-04-20"
+        query_string = "thedate={0}".format(date_value)
+        self.simulate_request("/", query_string=query_string)
+        req = self.resource.req
+        store = {}
+        req.get_param_as_date("thedate", store=store)
+        self.assertNotEqual(len(store), 0)
+
+    def test_get_date_invalid(self):
+        date_value = "notarealvalue"
+        query_string = "thedate={0}".format(date_value)
+        format_string = "%Y%m%d"
+        self.simulate_request("/", query_string=query_string)
+        req = self.resource.req
+        self.assertRaises(HTTPInvalidParam, req.get_param_as_date,
+                          "thedate", format_string=format_string)
+
 
 class PostQueryParams(_TestQueryParams):
     def simulate_request(self, path, query_string, **kwargs):