Repository: Sage/carbon (ts)

Issue:
Date Range locale override does not change format
### Description

I am using the date range **locale** override to change the region to `"fr-CA"` and the **dateFnsLocale** to `"frCA"`. It does not change the date format to `yyyy/mm/dd` which would be the expected behaviour.

### Reproduction

https://carbon.sage.com/?path=/docs/date-range--default-story

### Steps to reproduce

_No response_

### JIRA ticket numbers (Sage only)

_No response_

### Suggested solution

the `outputFormat` needs to be modified.

### Carbon version

125.6.0

### Design tokens version

4.34.0

### Relevant browsers

Chrome

### Relevant OSs

Windows

### Additional context

_No response_

### Confidentiality

- [ ] I confirm there is no confidential or commercially sensitive information included.
Allow date input to setup a custom  formattedValue
### Description

As a developer using Carbon I want to be able to define a custom `formattedValue` for date-input/date-range. The application I'm working on allows to setup prefered date format. It would be nice to be able pass this format to the date-input/date-range.

### Suggested solution

Add a prop to overide default smart behaviour based on locale.
```jsx
const [state, setState] = useState("04/04/2019");
  const setValue = (ev: DateChangeEvent) => {
    setState(ev.target.value.formattedValue); // 04-04-2019
  };
  return <DateInput label="Date" name="date-input" value={state} onChange={setValue} customFormat="DD-MM-yyyy" />;
```

### Demo URL

_No response_

### Alternatives

_No response_

### Additional context

_No response_

### Confidentiality

- [X] I confirm there is no confidential or commercially sensitive information included.

Pull request:
feat(date, date-range): provides a mechanism that allows consumers to override the format of dates
A new property has been added to the `Locale` interface for dates to allow customers to override the displayed date formats in both the Date and DateRange inputs

fix #6930 

### Proposed behaviour

Provide a mechanism to allow default date formats to be overridden

### Current behaviour

Currently, users are forced to adhere to the date formats decreed by their chosen locale, with the only option to change being to use a different locale.

### Checklist

- [X] Commits follow our style guide
- [X] Related issues linked in commit messages if required
- [ ] Screenshots are included in the PR if useful
- [x] All themes are supported if required
- [X] Unit tests added or updated if required
- [ ] Playwright automation tests added or updated if required
- [X] Storybook added or updated if required
- [ ] Translations added or updated (including creating or amending translation keys table in storybook) if required
- [ ] Typescript `d.ts` file added or updated if required
- [X] Related docs have been updated if required

#### QA

- [ ] Tested in provided StackBlitz sandbox/Storybook
- [ ] Add new Playwright test coverage if required
- [ ] Carbon implementation matches Design System/designs
- [ ] UI Tests GitHub check reviewed if required

### Testing instructions

Render one of the following component:

**DateInput**

```javascript
<I18nProvider
        locale={{
          locale: () => "de-DE",
          date: {
            dateFnsLocale: () => de,
            ariaLabels: {
              previousMonthButton: () => "Vorheriger Monat",
              nextMonthButton: () => "Nächster Monat",
            },
            dateFormatOverride: "yyyy-M-d",
          },
        }}
      >
        <DateInput
          label="Date `DE` locale"
          value={state}
          onChange={handleChange}
        />
      </I18nProvider>
```

**DateRange**

```javascript
      <I18nProvider
        locale={{
          locale: () => "de-DE",
          date: {
            dateFnsLocale: () => de,
            ariaLabels: {
              previousMonthButton: () => "Vorheriger Monat",
              nextMonthButton: () => "Nächster Monat",
            },
            dateFormatOverride: "y-m-ddd",
          },
        }}
      >
        <DateRange
          startLabel="Start"
          endLabel="End"
          value={state}
          onChange={handleChange}
        />
      </I18nProvider>
```
Change the value of `dateFormatOverride` and observe that the changes are correctly reflected in the inputs

Patch:
diff --git a/src/components/date-range/date-range.component.tsx b/src/components/date-range/date-range.component.tsx
index 8dca31fc7..ff1dde9a0 100644
--- a/src/components/date-range/date-range.component.tsx
+++ b/src/components/date-range/date-range.component.tsx
@@ -116,6 +116,8 @@ export interface DateRangeProps
   required?: boolean;
   /** Flag to configure component as optional. */
   isOptional?: boolean;
+  /** Date format string to be applied to the date inputs */
+  dateFormatOverride?: string;
 }
 
 export const DateRange = ({
@@ -141,10 +143,10 @@ export const DateRange = ({
     : labelsInline;
 
   const l = useLocale();
-  const { dateFnsLocale } = l.date;
+  const { dateFnsLocale, dateFormatOverride } = l.date;
   const { format } = useMemo(
-    () => getFormatData(dateFnsLocale()),
-    [dateFnsLocale],
+    () => getFormatData(dateFnsLocale(), dateFormatOverride),
+    [dateFnsLocale, dateFormatOverride],
   );
   const inlineLabelWidth = 40;
   const [lastChangedDate, setLastChangedDate] = useState("");
diff --git a/src/components/date-range/date-range.mdx b/src/components/date-range/date-range.mdx
index 8fdc09fbb..89e3ed7e6 100644
--- a/src/components/date-range/date-range.mdx
+++ b/src/components/date-range/date-range.mdx
@@ -39,7 +39,7 @@ import DateRange from "carbon-react/lib/components/date-range";
 
 ### LabelsInline
 
-**Note:** The `labelsInline` prop is not supported if the `validationRedesignOptIn` flag on the `CarbonProvider` is true. 
+**Note:** The `labelsInline` prop is not supported if the `validationRedesignOptIn` flag on the `CarbonProvider` is true.
 
 <Canvas of={DateRangeStories.LabelsInline} />
 
@@ -110,6 +110,13 @@ the French locale. Required locales can be imported like so `import { fr } from
 
 <Canvas of={DateRangeStories.LocaleOverrideExampleImplementation} />
 
+### Locale format override
+
+You can also override the format used to display dates in the date picker via the `dateFormatOverride` property. In the example below, the German locale is used
+but the date format has been overridden to `y-m-ddd` as opposed to the default `dd.MM.yyyy`.
+
+<Canvas of={DateRangeStories.LocaleFormatOverrideExampleImplementation} />
+
 ## Props
 
 ### Date Range
diff --git a/src/components/date-range/date-range.stories.tsx b/src/components/date-range/date-range.stories.tsx
index 93b90dcd3..0752198b8 100644
--- a/src/components/date-range/date-range.stories.tsx
+++ b/src/components/date-range/date-range.stories.tsx
@@ -1,6 +1,6 @@
 import React, { useState } from "react";
 import { Meta, StoryObj } from "@storybook/react";
-import { fr } from "date-fns/locale";
+import { fr, de } from "date-fns/locale";
 
 import generateStyledSystemProps from "../../../.storybook/utils/styled-system-props";
 
@@ -371,3 +371,49 @@ export const IsOptional: Story = () => {
   );
 };
 IsOptional.storyName = "IsOptional";
+
+export const LocaleFormatOverrideExampleImplementation: Story = ({
+  ...args
+}) => {
+  const [state, setState] = useState(["2016-10-01", "2016-10-30"]);
+  const handleChange = (ev: DateRangeChangeEvent) => {
+    const newValue = [
+      ev.target.value[0].formattedValue,
+      ev.target.value[1].formattedValue,
+    ];
+    setState(newValue);
+  };
+
+  return (
+    <div>
+      <I18nProvider
+        locale={{
+          locale: () => "de-DE",
+          date: {
+            dateFnsLocale: () => de,
+            ariaLabels: {
+              previousMonthButton: () => "Vorheriger Monat",
+              nextMonthButton: () => "Nächster Monat",
+            },
+            dateFormatOverride: args.dateFormatOverride || "dd-MM-yyyy",
+          },
+        }}
+      >
+        <DateRange
+          startLabel="Start"
+          endLabel="End"
+          value={state}
+          onChange={handleChange}
+        />
+      </I18nProvider>
+    </div>
+  );
+};
+LocaleFormatOverrideExampleImplementation.storyName =
+  "Locale Format Override Example Implementation";
+LocaleFormatOverrideExampleImplementation.parameters = {
+  chromatic: { disableSnapshot: true },
+};
+LocaleFormatOverrideExampleImplementation.args = {
+  dateFormatOverride: "d-M-yyyy",
+};
diff --git a/src/components/date/__internal__/date-formats/index.ts b/src/components/date/__internal__/date-formats/index.ts
index e624320a9..4de6900ef 100644
--- a/src/components/date/__internal__/date-formats/index.ts
+++ b/src/components/date/__internal__/date-formats/index.ts
@@ -140,7 +140,36 @@ interface LocaleFormats {
   format: string;
 }
 
-const getFormatData = ({ code = "en-GB" }: DateFnsLocale): LocaleFormats => {
+const getFormatData = (
+  { code = "en-GB" }: DateFnsLocale,
+  dateFormatOverride?: string,
+): LocaleFormats => {
+  if (dateFormatOverride) {
+    const { format } = getOutputFormatForLocale(code);
+    let formatFromLocale;
+
+    switch (code) {
+      case "en-CA":
+      case "en-US":
+        formatFromLocale = "MM/dd/yyyy";
+        break;
+      case "ar-EG":
+      case "en-ZA":
+      case "fr-CA":
+        formatFromLocale = "dd/MM/yyyy";
+        break;
+      default:
+        formatFromLocale = format;
+    }
+
+    const formatsForLocale = getInputFormatsArrayForLocale(formatFromLocale);
+
+    return {
+      format: dateFormatOverride,
+      formats: generateFormats(formatsForLocale, "/"),
+    };
+  }
+
   if (["en-CA", "en-US"].includes(code)) {
     const format = "MM/dd/yyyy";
     const formats = getInputFormatsArrayForLocale(format);
diff --git a/src/components/date/date.component.tsx b/src/components/date/date.component.tsx
index fa9755f5a..7205cfaaa 100644
--- a/src/components/date/date.component.tsx
+++ b/src/components/date/date.component.tsx
@@ -101,6 +101,8 @@ export interface DateInputProps
   onPickerOpen?: () => void;
   /** Callback triggered when the picker is closed */
   onPickerClose?: () => void;
+  /** Date format string to be applied to the date inputs */
+  dateFormatOverride?: string;
 }
 
 export const DateInput = React.forwardRef<HTMLInputElement, DateInputProps>(
@@ -146,10 +148,10 @@ export const DateInput = React.forwardRef<HTMLInputElement, DateInputProps>(
     const focusedViaPicker = useRef(false);
     const blockClose = useRef(false);
     const locale = useLocale();
-    const { dateFnsLocale } = locale.date;
+    const { dateFnsLocale, dateFormatOverride } = locale.date;
     const { format, formats } = useMemo(
-      () => getFormatData(dateFnsLocale()),
-      [dateFnsLocale],
+      () => getFormatData(dateFnsLocale(), dateFormatOverride),
+      [dateFnsLocale, dateFormatOverride],
     );
     const { inputRefMap, setInputRefMap } = useContext(DateRangeContext);
     const [open, setOpen] = useState(false);
diff --git a/src/components/date/date.mdx b/src/components/date/date.mdx
index 599a0a32b..cb36dd38b 100644
--- a/src/components/date/date.mdx
+++ b/src/components/date/date.mdx
@@ -66,7 +66,7 @@ be used to set the input value like in the example below, although the component
 
 ### With labelInline
 
-**Note:** The `labelInline` prop is not supported if the `validationRedesignOptIn` flag on the `CarbonProvider` is true. 
+**Note:** The `labelInline` prop is not supported if the `validationRedesignOptIn` flag on the `CarbonProvider` is true.
 
 <Canvas of={DateStories.WithLabelInline} />
 
@@ -149,6 +149,13 @@ the German (`de`) locale whilst the second is for a Chinese (`zh-CN`) locale. Re
 
 <Canvas of={DateStories.LocaleOverrideExampleImplementation} />
 
+### Locale format override
+
+You can also override the format used to display dates in the date picker via the `dateFormatOverride` property. In the example below, the German locale is used
+but the date format has been overridden to `yyyy-M-d` as opposed to the default `dd.MM.yyyy`.
+
+<Canvas of={DateStories.LocaleFormatOverrideExampleImplementation} />
+
 ## Props
 
 ### DateInput
diff --git a/src/components/date/date.stories.tsx b/src/components/date/date.stories.tsx
index 07876db87..9df69d32c 100644
--- a/src/components/date/date.stories.tsx
+++ b/src/components/date/date.stories.tsx
@@ -522,3 +522,44 @@ LocaleOverrideExampleImplementation.storyName =
 LocaleOverrideExampleImplementation.parameters = {
   chromatic: { disableSnapshot: true },
 };
+
+export const LocaleFormatOverrideExampleImplementation: Story = ({
+  ...args
+}) => {
+  const [state, setState] = useState("2022-04-05");
+  const handleChange = (ev: DateChangeEvent) => {
+    console.log(ev.target.value);
+    setState(ev.target.value.formattedValue);
+  };
+  return (
+    <div style={{ display: "flex" }}>
+      <I18nProvider
+        locale={{
+          locale: () => "de-DE",
+          date: {
+            dateFnsLocale: () => de,
+            ariaLabels: {
+              previousMonthButton: () => "Vorheriger Monat",
+              nextMonthButton: () => "Nächster Monat",
+            },
+            dateFormatOverride: args.dateFormatOverride || "dd-MM-yyyy",
+          },
+        }}
+      >
+        <DateInput
+          label="Date `DE` locale"
+          value={state}
+          onChange={handleChange}
+        />
+      </I18nProvider>
+    </div>
+  );
+};
+LocaleFormatOverrideExampleImplementation.storyName =
+  "Locale Format Override - Example Implementation";
+LocaleFormatOverrideExampleImplementation.parameters = {
+  chromatic: { disableSnapshot: true },
+};
+LocaleFormatOverrideExampleImplementation.args = {
+  dateFormatOverride: "d-M-yyyy",
+};
diff --git a/src/locales/de-de.ts b/src/locales/de-de.ts
index f743ab3c4..5329c785d 100644
--- a/src/locales/de-de.ts
+++ b/src/locales/de-de.ts
@@ -1,4 +1,5 @@
 import deDEDateLocale from "date-fns/locale/de";
+
 import Locale from "./locale";
 
 const isSingular = (count: string | number): boolean =>
diff --git a/src/locales/en-ca.ts b/src/locales/en-ca.ts
index e7ea079a8..6ef1bf16e 100644
--- a/src/locales/en-ca.ts
+++ b/src/locales/en-ca.ts
@@ -1,4 +1,5 @@
 import enCADateLocale from "date-fns/locale/en-CA";
+
 import Locale from "./locale";
 
 const enCA: Partial<Locale> = {
diff --git a/src/locales/en-gb.ts b/src/locales/en-gb.ts
index 41fbecd52..760155487 100644
--- a/src/locales/en-gb.ts
+++ b/src/locales/en-gb.ts
@@ -1,4 +1,5 @@
 import enGBDateLocale from "date-fns/locale/en-GB";
+
 import Locale from "./locale";
 
 const isSingular = (count: string | number): boolean =>
@@ -46,6 +47,7 @@ const enGB: Locale = {
       previousMonthButton: () => "Previous month",
       nextMonthButton: () => "Next month",
     },
+    dateFormatOverride: undefined,
   },
   dialog: {
     ariaLabels: {
diff --git a/src/locales/en-us.ts b/src/locales/en-us.ts
index 157e0b5c6..90d2a4023 100644
--- a/src/locales/en-us.ts
+++ b/src/locales/en-us.ts
@@ -1,4 +1,5 @@
 import enUSDateLocale from "date-fns/locale/en-US";
+
 import Locale from "./locale";
 
 const enUS: Partial<Locale> = {
diff --git a/src/locales/es-es.ts b/src/locales/es-es.ts
index 4f457cb25..7e372052e 100644
--- a/src/locales/es-es.ts
+++ b/src/locales/es-es.ts
@@ -1,4 +1,5 @@
 import esESDateLocale from "date-fns/locale/es";
+
 import Locale from "./locale";
 
 const isSingular = (count: string | number): boolean =>
diff --git a/src/locales/fr-ca.ts b/src/locales/fr-ca.ts
index 2e0106b25..66a3010e0 100644
--- a/src/locales/fr-ca.ts
+++ b/src/locales/fr-ca.ts
@@ -1,4 +1,5 @@
 import frCADateLocale from "date-fns/locale/fr-CA";
+
 import Locale from "./locale";
 
 const isSingular = (count: string | number): boolean =>
diff --git a/src/locales/fr-fr.ts b/src/locales/fr-fr.ts
index 896452bbd..a0e601ba7 100644
--- a/src/locales/fr-fr.ts
+++ b/src/locales/fr-fr.ts
@@ -1,4 +1,5 @@
 import frFRDateLocale from "date-fns/locale/fr";
+
 import Locale from "./locale";
 
 const isSingular = (count: string | number): boolean =>
diff --git a/src/locales/locale.ts b/src/locales/locale.ts
index 01638468e..5d7ce67cc 100644
--- a/src/locales/locale.ts
+++ b/src/locales/locale.ts
@@ -35,6 +35,7 @@ interface Locale {
       previousMonthButton: () => string;
       nextMonthButton: () => string;
     };
+    dateFormatOverride?: string;
   };
   dialog: {
     ariaLabels: {


Test patch:
diff --git a/src/components/date-range/date-range.test.tsx b/src/components/date-range/date-range.test.tsx
index 593b32bb3..b52d4a946 100644
--- a/src/components/date-range/date-range.test.tsx
+++ b/src/components/date-range/date-range.test.tsx
@@ -1,10 +1,13 @@
 import React from "react";
 import { render, screen, within } from "@testing-library/react";
 import userEvent from "@testing-library/user-event";
+import enGBLocale from "date-fns/locale/en-GB";
+import deLocale from "date-fns/locale/de";
 
 import DateRange, { DateRangeChangeEvent } from "./date-range.component";
 import { testStyledSystemMargin } from "../../__spec_helper__/__internal__/test-utils";
 import CarbonProvider from "../carbon-provider";
+import I18nProvider from "../i18n-provider";
 
 testStyledSystemMargin(
   (props) => (
@@ -1136,3 +1139,69 @@ test("should have the default styling when the `labelsInline` prop is set and `v
   expect(screen.getByTestId("start")).toHaveStyle("vertical-align: bottom");
   expect(screen.getByTestId("end")).toHaveStyle("vertical-align: bottom");
 });
+
+describe("Locale formatting overrides", () => {
+  test("should render with the input value matching the expected format when `dateFormatOverride` is set and the language is `de-DE`", () => {
+    render(
+      <I18nProvider
+        locale={{
+          locale: () => "de-DE",
+          date: {
+            ariaLabels: {
+              nextMonthButton: () => "foo",
+              previousMonthButton: () => "foo",
+            },
+            dateFnsLocale: () => deLocale,
+            dateFormatOverride: "y-m-ddd",
+          },
+        }}
+      >
+        <DateRange
+          startLabel="start"
+          endLabel="end"
+          value={["2016-10-10", "2016-11-11"]}
+          onChange={() => {}}
+        />
+      </I18nProvider>,
+    );
+
+    expect(screen.getByRole("textbox", { name: "start" })).toHaveValue(
+      "2016-0-010",
+    );
+    expect(screen.getByRole("textbox", { name: "end" })).toHaveValue(
+      "2016-0-011",
+    );
+  });
+
+  test("should render with the input value matching the expected format when `dateFormatOverride` is set and the language is `en-GB`", () => {
+    render(
+      <I18nProvider
+        locale={{
+          locale: () => "en-GB",
+          date: {
+            ariaLabels: {
+              nextMonthButton: () => "foo",
+              previousMonthButton: () => "foo",
+            },
+            dateFnsLocale: () => enGBLocale,
+            dateFormatOverride: "y-m-ddd",
+          },
+        }}
+      >
+        <DateRange
+          startLabel="start"
+          endLabel="end"
+          value={["2016-10-10", "2016-11-11"]}
+          onChange={() => {}}
+        />
+      </I18nProvider>,
+    );
+
+    expect(screen.getByRole("textbox", { name: "start" })).toHaveValue(
+      "2016-0-010",
+    );
+    expect(screen.getByRole("textbox", { name: "end" })).toHaveValue(
+      "2016-0-011",
+    );
+  });
+});
diff --git a/src/components/date/__internal__/date-formats/date-formats.test.ts b/src/components/date/__internal__/date-formats/date-formats.test.ts
index 099313074..9d06020b0 100644
--- a/src/components/date/__internal__/date-formats/date-formats.test.ts
+++ b/src/components/date/__internal__/date-formats/date-formats.test.ts
@@ -510,6 +510,36 @@ test("should default to en-GB locale if no locale code string passed to `getForm
   expect(format).toEqual(formatMap["en-GB"]);
 });
 
+describe("dateFormatOverride tests", () => {
+  const localeCodes = [
+    // handled locales
+    "en-CA",
+    "en-US",
+    "en-ZA",
+    "fr-CA",
+    "ar-EG",
+    // random locale to cover default switch scenario
+    "zh-HK",
+  ];
+  const dateFormatOverride = "dd Mo yyyy";
+
+  test.each(localeCodes)(
+    "should support %s locale code string passed to `getFormatData` when dateFormatOverride is provided",
+    (code: string) => {
+      const { formats, format } = getFormatData({ code }, dateFormatOverride);
+
+      const expectedFormats = getExpectedFormatForLocale(code);
+
+      expect(
+        expectedFormats.every((formatStr) => formats.includes(formatStr)) &&
+          formats.length === expectedFormats.length,
+      ).toEqual(true);
+
+      expect(format).toEqual(dateFormatOverride);
+    },
+  );
+});
+
 describe.each(euLocales)(
   "when EU locales are passed to `getFormatData`",
   (locale: string) => {
diff --git a/src/components/date/date-test.stories.tsx b/src/components/date/date-test.stories.tsx
index bf6c5eab9..713498346 100644
--- a/src/components/date/date-test.stories.tsx
+++ b/src/components/date/date-test.stories.tsx
@@ -1,7 +1,8 @@
 import React, { useState } from "react";
 import { action } from "@storybook/addon-actions";
-
 import { StoryObj } from "@storybook/react";
+import deLocale from "date-fns/locale/de";
+
 import DateInput, { DateChangeEvent } from "./date.component";
 import {
   CommonTextboxArgs,
@@ -12,6 +13,7 @@ import {
 import CarbonProvider from "../carbon-provider/carbon-provider.component";
 import Box from "../box";
 import Confirm from "../confirm";
+import I18nProvider from "../i18n-provider";
 
 export default {
   title: "Date Input/Test",
@@ -148,3 +150,55 @@ export const MultipleDates: StoryObj<typeof DateInput> = () => {
 MultipleDates.storyName =
   "Multiple Dates with onPickerOpen and onPickerClose callbacks";
 MultipleDates.parameters = { chromatic: { disableSnapshot: true } };
+
+interface I18nArgs extends CommonTextboxArgs {
+  /** The format used to override te displayed date format */
+  dateFormatOverride?: string;
+}
+
+export const I18NStory = (args: I18nArgs) => {
+  const [state, setState] = useState("2019-04-05");
+  const setValue = (ev: DateChangeEvent) => {
+    action("onChange")(ev.target.value);
+    setState(ev.target.value.formattedValue);
+  };
+  return (
+    <CarbonProvider validationRedesignOptIn>
+      <I18nProvider
+        locale={{
+          locale: () => "de-DE",
+          date: {
+            ariaLabels: {
+              nextMonthButton: () => "foo",
+              previousMonthButton: () => "foo",
+            },
+            dateFnsLocale: () => deLocale,
+            dateFormatOverride: args.dateFormatOverride || "dd/MM/yyyy",
+          },
+        }}
+      >
+        <DateInput
+          name="dateinput"
+          m={2}
+          value={state}
+          onChange={setValue}
+          onBlur={(ev) => {
+            action("onBlur")(ev.target.value);
+          }}
+          onKeyDown={(ev) =>
+            action("onKeyDown")((ev.target as HTMLInputElement).value)
+          }
+          onClick={(ev) =>
+            action("onClick")((ev.target as HTMLInputElement).value)
+          }
+          {...getCommonTextboxArgsWithSpecialCaracters(args)}
+        />
+      </I18nProvider>
+    </CarbonProvider>
+  );
+};
+I18NStory.storyName = "i18n Story";
+I18NStory.args = {
+  dateFormatOverride: "dd/MM/yyyy",
+  ...getCommonTextboxArgs(),
+};
diff --git a/src/components/date/date.test.tsx b/src/components/date/date.test.tsx
index d69a2bb39..2ee4aa1db 100644
--- a/src/components/date/date.test.tsx
+++ b/src/components/date/date.test.tsx
@@ -783,6 +783,25 @@ describe("when the `locale` is 'en-GB''", () => {
       expect(input).toHaveValue("04/04/2019");
     },
   );
+
+  test("should render with the input value matching the expected format when `dateFormatOverride` is set", () => {
+    render(
+      <I18nProvider
+        locale={{
+          locale: () => "en-GB",
+          date: {
+            ariaLabels,
+            dateFnsLocale: () => enGBLocale,
+            dateFormatOverride: "y-m-ddd",
+          },
+        }}
+      >
+        <DateInput onChange={() => {}} value="2019-04-05" />
+      </I18nProvider>,
+    );
+
+    expect(screen.getByRole("textbox")).toHaveValue("2019-0-005");
+  });
 });
 
 describe("when the `locale` is 'de-DE'", () => {
@@ -844,6 +863,25 @@ describe("when the `locale` is 'de-DE'", () => {
       expect(input).toHaveValue("04.04.2019");
     },
   );
+
+  test("should render with the input value matching the expected format when `dateFormatOverride` is set", () => {
+    render(
+      <I18nProvider
+        locale={{
+          locale: () => "de-DE",
+          date: {
+            ariaLabels,
+            dateFnsLocale: () => deLocale,
+            dateFormatOverride: "y-m-ddd",
+          },
+        }}
+      >
+        <DateInput onChange={() => {}} value="2019-04-05" />
+      </I18nProvider>,
+    );
+
+    expect(screen.getByRole("textbox")).toHaveValue("2019-0-005");
+  });
 });
 
 describe("when the `locale` is 'es'", () => {
@@ -905,6 +943,25 @@ describe("when the `locale` is 'es'", () => {
       expect(input).toHaveValue("04/04/2019");
     },
   );
+
+  test("should render with the input value matching the expected format when `dateFormatOverride` is set", () => {
+    render(
+      <I18nProvider
+        locale={{
+          locale: () => "es",
+          date: {
+            ariaLabels,
+            dateFnsLocale: () => esLocale,
+            dateFormatOverride: "y-m-ddd",
+          },
+        }}
+      >
+        <DateInput onChange={() => {}} value="2019-04-05" />
+      </I18nProvider>,
+    );
+
+    expect(screen.getByRole("textbox")).toHaveValue("2019-0-005");
+  });
 });
 
 describe("when the `locale` is 'en-ZA'", () => {
@@ -966,6 +1023,25 @@ describe("when the `locale` is 'en-ZA'", () => {
       expect(input).toHaveValue("04/04/2019");
     },
   );
+
+  test("should render with the input value matching the expected format when `dateFormatOverride` is set", () => {
+    render(
+      <I18nProvider
+        locale={{
+          locale: () => "en-ZA",
+          date: {
+            ariaLabels,
+            dateFnsLocale: () => enZALocale,
+            dateFormatOverride: "y-m-ddd",
+          },
+        }}
+      >
+        <DateInput onChange={() => {}} value="2019-04-05" />
+      </I18nProvider>,
+    );
+
+    expect(screen.getByRole("textbox")).toHaveValue("2019-0-005");
+  });
 });
 
 describe("when the `locale` is 'fr-FR'", () => {
@@ -1027,6 +1103,25 @@ describe("when the `locale` is 'fr-FR'", () => {
       expect(input).toHaveValue("04/04/2019");
     },
   );
+
+  test("should render with the input value matching the expected format when `dateFormatOverride` is set", () => {
+    render(
+      <I18nProvider
+        locale={{
+          locale: () => "fr-FR",
+          date: {
+            ariaLabels,
+            dateFnsLocale: () => frLocale,
+            dateFormatOverride: "y-m-ddd",
+          },
+        }}
+      >
+        <DateInput onChange={() => {}} value="2019-04-05" />
+      </I18nProvider>,
+    );
+
+    expect(screen.getByRole("textbox")).toHaveValue("2019-0-005");
+  });
 });
 
 describe("when the `locale` is 'fr-CA'", () => {
@@ -1088,6 +1183,25 @@ describe("when the `locale` is 'fr-CA'", () => {
       expect(input).toHaveValue("04/04/2019");
     },
   );
+
+  test("should render with the input value matching the expected format when `dateFormatOverride` is set", () => {
+    render(
+      <I18nProvider
+        locale={{
+          locale: () => "fr-CA",
+          date: {
+            ariaLabels,
+            dateFnsLocale: () => frCALocale,
+            dateFormatOverride: "y-m-ddd",
+          },
+        }}
+      >
+        <DateInput onChange={() => {}} value="2019-04-05" />
+      </I18nProvider>,
+    );
+
+    expect(screen.getByRole("textbox")).toHaveValue("2019-0-005");
+  });
 });
 
 describe("when the `locale` is 'en-CA'", () => {
@@ -1149,6 +1263,25 @@ describe("when the `locale` is 'en-CA'", () => {
       expect(input).toHaveValue("04/04/2019");
     },
   );
+
+  test("should render with the input value matching the expected format when `dateFormatOverride` is set", () => {
+    render(
+      <I18nProvider
+        locale={{
+          locale: () => "en-CA",
+          date: {
+            ariaLabels,
+            dateFnsLocale: () => enCALocale,
+            dateFormatOverride: "y-m-ddd",
+          },
+        }}
+      >
+        <DateInput onChange={() => {}} value="2019-04-05" />
+      </I18nProvider>,
+    );
+
+    expect(screen.getByRole("textbox")).toHaveValue("2019-0-005");
+  });
 });
 
 describe("when the `locale` is 'en-US'", () => {
@@ -1210,6 +1343,25 @@ describe("when the `locale` is 'en-US'", () => {
       expect(input).toHaveValue("04/04/2019");
     },
   );
+
+  test("should render with the input value matching the expected format when `dateFormatOverride` is set", () => {
+    render(
+      <I18nProvider
+        locale={{
+          locale: () => "en-US",
+          date: {
+            ariaLabels,
+            dateFnsLocale: () => enUSLocale,
+            dateFormatOverride: "y-m-ddd",
+          },
+        }}
+      >
+        <DateInput onChange={() => {}} value="2019-04-05" />
+      </I18nProvider>,
+    );
+
+    expect(screen.getByRole("textbox")).toHaveValue("2019-0-005");
+  });
 });
 
 test("should update the input value and call `onChange` with expected parameters when the user types a string with a valid leap year and the input is blurred", async () => {
@@ -1491,3 +1643,31 @@ test("should call `onPickerOpen` callback when the user opens the DatePicker and
   await user.click(document.body);
   expect(onPickerClose).toHaveBeenCalled();
 });
+
+test("should select the correct date when the locale is overridden and a date is typed into the input", async () => {
+  const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
+  const onChange = jest.fn();
+
+  render(
+    <I18nProvider
+      locale={{
+        locale: () => "de-DE",
+        date: {
+          ariaLabels,
+          dateFnsLocale: () => deLocale,
+          dateFormatOverride: "dd/MM/yyyy",
+        },
+      }}
+    >
+      <DateInput onChange={onChange} value="2019-04-05" />
+    </I18nProvider>,
+  );
+  const input = screen.getByRole("textbox");
+  await user.click(input);
+  jest.advanceTimersByTime(10);
+  await user.type(input, "05/04");
+  jest.advanceTimersByTime(10);
+
+  const grid = screen.getByRole("grid").childNodes[0].textContent;
+  expect(grid).toEqual("April 2019");
+});