diff --git a/modules/drivers/googleanalytics/src/metabase/driver/googleanalytics/query_processor.clj b/modules/drivers/googleanalytics/src/metabase/driver/googleanalytics/query_processor.clj
index d4133a508760386d0ebfc6644adf8189f5fd1557..a0886f432bd7ecc4c4bd359b52f2959a10acae38 100644
--- a/modules/drivers/googleanalytics/src/metabase/driver/googleanalytics/query_processor.clj
+++ b/modules/drivers/googleanalytics/src/metabase/driver/googleanalytics/query_processor.clj
@@ -2,6 +2,7 @@
   "The Query Processor is responsible for translating the Metabase Query Language into Google Analytics request format.
   See https://developers.google.com/analytics/devguides/reporting/core/v3"
   (:require [clojure.string :as str]
+            [clojure.tools.logging :as log]
             [clojure.tools.reader.edn :as edn]
             [java-time :as t]
             [metabase.mbql.util :as mbql.u]
@@ -10,8 +11,10 @@
              [date-2 :as u.date]
              [i18n :as ui18n :refer [deferred-tru tru]]
              [schema :as su]]
-            [metabase.util.date-2.parse :as u.date.parse]
-            [metabase.util.date-2.parse.builder :as u.date.parse.builder]
+            [metabase.util.date-2
+             [common :as u.date.common]
+             [parse :as u.date.parse]]
+            [metabase.util.date-2.parse.builder :as u.date.builder]
             [schema.core :as s])
   (:import [com.google.api.services.analytics.model GaData GaData$ColumnHeaders]
            java.time.DayOfWeek
@@ -415,27 +418,40 @@
   (edn/read-string (str/replace s #"^0+(.+)$" "$1")))
 
 (def ^:private ^DateTimeFormatter iso-year-week-formatter
-  (u.date.parse.builder/formatter
-   (u.date.parse.builder/value :iso/week-based-year 4)
-   (u.date.parse.builder/value :iso/week-of-week-based-year 2)))
+  (u.date.builder/formatter
+   (u.date.builder/value :iso/week-based-year 4)
+   (u.date.builder/value :iso/week-of-week-based-year 2)))
 
 (defn- parse-iso-year-week [^String s]
   (when s
     (-> (YearWeek/from (.parse iso-year-week-formatter s))
         (.atDay DayOfWeek/MONDAY))))
 
+(def ^:private ^DateTimeFormatter year-week
+  (u.date.builder/formatter
+   (u.date.builder/value :week-fields/week-based-year 4)
+   (u.date.builder/value :week-fields/week-of-week-based-year 2)))
+
+(defn- parse-year-week [^String s]
+  (when s
+    (let [parsed (.parse year-week s)
+          year   (.getLong parsed (u.date.common/temporal-field :week-fields/week-based-year))
+          week   (.getLong parsed (u.date.common/temporal-field :week-fields/week-of-week-based-year))]
+      (t/adjust (t/local-date year 1 1) (u.date/adjuster :week-of-year week)))))
+
 (def ^:private ga-dimension->date-format-fn
-  {"ga:minute"         parse-number
-   "ga:dateHour"       (partial u.date.parse/parse-with-formatter "yyyyMMddHH")
-   "ga:hour"           parse-number
-   "ga:date"           (partial u.date.parse/parse-with-formatter "yyyyMMdd")
-   "ga:dayOfWeek"      (comp inc parse-number)
+  {"ga:date"           "yyyyMMdd"
+   "ga:dateHour"       "yyyyMMddHH"
    "ga:day"            parse-number
+   "ga:dayOfWeek"      (comp inc parse-number)
+   "ga:hour"           parse-number
    "ga:isoYearIsoWeek" parse-iso-year-week
-   "ga:week"           parse-number
-   "ga:yearMonth"      (partial u.date.parse/parse-with-formatter "yyyyMM")
+   "ga:minute"         parse-number
    "ga:month"          parse-number
-   "ga:year"           parse-number})
+   "ga:week"           parse-number
+   "ga:year"           parse-number
+   "ga:yearMonth"      "yyyyMM"
+   "ga:yearWeek"       parse-year-week})
 
 (defn- header->column [^GaData$ColumnHeaders header]
   (let [date-parser (ga-dimension->date-format-fn (.getName header))]
@@ -447,11 +463,15 @@
 
 (defn- header->getter-fn [^GaData$ColumnHeaders header]
   (let [date-parser (ga-dimension->date-format-fn (.getName header))
-        base-type   (ga-type->base-type (.getDataType header))]
-    (cond
-      date-parser                   date-parser
-      (isa? base-type :type/Number) edn/read-string
-      :else                         identity)))
+        base-type   (ga-type->base-type (.getDataType header))
+        parser      (cond
+                      date-parser                   date-parser
+                      (isa? base-type :type/Number) edn/read-string
+                      :else                         identity)]
+    (log/tracef "Parsing result column %s with %s" (.getName header) (pr-str parser))
+    (if (string? parser)
+      (partial u.date.parse/parse-with-formatter parser)
+      parser)))
 
 (defn execute-query
   "Execute a `query` using the provided `do-query` function, and return the results in the usual format."
diff --git a/modules/drivers/googleanalytics/test/metabase/driver/googleanalytics/query_processor_test.clj b/modules/drivers/googleanalytics/test/metabase/driver/googleanalytics/query_processor_test.clj
index 08ba3f927243eff22c161b1c084d44128080d0f6..5bf667e0ee38dd3257fa64197fe1892f88953ef4 100644
--- a/modules/drivers/googleanalytics/test/metabase/driver/googleanalytics/query_processor_test.clj
+++ b/modules/drivers/googleanalytics/test/metabase/driver/googleanalytics/query_processor_test.clj
@@ -16,10 +16,19 @@
     (is (= "ga::B"
            (#'ga.qp/built-in-segment {:filter [:and [:segment 100] [:segment "ga::B"]]})))))
 
-(deftest iso-year-iso-week-test
+(deftest parse-year-week-test
   (testing "Make sure we properly parse isoYearIsoWeeks (#9244)"
-    (is (= #t "2018-12-31"
-           ((#'ga.qp/ga-dimension->date-format-fn "ga:isoYearIsoWeek") "201901")))))
+    (let [f (#'ga.qp/ga-dimension->date-format-fn "ga:isoYearIsoWeek")]
+      (is (= #t "2018-12-31"
+             (f "201901")))
+      (is (= #t "2019-12-09"
+             (f "201950")))))
+  (testing "Make sure we properly parse (non-ISO) yearWeeks"
+    (let [f (#'ga.qp/ga-dimension->date-format-fn "ga:yearWeek")]
+      (is (= #t "2018-12-30"
+             (f "201901")))
+      (is (= #t "2019-12-08"
+             (f "201950"))))))
 
 (deftest filter-test
   (testing "absolute datetimes"
diff --git a/src/metabase/util/date_2.clj b/src/metabase/util/date_2.clj
index 08a183413532bc869eaa66873dd3ae5be1ba1602..257157247d324ee329e00e3a7f63da8762930201 100644
--- a/src/metabase/util/date_2.clj
+++ b/src/metabase/util/date_2.clj
@@ -148,24 +148,51 @@
              :quarter-of-year  :quarter-of-year
              :year             :year))))
 
-(def ^:private adjusters*
-  {:first-day-of-week
-   (reify TemporalAdjuster
-     (adjustInto [_ t]
-       (t/adjust t :previous-or-same-day-of-week :sunday)))
-
-   :first-day-of-iso-week
-   (reify TemporalAdjuster
-     (adjustInto [_ t]
-       (t/adjust t :previous-or-same-day-of-week :monday)))
-
-   :first-day-of-quarter
-   (reify TemporalAdjuster
-     (adjustInto [_ t]
-       (.with t (.atDay (t/year-quarter t) 1))))})
-
-(defn- adjusters ^TemporalAdjuster [k]
-  (get adjusters* k))
+(defmulti ^TemporalAdjuster adjuster
+  "Get the custom `TemporalAdjuster` named by `k`.
+
+    ;; adjust 2019-12-10T17:26 to the second week of the year
+    (t/adjust #t \"2019-12-10T17:26\" (u.date/adjuster :week-of-year 2)) ;; -> #t \"2019-01-06T17:26\""
+  {:arglists '([k & args])}
+  (fn [k & _] (keyword k)))
+
+(defmethod adjuster :default
+  [k]
+  (throw (Exception. (tru "No temporal adjuster named {0}" k))))
+
+(defmethod adjuster :first-day-of-week
+  [_]
+  (reify TemporalAdjuster
+    (adjustInto [_ t]
+      (t/adjust t :previous-or-same-day-of-week :sunday))))
+
+(defmethod adjuster :first-day-of-iso-week
+  [_]
+  (reify TemporalAdjuster
+    (adjustInto [_ t]
+      (t/adjust t :previous-or-same-day-of-week :monday))))
+
+(defmethod adjuster :first-day-of-quarter
+  [_]
+  (reify TemporalAdjuster
+    (adjustInto [_ t]
+      (.with t (.atDay (t/year-quarter t) 1)))))
+
+(defmethod adjuster :first-week-of-year
+  [_]
+  (reify TemporalAdjuster
+    (adjustInto [_ t]
+      (-> t
+          (t/adjust :first-day-of-year)
+          (t/adjust (adjuster :first-day-of-week))))))
+
+(defmethod adjuster :week-of-year
+  [_ week-of-year]
+  (reify TemporalAdjuster
+    (adjustInto [_ t]
+      (-> t
+          (t/adjust (adjuster :first-week-of-year))
+          (t/plus (t/weeks (dec week-of-year)))))))
 
 ;; if you attempt to truncate a `LocalDate` to `:day` or anything smaller we can go ahead and return it as is
 (extend-protocol t.core/Truncatable
@@ -196,10 +223,10 @@
      :minute      (t/truncate-to t :minutes)
      :hour        (t/truncate-to t :hours)
      :day         (t/truncate-to t :days)
-     :week        (-> (.with t (adjusters :first-day-of-week))     (t/truncate-to :days))
-     :iso-week    (-> (.with t (adjusters :first-day-of-iso-week)) (t/truncate-to :days))
+     :week        (-> (.with t (adjuster :first-day-of-week))     (t/truncate-to :days))
+     :iso-week    (-> (.with t (adjuster :first-day-of-iso-week)) (t/truncate-to :days))
      :month       (-> (t/adjust t :first-day-of-month)             (t/truncate-to :days))
-     :quarter     (-> (.with t (adjusters :first-day-of-quarter))  (t/truncate-to :days))
+     :quarter     (-> (.with t (adjuster :first-day-of-quarter))  (t/truncate-to :days))
      :year        (-> (t/adjust t :first-day-of-year)              (t/truncate-to :days)))))
 
 (s/defn bucket :- (s/cond-pre Number Temporal)
diff --git a/src/metabase/util/date_2/parse/builder.clj b/src/metabase/util/date_2/parse/builder.clj
index b5550fdeb8e7802882c66ada97db7ad317383572..cfca94f97511de0429cd1e336f0cac0d8e7298a9 100644
--- a/src/metabase/util/date_2/parse/builder.clj
+++ b/src/metabase/util/date_2/parse/builder.clj
@@ -98,7 +98,8 @@
     field))
 
 (defn value
-  "Define a section for a specific field such as `:hour-of-day` or `:minute-of-hour`."
+  "Define a section for a specific field such as `:hour-of-day` or `:minute-of-hour`. Refer to
+  `metabase.util.date-2.common/temporal-field` for all possible temporal fields names."
   ([temporal-field-name]
    (fn [^DateTimeFormatterBuilder builder]
      (.appendValue builder (temporal-field temporal-field-name))))
diff --git a/test/metabase/util/date_2_test.clj b/test/metabase/util/date_2_test.clj
index b3db60a5774bc07998dde51a98483787948d6a83..fcae323a068ea3b050314afa1592dd4aecad9a9f 100644
--- a/test/metabase/util/date_2_test.clj
+++ b/test/metabase/util/date_2_test.clj
@@ -153,6 +153,22 @@
            (u.date/format-sql (t/zoned-date-time "2019-11-01T18:39:00-07:00[US/Pacific]")))
         "should get formatted as the same way as an OffsetDateTime")))
 
+(deftest adjuster-test
+  (let [now (t/zoned-date-time "2019-12-10T17:17:00-08:00[US/Pacific]")]
+    (testing "adjust temporal value to first day of week (Sunday)"
+      (is (= (t/zoned-date-time "2019-12-08T17:17-08:00[US/Pacific]")
+             (t/adjust now (u.date/adjuster :first-day-of-week)))))
+    (testing "adjust temporal value to first day of ISO week (Monday)"
+      (is (= (t/zoned-date-time "2019-12-09T17:17-08:00[US/Pacific]")
+             (t/adjust now (u.date/adjuster :first-day-of-iso-week)))))
+    (testing "adjust temporal value to first day of first week of year (previous or same Sunday as first day of year)"
+      (is (= (t/zoned-date-time "2018-12-30T17:17-08:00[US/Pacific]")
+             (t/adjust now (u.date/adjuster :first-week-of-year))
+             (t/adjust now (u.date/adjuster :week-of-year 1)))))
+    (testing "adjust temporal value to the 50th week of the year"
+      (is (= (t/zoned-date-time "2019-12-08T17:17-08:00[US/Pacific]")
+             (t/adjust now (u.date/adjuster :week-of-year 50)))))))
+
 (deftest extract-test
   (testing "u.date/extract with 2 args"
     ;; everything is at `Sunday October 27th 2019 2:03:40.555 PM` or subset thereof