diff --git a/frontend/src/metabase/app.js b/frontend/src/metabase/app.js
index 261fbe97c6ae37aea657c3c0aab44f0f407b1dd3..c9b29521e2c04b35b841065db6bb4266ff251817 100644
--- a/frontend/src/metabase/app.js
+++ b/frontend/src/metabase/app.js
@@ -11,6 +11,9 @@ import "number-to-locale-string";
 // Should be imported before any other metabase import
 import "ee-overrides"; // eslint-disable-line import/no-duplicates
 
+// day.js plugins should be enabled before setting the locale
+import "metabase/lib/dayjs";
+
 // If enabled this monkeypatches `t` and `jt` to return blacked out
 // strings/elements to assist in finding untranslated strings.
 import "metabase/lib/i18n-debug";
diff --git a/frontend/src/metabase/lib/dayjs.ts b/frontend/src/metabase/lib/dayjs.ts
new file mode 100644
index 0000000000000000000000000000000000000000..00cf862e2724de1ab2194ece664fed77e178122c
--- /dev/null
+++ b/frontend/src/metabase/lib/dayjs.ts
@@ -0,0 +1,6 @@
+import dayjs from "dayjs";
+import localeDataPlugin from "dayjs/plugin/localeData";
+import updateLocalePlugin from "dayjs/plugin/updateLocale";
+
+dayjs.extend(localeDataPlugin);
+dayjs.extend(updateLocalePlugin);
diff --git a/frontend/src/metabase/lib/i18n.js b/frontend/src/metabase/lib/i18n.js
index 35256d3b70aabaed39a5931e322dc0df3ac2f6e5..9946b411fcc8e11d6f87c46c19ae594d3751afe4 100644
--- a/frontend/src/metabase/lib/i18n.js
+++ b/frontend/src/metabase/lib/i18n.js
@@ -1,5 +1,6 @@
 import { addLocale, useLocale } from "ttag";
 import moment from "moment-timezone";
+import dayjs from "dayjs";
 
 import MetabaseSettings from "metabase/lib/settings";
 import { DAY_OF_WEEK_OPTIONS } from "metabase/lib/date-time";
@@ -26,26 +27,20 @@ export async function loadLocalization(locale) {
   setLocalization(translationsObject);
 }
 
-// Tell Moment.js to use the value of the start-of-week Setting for its current locale
+// Tell moment.js to use the value of the start-of-week Setting for its current locale
+// Moment.js dow range Sunday (0) - Saturday (6)
 export function updateMomentStartOfWeek() {
-  const startOfWeekDayName = MetabaseSettings.get("start-of-week");
-  if (!startOfWeekDayName) {
-    return;
+  const startOfWeekDay = getStartOfWeekDay();
+  if (startOfWeekDay != null) {
+    moment.updateLocale(moment.locale(), { week: { dow: startOfWeekDay } });
   }
+}
 
-  const startOfWeekDayNumber = DAY_OF_WEEK_OPTIONS.findIndex(
-    ({ id }) => id === startOfWeekDayName,
-  );
-  if (startOfWeekDayNumber === -1) {
-    return;
+export function updateDayjsStartOfWeek() {
+  const startOfWeekDay = getStartOfWeekDay();
+  if (startOfWeekDay != null) {
+    dayjs.updateLocale(dayjs.locale(), { week: { dow: startOfWeekDay } });
   }
-
-  moment.updateLocale(moment.locale(), {
-    week: {
-      // Moment.js dow range Sunday (0) - Saturday (6)
-      dow: startOfWeekDayNumber,
-    },
-  });
 }
 
 // if the start of week Setting is updated, update the moment start of week
@@ -62,35 +57,66 @@ function setLanguage(translationsObject) {
 }
 
 function setLocalization(translationsObject) {
-  const locale = translationsObject.headers.language;
-
+  const language = translationsObject.headers.language;
   setLanguage(translationsObject);
-
-  updateMomentLocale(locale);
-  updateMomentStartOfWeek(locale);
+  updateMomentLocale(language);
+  updateDayjsLocale(language);
+  updateMomentStartOfWeek();
+  updateDayjsStartOfWeek();
 }
 
-function updateMomentLocale(locale) {
-  const momentLocale = mapToMomentLocale(locale);
+function updateMomentLocale(language) {
+  const locale = getLocale(language);
+
   try {
-    if (momentLocale !== "en") {
-      require("moment/locale/" + momentLocale);
+    if (locale !== "en") {
+      require(`moment/locale/${locale}.js`);
     }
-    moment.locale(momentLocale);
+    moment.locale(locale);
   } catch (e) {
-    console.warn(`Could not set moment locale to ${momentLocale}`);
+    console.warn(`Could not set moment.js locale to ${locale}`);
     moment.locale("en");
   }
 }
 
-function mapToMomentLocale(locale = "") {
-  switch (locale) {
+function updateDayjsLocale(language) {
+  const locale = getLocale(language);
+
+  try {
+    if (locale !== "en") {
+      require(`dayjs/locale/${locale}.js`);
+    }
+    dayjs.locale(locale);
+  } catch (e) {
+    console.warn(`Could not set day.js locale to ${locale}`);
+    dayjs.locale("en");
+  }
+}
+
+function getLocale(language = "") {
+  switch (language) {
     case "zh":
     case "zh-Hans":
       return "zh-cn";
     default:
-      return locale.toLowerCase();
+      return language.toLowerCase();
+  }
+}
+
+function getStartOfWeekDay() {
+  const startOfWeekDayName = MetabaseSettings.get("start-of-week");
+  if (!startOfWeekDayName) {
+    return;
   }
+
+  const startOfWeekDayNumber = DAY_OF_WEEK_OPTIONS.findIndex(
+    ({ id }) => id === startOfWeekDayName,
+  );
+  if (startOfWeekDayNumber === -1) {
+    return;
+  }
+
+  return startOfWeekDayNumber;
 }
 
 // we delete msgid property since it's redundant, but have to add it back in to
diff --git a/frontend/src/metabase/ui/components/theme/DatesProvider/DatesProvider.tsx b/frontend/src/metabase/ui/components/theme/DatesProvider/DatesProvider.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..04b93ab2312373b93243e877404993c573b0c701
--- /dev/null
+++ b/frontend/src/metabase/ui/components/theme/DatesProvider/DatesProvider.tsx
@@ -0,0 +1,19 @@
+import type { ReactNode } from "react";
+import dayjs from "dayjs";
+import { DatesProvider as MantineDatesProvider } from "@mantine/dates";
+import type { DatesProviderSettings, DayOfWeek } from "@mantine/dates";
+
+interface DatesProviderProps {
+  children?: ReactNode;
+}
+
+export function DatesProvider({ children }: DatesProviderProps) {
+  const settings: DatesProviderSettings = {
+    locale: dayjs.locale(),
+    firstDayOfWeek: dayjs.localeData().firstDayOfWeek() as DayOfWeek,
+  };
+
+  return (
+    <MantineDatesProvider settings={settings}>{children}</MantineDatesProvider>
+  );
+}
diff --git a/frontend/src/metabase/ui/components/theme/DatesProvider/index.ts b/frontend/src/metabase/ui/components/theme/DatesProvider/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..12f87bccc691795072b664e9a40923f51d8b4607
--- /dev/null
+++ b/frontend/src/metabase/ui/components/theme/DatesProvider/index.ts
@@ -0,0 +1 @@
+export * from "./DatesProvider";
diff --git a/frontend/src/metabase/ui/components/theme/ThemeProvider/ThemeProvider.tsx b/frontend/src/metabase/ui/components/theme/ThemeProvider/ThemeProvider.tsx
index b76d55b6f259dc3670b99d0072de6a9b842597ed..8908e451f7de040377f474701a49155bf0fe9f05 100644
--- a/frontend/src/metabase/ui/components/theme/ThemeProvider/ThemeProvider.tsx
+++ b/frontend/src/metabase/ui/components/theme/ThemeProvider/ThemeProvider.tsx
@@ -3,6 +3,7 @@ import { MantineProvider } from "@mantine/core";
 import { withEmotionCache } from "@emotion/react";
 import type { EmotionCache } from "@emotion/react";
 import { getThemeOverrides } from "../../../theme";
+import { DatesProvider } from "../DatesProvider";
 
 interface ThemeProviderProps {
   children: ReactNode;
@@ -14,7 +15,7 @@ export const ThemeProvider = withEmotionCache(
 
     return (
       <MantineProvider theme={theme} emotionCache={cache}>
-        {children}
+        <DatesProvider>{children}</DatesProvider>
       </MantineProvider>
     );
   },
diff --git a/frontend/test/jest-setup.js b/frontend/test/jest-setup.js
index 97acb8023cea8e2ceaf044f4347eebcee7af1e42..d84cc236b7427c206ba8d43e3c9d36f359ab40ca 100644
--- a/frontend/test/jest-setup.js
+++ b/frontend/test/jest-setup.js
@@ -3,6 +3,7 @@ import "cross-fetch/polyfill";
 import "raf/polyfill";
 import "jest-localstorage-mock";
 import "jest-canvas-mock";
+import "metabase/lib/dayjs";
 import "__support__/mocks";
 
 // NOTE: this is needed because sometimes asynchronous code tries to access
diff --git a/package.json b/package.json
index 4fd560e0f5e014f25c92dc18bdaef7339dd9bd1f..5fa8f24cf11a73f5eac65afb33236ab577f90692 100644
--- a/package.json
+++ b/package.json
@@ -49,6 +49,7 @@
     "d3-array": "^3.1.1",
     "d3-scale": "^3.3.0",
     "d3-shape": "^3.1.0",
+    "dayjs": "^1.10.4",
     "dc": "2.1.9",
     "diff": "^3.2.0",
     "formik": "^2.2.9",
@@ -244,8 +245,8 @@
     "jest-environment-jsdom": "^29.5.0",
     "jest-localstorage-mock": "^2.4.22",
     "jest-watch-typeahead": "^2.2.1",
-    "jsonwebtoken": "^9.0.0",
     "json-to-pretty-yaml": "^1.2.2",
+    "jsonwebtoken": "^9.0.0",
     "knex": "^2.4.2",
     "lint-staged": "^13.1.2",
     "markdown-link-check": "^3.10.2",