     ["=" field param-value]
     ;; otherwise we need to handle date filtering
     (if-not (contains? relative-dates param-value)
-      ;; absolute date range such as: "2014-05-10,2014-05-16"
-      (let [[start end] (s/split param-value #"~" 2)]
+      ;; absolute date range
+      (let [{:keys [start end]} (absolute-date->range param-value)]
         ["BETWEEN" field start end])
-      ;; relative date range, so build appropriate MBQL clause
+      ;; relative date range
       (condp = param-value
         "past7days"  ["TIME_INTERVAL" field -7 "day"]
         "past30days" ["TIME_INTERVAL" field -30 "day"]
+        "thisweek"   ["TIME_INTERVAL" field "current" "week"]
+        "thismonth"  ["TIME_INTERVAL" field "current" "month"]
+        "thisyear"   ["TIME_INTERVAL" field "current" "year"]
+        "lastweek"   ["TIME_INTERVAL" field "last" "week"]
+        "lastmonth"  ["TIME_INTERVAL" field "last" "month"]
+        "lastyear"   ["TIME_INTERVAL" field "last" "year"]
         "yesterday"  ["=" field ["relative_datetime" -1 "day"]]
         "today"      ["=" field ["relative_datetime" "current"]]))))
 

            [clj-time.core :as t]
            [clj-time.format :as tf]
            [medley.core :as m]
            [metabase.driver :as driver]))


(def ^:private ^:const relative-dates
  #{"today"
    "yesterday"
    "past7days"
    "past30days"})


;;; +-------------------------------------------------------------------------------------------------------+

;;; +-------------------------------------------------------------------------------------------------------+


(defn- relative-date->range
  "Take a given string description of a relative date range such as 'lastmonth' and return a MAP with a given
   `:start` and `:end` as iso8601 string formatted dates.  Values should be appropriate for the given REPORT-TIMEZONE."
  [value report-timezone]
  (let [tz        (t/time-zone-for-id report-timezone)
        formatter (tf/formatter "YYYY-MM-dd" tz)
        today     (t/today-at-midnight tz)]
    (->> (condp = value
           "past7days"  {:end   (t/minus today (t/days 1))
                         :start (t/minus today (t/days 7))}
           "past30days" {:end   (t/minus today (t/days 1))
                         :start (t/minus today (t/days 30))}
           "thisweek"   (week-range today)
           "thismonth"  (month-range today)
           "thisyear"   (year-range today)
           "lastweek"   (week-range (t/minus today (t/weeks 1)))
           "lastmonth"  (month-range (t/minus today (t/months 1)))
           "lastyear"   (year-range (t/minus today (t/years 1)))
           "yesterday"  {:end   (t/minus today (t/days 1))
                         :start (t/minus today (t/days 1))}
           "today"      {:end   today
                         :start today})
         ;; the above values are JodaTime objects, so unparse them to iso8601 strings
         (m/map-vals (partial tf/unparse formatter)))))

(defn- extract-dates [value report-timezone]
  (if-not (contains? relative-dates value)
    ;; absolute date range
    (absolute-date->range value)
    ;; relative date range
    (relative-date->range value report-timezone)))

(defn- expand-date-range-param [report-timezone {[target param-name] :target, param-type :type, param-value :value, :as param}]
  (if-not (= param-type "date")
