---
title: Date Picker
related:
  - title: Time Picker
    path: time.md
  - title: Date Utils
    path: ../quasar-utils/date-utils.md
  - title: Field
    path: field.md
---
The QDate component provides a method to input date. Currently it supports Gregorian (default) and Persian calendars.

> [!NOTE]
> For handling date and/or time, also check out [Quasar Date Utils](../quasar-utils/date-utils.md).

## QDate API

### Props

- `name` (string, optional)
  Used to specify the name of the control; Useful if dealing with forms submitted directly to a URL
  Examples: `'car_id'`
- `landscape` (boolean, optional)
  Display the component in landscape mode
- `mask` (string, optional), default `'YYYY/MM/DD'`
  Mask (formatting string) used for parsing and formatting value
  Examples:
    - `'YYYY-MM-DD'`
    - `'MMMM Do, YYYY'`
    - `'YYYY-MM-DD HH:mm:ss'`
- `locale` (object, optional)
  Locale formatting options
  Examples:
    - `{ monthsShort: [ 'Ian', 'Feb', 'Mar', '...' ] }`
  Object shape:
    - `days` (any[], optional)
      List of full day names (DDDD), starting with Sunday
      Examples:
        - `['Duminica', 'Luni', 'Marti', '...']`
    - `daysShort` (any[], optional)
      List of short day names (DDD), starting with Sunday
      Examples:
        - `['Dum', 'Lun', 'Mar', '...']`
    - `months` (any[], optional)
      List of full month names (MMMM), starting with January
      Examples:
        - `['Ianuarie', 'Februarie', 'Martie', '...']`
    - `monthsShort` (any[], optional)
      List of short month names (MMM), starting with January
      Examples:
        - `['Ian', 'Feb', 'Mar', '...']`
- `calendar` (string, optional), default `'gregorian'`
  Specify calendar type
  Accepts: `'gregorian'`, `'persian'`
- `color` (string, optional)
  Color name for component from the Quasar Color Palette
  Examples: `'primary'`, `'teal'`, `'teal-10'`
- `text-color` (string, optional)
  Overrides text color (if needed); Color name from the Quasar Color Palette
  Examples: `'primary'`, `'teal'`, `'teal-10'`
- `dark` (boolean, optional), default `null`
  Notify the component that the background is a dark color
- `square` (boolean, optional)
  Removes border-radius so borders are squared
- `flat` (boolean, optional)
  Applies a 'flat' design (no default shadow)
- `bordered` (boolean, optional)
  Applies a default border to the component
- `readonly` (boolean, optional)
  Put component in readonly mode
- `disable` (boolean, optional)
  Put component in disabled mode
- `model-value` (string | any[] | object, required, syncable), default `null`
  Date(s) of the component; Must be Array if using 'multiple' prop; Either use this property (along with a listener for 'update:model-value' event) OR use v-model directive
  Examples:
    - `v-model="myDate"`
    - `v-model="[myDate1, myDate2]"`
    - `v-model="[{ from: myDateFrom, to: myDateTo }]"`
    - `v-model="[myDate1, { from: myDateFrom, to: myDateTo }, myDate2]"`
- `title` (string, optional)
  When specified, it overrides the default header title; Makes sense when not in 'minimal' mode
  Examples: `'Birthday'`
- `subtitle` (string, optional)
  When specified, it overrides the default header subtitle; Makes sense when not in 'minimal' mode
  Examples: `'John Doe'`
- `default-year-month` (string, optional)
  The default year and month to display (in YYYY/MM format) when model is unfilled (undefined or null); Please ensure it is within the navigation min/max year-month (if using them)
  Examples: `'1986/02'`
- `default-view` (string, optional), default `'Calendar'`
  The view which will be displayed by default
  Accepts: `'Calendar'`, `'Months'`, `'Years'`
- `years-in-month-view` (boolean, optional)
  Show the years selector in months view
- `events` (any[] | Function, optional)
  A list of events to highlight on the calendar; If using an Array, its entries must be in YYYY/MM/DD format, regardless of the 'mask' in use; If using a function, it receives the date as a String (in YYYY/MM/DD format) and must return a Boolean (matches or not); If using a function then for best performance, reference it from your scope and do not define it inline
  Function signature: `(date?: string) => boolean`
  Examples:
    - `['2018/11/05', '2018/11/06', '2018/11/09', '2018/11/23']`
    - `date => (date[ 9 ] % 3 === 0)`
  Params:
    - `date` (string, optional)
      The current date being processed.
      Examples: `'2018/11/05'`, `'2021/10/25'`
  Returns: `boolean`
    If true, the current date will be highlighted
- `event-color` (string | Function, optional)
  Color name (from the Quasar Color Palette); If using a function, it receives the date as a String and must return a String (color for the received date); If using a function then for best performance, reference it from your scope and do not define it inline
  Function signature: `(date?: string) => string`
  Examples: `'teal-10'`, `date => (date[ 9 ] % 2 === 0 ? 'teal' : 'orange')`
  Params:
    - `date` (string, optional)
      The current date being processed.
      Examples: `'2018/11/05'`, `'2021/10/25'`
  Returns: `string`
    Color for the current date.
    Examples: `'teal'`, `'orange'`
- `options` (any[] | Function, optional)
  Optionally configure the days that are selectable; If using an Array, its entries must be in YYYY/MM/DD format, regardless of the 'mask' in use; If using a function, it receives the date as a String (in YYYY/MM/DD format) and must return a Boolean (is date acceptable or not); If using a function then for best performance, reference it from your scope and do not define it inline; Incompatible with 'range' prop
  Function signature: `(date?: string) => boolean`
  Examples:
    - `['2018/11/05', '2018/11/12', '2018/11/19', '2018/11/26']`
    - `date => (date[ 9 ] % 3 === 0)`
    - `date => (date >= '2018/11/03' && date <= '2018/11/15')`
  Params:
    - `date` (string, optional)
      The current date being processed.
      Examples: `'2018/11/05'`, `'2021/10/25'`
  Returns: `boolean`
    If true, the current date will be made available for selection
- `navigation-min-year-month` (string, optional)
  Lock user from navigating below a specific year+month (in YYYY/MM format); This prop is not used to correct the model; You might want to also use 'default-year-month' prop
  Examples: `'2020/07'`
- `navigation-max-year-month` (string, optional)
  Lock user from navigating above a specific year+month (in YYYY/MM format); This prop is not used to correct the model; You might want to also use 'default-year-month' prop
  Examples: `'2020/10'`
- `no-unset` (boolean, optional)
  Remove ability to unselect a date; It does not apply to selecting a range over already selected dates
- `first-day-of-week` (string | number, optional), default `based on configured Quasar lang language`
  Sets the day of the week that is considered the first day (0 - Sunday, 1 - Monday, ...); This day will show in the left-most column of the calendar
  Examples: `1`, `first-day-of-week="1"`, `:first-day-of-week="selectedFirstDayOfTheWeek"`
- `today-btn` (boolean, optional)
  Display a button that selects the current day
- `minimal` (boolean, optional)
  Don’t display the header
- `multiple` (boolean, optional)
  Allow multiple selection; Model must be Array
- `range` (boolean, optional)
  Allow range selection; Partial compatibility with 'options' prop: selected ranges might also include 'unselectable' days
- `emit-immediately` (boolean, optional)
  Emit model when user browses month and year too; ONLY for single selection (non-multiple, non-range)

### Methods

- `setToday(): void`
  Change model to today
- `setView(view: string): void`
  Change current view
  Params:
    - `view` (string, required)
      QDate view name
      Accepts: `'Calendar'`, `'Months'`, `'Years'`
- `offsetCalendar(type: string, descending?: boolean): void`
  Increment or decrement calendar view's month or year
  Params:
    - `type` (string, required)
      What to increment/decrement
      Accepts: `'month'`, `'year'`
    - `descending` (boolean, optional)
      Decrement?
- `setCalendarTo(year?: number, month?: number): void`
  Change current year and month of the Calendar view; It gets corrected if using navigation-min/max-year-month and sets the current view to Calendar
  Params:
    - `year` (number, optional)
      The year
    - `month` (number, optional)
      The month
- `setEditingRange(from?: object, to?: object): void`
  Configure the current editing range
  Params:
    - `from` (object, optional)
      Definition of date from where the range begins
      Object shape:
        - `year` (number, optional)
          The year
        - `month` (number, optional)
          The month
        - `day` (number, optional)
          The day of month
    - `to` (object, optional)
      Definition of date to where the range ends
      Object shape:
        - `year` (number, optional)
          The year
        - `month` (number, optional)
          The month
        - `day` (number, optional)
          The day of month

### Events

- `@update:model-value`
  Emitted when the component needs to change the model; Is also used by v-model
  Params:
    - `value` (string | any[] | object, required)
      New model value
    - `reason` (string, optional)
      Reason of the user interaction (what was picked)
      Accepts: `'add-day'`, `'remove-day'`, `'add-range'`, `'remove-range'`, `'mask'`, `'locale'`, `'year'`, `'month'`
    - `details` (object, optional)
      Object of properties on the new model
      Object shape:
        - `year` (number, required)
          The year of the date that the user has clicked/tapped on
        - `month` (number, required)
          The month of the date that the user has clicked/tapped on
        - `day` (number, required)
          The day of the month that the user has clicked/tapped on
        - `from` (object, optional)
          Object of properties of the range starting point (only if range)
          Object shape:
            - `year` (number, required)
              The year
            - `month` (number, required)
              The month
            - `day` (number, required)
              The day of month
        - `to` (object, optional)
          Object of properties of the range ending point (only if range)
          Object shape:
            - `year` (number, required)
              The year
            - `month` (number, required)
              The month
            - `day` (number, required)
              The day of month
- `@navigation`
  Emitted when user navigates to a different month or year (and even when the model changes from an outside source)
  Params:
    - `view` (object, optional)
      Definition of the current view (year, month)
      Object shape:
        - `year` (number, required)
          The year
        - `month` (number, required)
          The month
- `@range-start`
  User has started a range selection
  Params:
    - `from` (object, optional)
      Definition of date from where the range begins
      Object shape:
        - `year` (number, required)
          The year
        - `month` (number, required)
          The month
        - `day` (number, required)
          The day of month
- `@range-end`
  User has ended a range selection
  Params:
    - `range` (object, optional)
      Definition of the range
      Object shape:
        - `from` (object, required)
          Definition of date from where the range begins
          Object shape:
            - `year` (number, required)
              The year
            - `month` (number, required)
              The month
            - `day` (number, required)
              The day of month
        - `to` (object, required)
          Definition of date to where the range ends
          Object shape:
            - `year` (number, required)
              The year
            - `month` (number, required)
              The month
            - `day` (number, required)
              The day of month

### Slots

- `#default`
  This is where additional buttons can go

## Usage

> [!NOTE]
> Notice that the actual date(s) of the model are all in String format.

### Basic

```vue
<template>
  <div class="q-gutter-md row items-start">
    <q-date v-model="date" />

    <q-date v-model="date" minimal />
  </div>
</template>

<script setup>
import { ref } from 'vue'

const date = ref('2019/02/01')
</script>
```

> [!TIP]
> For landscape mode, you can use it along with `$q.screen` to make QDate responsive. Example: `:landscape="$q.screen.gt.xs"`. More info: [Quasar Screen Plugin](../options/screen-plugin.md).

Example "Landscape":

```vue
<template>
  <q-date v-model="date" landscape />
</template>

<script setup>
import { ref } from 'vue'

const date = ref('2019/02/01')
</script>
```

### Accessibility *(v2.25+)*

Each selectable day of the calendar renders as a button named with its full date. Selection — single days as well as days inside a range — is marked with `aria-pressed`, and today additionally carries `aria-current="date"`. The header navigation buttons (previous/next month and year, "Today") get localized labels from the [Quasar Language Pack](../options/quasar-language-packs.md). Keyboard focus roves over the day buttons (roving tabindex) and is restored on the equivalent day when navigation crosses into another month. A `disable`d QDate exposes `aria-disabled="true"` on its root element.

The calendar days form a single Tab stop: use the <kbd>Arrow</kbd> keys to move between days (crossing into the adjacent month at the edges), <kbd>Home</kbd> / <kbd>End</kbd> to jump to the start/end of the week, and <kbd>PageUp</kbd> / <kbd>PageDown</kbd> to switch to the previous/next month (with <kbd>Shift</kbd>: year). Each day announces its full date to screen readers, along with its selection state and whether it is today.

### Multiple selection

Notice below that the model is an Array and we specify the "multiple" prop.

Clicking on an already selected day will deselect it.

Example "Multiple days":

```vue
<template>
  <div class="q-pb-sm"> Model: {{ days }} </div>

  <q-date v-model="days" multiple />
</template>

<script setup>
import { ref } from 'vue'

const days = ref(['2019/02/01', '2019/02/10'])
</script>
```

### Range selection

Notice in the examples below that the model is an Object (single selection) or an Array of Objects (multiple selection).

> [!NOTE]
>
> - Clicking on an already selected day will deselect it.
> - The user's current editing range can also be set programmatic through the `setEditingRange` method (check the API card).
> - There are two useful events in regards to the current editing range: `range-start` and `range-end` (check the API card).

> [!WARNING]
> The `range` property is only partially compatible with the `options` prop: selected ranges might also include "unselectable" days.

Example "Single Range":

```vue
<template>
  <div class="q-pb-sm"> Model: {{ model }} </div>

  <q-date v-model="model" range />
</template>

<script setup>
import { ref } from 'vue'

const model = ref({ from: '2020/07/08', to: '2020/07/17' })
</script>
```

Example "Multiple ranges":

```vue
<template>
  <div class="q-pb-sm"> Model: {{ days }} </div>

  <q-date v-model="days" range multiple />
</template>

<script setup>
import { ref } from 'vue'

const days = ref([
  { from: '2020/07/01', to: '2020/07/10' },
  { from: '2020/07/21', to: '2020/07/25' }
])
</script>
```

### Custom title and subtitle

When not in 'minimal' mode, QDate has a computed header title and subtitle. You can override it, like in the example below.

When clicking on title then the QDate's view is changed to the calendar and when clicking on subtitle, the view will switch to year picking.

```vue
<template>
  <div class="q-gutter-md row items-start">
    <q-date v-model="date" title="John Doe" subtitle="Birthday" />
  </div>
</template>

<script setup>
import { ref } from 'vue'

const date = ref('2019/02/01')
</script>
```

### Functionality

When model is unfilled (like `null`, `void 0` / `undefined`) QDate still has to show the calendar for a month of a year. You can use `default-year-month` prop for this, otherwise the current month of the year will be shown:

When server-side rendering an unfilled QDate in SSR or SSG modes, set `default-year-month` explicitly. Otherwise, a server and browser in different time zones can select different initial months during hydration.

Example "Default year month":

```vue
<template>
  <q-date v-model="date" default-year-month="1964/08" />
</template>

<script setup>
import { ref } from 'vue'

const date = ref(null)
</script>
```

The default view can be changed.

Example "Default view":

```vue
<template>
  <q-date v-model="date" default-view="Years" />
</template>

<script setup>
import { ref } from 'vue'

const date = ref(null)
</script>
```

The first day of the week is applied depending on the [Quasar Language Pack](../options/quasar-language-packs.md) that you've set, but you can also force it, like in the example below.

Example "First day of week":

```vue
<template>
  <q-date v-model="date" first-day-of-week="1" />
</template>

<script setup>
import { ref } from 'vue'

const date = ref('2019/02/01')
</script>
```

Clicking on the "Today" button sets date to current user date. Requires the header, so you can't use it along with "minimal" mode:

Example "Today button":

```vue
<template>
  <q-date v-model="date" today-btn />
</template>

<script setup>
import { ref } from 'vue'

const date = ref('2019/02/01')
</script>
```

Example "Disable and readonly":

```vue
<template>
  <div class="q-gutter-md">
    <q-date v-model="date" disable />

    <q-date v-model="date" readonly />
  </div>
</template>

<script setup>
import { ref } from 'vue'

const date = ref('2019/02/01')
</script>
```

### Model mask

The default model mask is `YYYY/MM/DD`, however you can use custom ones too.

The `mask` prop tokens can be found at [Quasar Utils > Date utils](../quasar-utils/date-utils.md#format-for-display).

> [!WARNING]
> **Note on SSR/SSG**
>
> Using `x` or `X` (timestamps) in the mask may cause hydration errors on the client, because decoding the model String must be done with `new Date()` which takes into account the local timezone. As a result, if the server is in a different timezone than the client, then the rendered output of the server will differ than the one on the client so hydration will fail.

> [!NOTE]
> **Note on persian calendar**
>
> When using the persian calendar, the mask for QDate is forced to `YYYY/MM/DD`.

Example "Simple mask":

```vue
<template>
  <div class="q-gutter-md row items-start">
    <div>
      <div class="q-pb-sm q-gutter-sm">
        <q-badge color="teal"> Model: {{ model1 }} </q-badge>
        <q-badge color="purple" text-color="white">
          Mask: YYYY-MM-DD
        </q-badge>
      </div>

      <q-date v-model="model1" mask="YYYY-MM-DD" />
    </div>

    <div>
      <div class="q-pb-sm q-gutter-sm">
        <q-badge color="teal"> Model: {{ model2 }} </q-badge>
        <q-badge color="purple" text-color="white">
          Mask: MM-DD-YYYY
        </q-badge>
      </div>

      <q-date v-model="model2" mask="MM-DD-YYYY" />
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const model1 = ref('2019-02-15')
const model2 = ref('03-21-2019')
</script>
```

If you want to insert strings (including `[` and `]` characters) into your mask, make sure you escape them by surrounding them with `[` and `]`, otherwise the characters might be interpreted as format tokens.

Example "Mask with escaped characters":

```vue
<template>
  <div class="q-gutter-md row items-start">
    <div>
      <div class="q-pb-sm">
        <q-badge color="teal"> Model: {{ model1 }} </q-badge>
      </div>
      <div class="q-pb-sm">
        <q-badge color="purple" text-color="white">
          Mask: dddd, MMM D, YYYY
        </q-badge>
      </div>

      <q-date v-model="model1" mask="dddd, MMM D, YYYY" />
    </div>

    <div>
      <div class="q-pb-sm">
        <q-badge color="teal"> Model: {{ model2 }} </q-badge>
      </div>
      <div class="q-pb-sm">
        <q-badge color="purple" text-color="white">
          Mask: [Month ( ]MMMM ) Do[, Year ( ]YYYY )
        </q-badge>
      </div>

      <q-date v-model="model2" mask="[Month ( ]MMMM ) Do[, Year ( ]YYYY )" />
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const model1 = ref('Sunday, Apr 28, 2019')
const model2 = ref('Month ( March ) 14th, Year ( 2019 )')
</script>
```

Using the mask to connect a QDate and [QTime](time.md) to the same model:

Example "QDate and QTime on same model":

```vue
<template>
  <div class="q-gutter-sm">
    <q-badge color="teal"> Model: {{ model }} </q-badge>
    <q-badge color="purple" text-color="white" class="q-ma-md">
      Mask: YYYY-MM-DD HH:mm
    </q-badge>
  </div>

  <div class="q-gutter-md row items-start">
    <q-date v-model="model" mask="YYYY-MM-DD HH:mm" color="purple" />
    <q-time v-model="model" mask="YYYY-MM-DD HH:mm" color="purple" />
  </div>
</template>

<script setup>
import { ref } from 'vue'

const model = ref('2019-02-22 21:02')
</script>
```

> [!IMPORTANT]
> If you want to programmatically set the value of QDate, you can do so by just re-assigning the value that you pass. However, the updated value needs to be a string in the same format as your mask. Eg. in the case your mask is `'dddd, MMM D, YYYY'`, passing `'2019/04/28'` as value won't work, you would need to pass `'Sunday, Apr 28, 2019'` instead.

### Custom ad-hoc locale

If, for some reason, you need to use a custom ad-hoc locale rather than the current Quasar Language Pack that has been set, you can use the `locale` prop:

```vue
<template>
  <div class="q-pb-sm">
    <q-badge color="teal"> Model: {{ model }} </q-badge>
  </div>

  <q-date v-model="model" :locale="myLocale" />
</template>

<script setup>
import { ref } from 'vue'

const model = ref('2019/03/15')

// can supply only what needed (the rest will be taken from current locale):
const myLocale = {
  /* starting with Sunday */
  days: 'Domingo_Lunes_Martes_Miércoles_Jueves_Viernes_Sábado'.split('_'),
  daysShort: 'Dom_Lun_Mar_Mié_Jue_Vie_Sáb'.split('_'),
  months:
    'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split(
      '_'
    ),
  monthsShort: 'Ene_Feb_Mar_Abr_May_Jun_Jul_Ago_Sep_Oct_Nov_Dic'.split('_'),
  firstDayOfWeek: 1, // 0-6, 0 - Sunday, 1 Monday, ...
  format24h: true,
  pluralDay: 'dias'

  // "formatNumber" is an optional root-level key of the language pack,
  // so the ad-hoc locale has to carry it along with the date strings:
  // formatNumber: val => val.replace(/\d/g, d => '٠١٢٣٤٥٦٧٨٩'[d])
}
</script>
```

### Coloring

```vue
<template>
  <div class="q-gutter-md">
    <q-date v-model="date" color="orange" />

    <q-date v-model="date" color="yellow" text-color="black" />
  </div>
</template>

<script setup>
import { ref } from 'vue'

const date = ref('2019/02/01')
</script>
```

Example "Force dark mode":

```vue
<template>
  <div class="bg-grey-9 text-white">
    <div class="q-gutter-md">
      <q-date v-model="date" dark bordered />

      <q-date v-model="date" color="orange" text-color="black" dark bordered />
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const date = ref('2019/02/01')
</script>
```

### Highlighting events

The first example is using an array and the second example is using a function.

> [!IMPORTANT]
> The `events` array entries, as well as the String supplied to the function form, are always in `YYYY/MM/DD` format, regardless of the `mask` in use (the mask only shapes the model value). If you keep your event dates in another format, use the function form and convert before comparing.

Example "Events":

```vue
<template>
  <div class="q-gutter-md">
    <q-date v-model="date" :events="events" />

    <q-date v-model="date" :events="eventsFn" />
  </div>
</template>

<script setup>
import { ref } from 'vue'

const date = ref('2019/02/01')
const events = [
  // ...
]

function eventsFn(d) {
  const parts = d.split('/')
  return parts[2] % 2 === 0
}
</script>
```

Example "Event color":

```vue
<template>
  <div class="q-gutter-md">
    <q-date
      v-model="date"
      :events="events"
      :event-color="date => (date[9] % 2 === 0 ? 'teal' : 'orange')"
    />

    <q-date
      v-model="date"
      :events="eventsFn"
      :event-color="date => (date[9] % 2 === 0 ? 'teal' : 'orange')"
    />
  </div>
</template>

<script setup>
import { ref } from 'vue'

const date = ref('2019/02/01')
const events = [
  // ...
]

function eventsFn(d) {
  return (
    d === '2019/02/01' ||
    d === '2019/02/05' ||
    d === '2019/02/06' ||
    d === '2019/02/09' ||
    d === '2019/02/23'
  )
}
</script>
```

### Limiting options

- You can use the `options` prop to limit user selection to certain times.
- Alternatively, for a more in-depth way of limiting options, you can also supply a function (second and third example below) to `options-fn` prop.
- The `options` array entries, as well as the String supplied to the function form, are always in `YYYY/MM/DD` format, regardless of the `mask` in use.

> [!WARNING]
> The `options` property is only partially compatible with the `range` prop. Ranges might contain "unselectable" days.

Example "Options":

```vue
<template>
  <div class="q-gutter-md">
    <q-date v-model="date" :options="options" />

    <q-date v-model="date" :options="optionsFn" />

    <q-date v-model="date" :options="optionsFn2" />
  </div>
</template>

<script setup>
import { ref } from 'vue'

const date = ref('2019/02/01')

const options = [
  // ...
]

function optionsFn(d) {
  return d >= '2019/02/03' && d <= '2019/02/15'
}

function optionsFn2(d) {
  const parts = d.split('/')
  return parts[2] % 2 === 0
}
</script>
```

### Applying navigation boundaries

In the example below the navigation is restricted between 2020/07 and 2020/09.

Example "Navigation boundaries":

```vue
<template>
  <q-date
    v-model="date"
    navigation-min-year-month="2020/07"
    navigation-max-year-month="2020/09"
  />
</template>

<script setup>
import { ref } from 'vue'

const date = ref('2020/07/04')
</script>
```

### With additional buttons

You can use the default slot for adding buttons:

```vue
<template>
  <div class="q-mb-sm">
    <q-badge color="teal"> Model: {{ date }} </q-badge>
  </div>

  <q-btn icon="event" round color="primary">
    <q-popup-proxy
      @before-show="updateProxy"
      cover
      transition-show="scale"
      transition-hide="scale"
    >
      <q-date v-model="proxyDate">
        <div class="row items-center justify-end q-gutter-sm">
          <q-btn label="Cancel" color="primary" flat v-close-popup />
          <q-btn
            label="OK"
            color="primary"
            flat
            @click="save"
            v-close-popup
          />
        </div>
      </q-date>
    </q-popup-proxy>
  </q-btn>
</template>

<script setup>
import { ref } from 'vue'

const date = ref('2019/03/01')
const proxyDate = ref('2019/03/01')

function updateProxy() {
  proxyDate.value = date.value
}

function save() {
  date.value = proxyDate.value
}
</script>
```

### With QSplitter and QTabPanels

```vue
<template>
  <q-splitter v-model="splitterModel" style="height: 450px">
    <template #before>
      <div class="q-pa-md">
        <q-date v-model="date" :events="events" event-color="orange" />
      </div>
    </template>

    <template #after>
      <q-tab-panels
        v-model="date"
        animated
        transition-prev="jump-up"
        transition-next="jump-up"
      >
        <q-tab-panel name="2019/02/01">
          <div class="text-h4 q-mb-md">2019/02/01</div>
          <p
            >Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quis
            praesentium cumque magnam odio iure quidem, quod illum numquam
            possimus obcaecati commodi minima assumenda consectetur culpa fuga
            nulla ullam. In, libero.</p
          >
          <p
            >Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quis
            praesentium cumque magnam odio iure quidem, quod illum numquam
            possimus obcaecati commodi minima assumenda consectetur culpa fuga
            nulla ullam. In, libero.</p
          >
        </q-tab-panel>

        <!-- ... -->
      </q-tab-panels>
    </template>
  </q-splitter>
</template>

<script setup>
import { ref } from 'vue'

const splitterModel = ref(50)
const date = ref('2019/02/01')
const events = ['2019/02/01', '2019/02/05', '2019/02/06']
</script>
```

More info: [QSplitter](splitter.md), [QTabPanels](tab-panels.md).

### With QInput

```vue
<template>
  <div style="max-width: 300px">
    <q-input filled v-model="date" mask="date" :rules="['date']">
      <template #append>
        <q-icon name="event" class="cursor-pointer">
          <q-popup-proxy cover transition-show="scale" transition-hide="scale">
            <q-date v-model="date">
              <div class="row items-center justify-end">
                <q-btn v-close-popup label="Close" color="primary" flat />
              </div>
            </q-date>
          </q-popup-proxy>
        </q-icon>
      </template>
    </q-input>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const date = ref('2019/02/01')
</script>
```

Connecting a QDate and QTime with same model on a QInput:

Example "QDate and QTime with QInput":

```vue
<template>
  <div style="max-width: 300px">
    <q-input filled v-model="date">
      <template #prepend>
        <q-icon name="event" class="cursor-pointer">
          <q-popup-proxy cover transition-show="scale" transition-hide="scale">
            <q-date v-model="date" mask="YYYY-MM-DD HH:mm">
              <div class="row items-center justify-end">
                <q-btn v-close-popup label="Close" color="primary" flat />
              </div>
            </q-date>
          </q-popup-proxy>
        </q-icon>
      </template>

      <template #append>
        <q-icon name="access_time" class="cursor-pointer">
          <q-popup-proxy cover transition-show="scale" transition-hide="scale">
            <q-time v-model="date" mask="YYYY-MM-DD HH:mm" format24h>
              <div class="row items-center justify-end">
                <q-btn v-close-popup label="Close" color="primary" flat />
              </div>
            </q-time>
          </q-popup-proxy>
        </q-icon>
      </template>
    </q-input>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const date = ref('2019-02-01 12:44')
</script>
```

The following are **helpers** for QInput `mask` and `rules` props. You can use these for convenience or write the string specifying your [custom needs](input.md#mask).

- Property `mask` helpers: [full list](https://github.com/quasarframework/quasar/blob/dev/ui/src/components/input/use-mask.js#L6).
- Property `rules` helpers: [full list](https://github.com/quasarframework/quasar/blob/dev/ui/src/utils/patterns/patterns.js).

Examples: "date", "time", "fulltime".

More info: [QInput](input.md).

### Persian calendar

You have to set `calendar` to `persian` to use this feature.

> [!TIP]
> You can couple this with a Quasar [language pack](../options/quasar-language-packs.md) such as Persian (Farsi, `fa-IR`) to have the QDate strings translated too, for the full experience.

> [!NOTE]
> When using the persian calendar, the mask for QDate is forced to `YYYY/MM/DD`.

```vue
<template>
  <div class="q-gutter-md row items-start">
    <q-date v-model="date" calendar="persian" :locale="locale" today-btn />
  </div>
</template>

<script setup>
import { ref } from 'vue'

// Not needed if the Lang is already set to it;
// Importing here just for the demonstration purposes
import langFa from 'quasar/lang/fa-IR'

// Again, for demonstration purposes only:
// the digits formatter is a root-level key of the language pack,
// so the ad-hoc locale has to carry it along with the date strings
const locale = {
  ...langFa.date,
  formatNumber: langFa.formatNumber
}

const date = ref('1397/08/12')
</script>
```

#### Localized digits *(v2.31+)*

The day and year numbers that QDate displays (calendar cells, navigation, header, years view) follow the `formatNumber` function of the active [language pack](../options/quasar-language-packs.md), or one passed through the `locale` prop, when one is defined. The `fa` and `fa-IR` packs define it to render Persian digits, as the example above shows. The model always keeps ASCII digits (`1397/08/12`).

Any language pack (root-level `formatNumber` key) or ad-hoc locale can opt in. The function receives the ASCII digit string that would be displayed (zero-padded where QTime pads it) and returns its localized rendering:

```js
const myLocale = {
  // ...the other locale fields
  formatNumber: value => value.replace(/\d/g, digit => '০১২৩৪৫৬৭৮৯'[digit]) // Bengali digits
}
```

[QTime](time.md#custom-ad-hoc-locale) honors the same function for its header and clock face, and [QPagination](pagination.md#localized-digits) for its page numbers.

### Native form submit

When dealing with a native form which has an `action` and a `method` (eg. when using Quasar with ASP.NET controllers), you need to specify the `name` property on QDate, otherwise formData will not contain it (if it should):

The browser converts the model to a String. When using `multiple` or `range`, use your own hidden inputs if the server requires individual dates or structured range data.

Example "Native form":

```vue
<template>
  <q-form @submit="onSubmit" class="q-gutter-md">
    <q-date name="wedding" v-model="date" />

    <div>
      <q-btn label="Submit" type="submit" color="primary" />
    </div>
  </q-form>

  <q-card
    v-if="submitResult.length > 0"
    flat
    bordered
    class="q-mt-md"
    :class="$q.dark.isActive ? 'bg-grey-9' : 'bg-grey-2'"
  >
    <q-card-section
      >Submitted form contains the following formData (key =
      value):</q-card-section
    >
    <q-separator />
    <q-card-section class="row q-gutter-sm items-center">
      <div
        v-for="(item, index) in submitResult"
        :key="index"
        class="q-px-sm q-py-xs bg-grey-8 text-white rounded-borders text-center text-no-wrap"
        >{{ item.name }} = {{ item.value }}</div
      >
    </q-card-section>
  </q-card>
</template>

<script setup>
import { ref } from 'vue'

const date = ref('2020/03/20')
const submitResult = ref([])

function onSubmit(evt) {
  const formData = new FormData(evt.target)
  const data = []

  for (const [name, value] of formData.entries()) {
    data.push({
      name,
      value
    })
  }

  submitResult.value = data
}
</script>
```
