From 49358630495fc7b6e91b630be6a5975e1e55ab80 Mon Sep 17 00:00:00 2001
From: Oleksandr Yakushev <alex@bytopia.org>
Date: Fri, 23 Aug 2024 08:55:31 +0300
Subject: [PATCH] perf: [date-2.parse] Add a fastpath for timestamps that are
 likely ISO instants (#47143)

---
 src/metabase/util/date_2/parse.clj | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/src/metabase/util/date_2/parse.clj b/src/metabase/util/date_2/parse.clj
index 563b68784ce..5e9f8354aeb 100644
--- a/src/metabase/util/date_2/parse.clj
+++ b/src/metabase/util/date_2/parse.clj
@@ -7,8 +7,8 @@
    [metabase.util.i18n :refer [tru]]
    [metabase.util.malli :as mu])
   (:import
-   (java.time LocalDateTime OffsetDateTime OffsetTime ZonedDateTime ZoneOffset)
-   (java.time.format DateTimeFormatter)
+   (java.time Instant LocalDateTime OffsetDateTime OffsetTime ZonedDateTime ZoneOffset)
+   (java.time.format DateTimeFormatter DateTimeParseException)
    (java.time.temporal Temporal TemporalAccessor TemporalField TemporalQueries)))
 
 (set! *warn-on-reflection* true)
@@ -49,6 +49,15 @@
 
 (def ^:private utc-zone-region (t/zone-id "UTC"))
 
+(defn- try-parse-as-iso-timestamp
+  "Fastpath for parsing ISO Instant timestamp if it matches the required length. Return nil if the length doesn't match
+  or the parsing fails, otherwise return a ZonedDateTime instance at UTC."
+  [^String s]
+  (when (and s (= (.length s) (.length "1970-01-01T00:00:00Z")))
+    (try (let [temporal-accessor (.parse DateTimeFormatter/ISO_INSTANT s)]
+           (.atZone (Instant/from temporal-accessor) utc-zone-region))
+         (catch DateTimeParseException _))))
+
 (mu/defn parse-with-formatter :- [:maybe InstanceOfTemporal]
   "Parse a String with a DateTimeFormatter, returning an appropriate instance of an `java.time` temporal class."
   [formattr
@@ -137,4 +146,5 @@
 (defn parse
   "Parse a string into a `java.time` object."
   [^String s]
-  (parse-with-formatter formatter s))
+  (or (try-parse-as-iso-timestamp s) ;; Try the fastpath first.
+      (parse-with-formatter formatter s)))
-- 
GitLab