> ## Documentation Index
> Fetch the complete documentation index at: https://docs.awaitio.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Input Date

> Asks for a calendar date.

`io.input.date()` requests a calendar date, without a time, and returns it as a [luxon](https://moment.github.io/luxon/) `DateTime`. Provided by the `@awaitio/input-date` package.

<Frame>
  <img src="https://mintcdn.com/awaitio/MjbT5AW66vMXbVck/images/io-input-date.png?fit=max&auto=format&n=MjbT5AW66vMXbVck&q=85&s=14afd120fadf146c6a36674da0c0c565" alt="A Date field with a picked date, and help text under it" width="1004" height="212" data-path="images/io-input-date.png" />
</Frame>

The value is a day, not an instant, so no time zone is involved: the date the person picks is the date the handler gets.

## Install

```bash theme={null}
npm install @awaitio/input-date
```

## Setup

Register it under the key you want in `io`, see [Input components](/core/components):

```ts app.ts {5} theme={null}
import { inputDate } from '@awaitio/input-date';

export const app = new AwaitIO({
  // name, actionsDirectory, theme, secret, users…
  components: { input: { date: inputDate } },
});
```

## Usage

```ts theme={null}
import { DateTime } from 'luxon';

const dueOn = await io.input.date('Due date', {
  defaultValue: DateTime.now().plus({ days: 14 }),
  min: DateTime.now(),
});

dueOn.toISODate(); // '2026-11-02'
```

## Props

| Prop | Type | Required | Description |
| - | - | - | - |
| `helpText` | `string` | Optional | Secondary text under the field. |
| `defaultValue` | `DateTime \| Date \| string` | Optional | The value the field starts with. Empty when left out. |
| `min` | `DateTime \| Date \| string` | Optional | The earliest date that can be picked, itself included. |
| `max` | `DateTime \| Date \| string` | Optional | The latest date that can be picked, itself included. |
| `disabled` | `boolean` | Optional | Shows the starting value without letting it change; the handler gets that value whatever the browser sends. |

`defaultValue`, `min` and `max` take a luxon `DateTime` (its own zone's day), a JavaScript `Date` (its day in UTC) or a `'YYYY-MM-DD'` string. An impossible date such as `2026-02-30` throws when the io call is made.

## Optional

The field is required. Chain `.optional()` to let it stay empty; the handler then gets `DateTime | undefined`, see [Optional fields](/core/components#optional-fields).

```ts theme={null}
const birthday = await io.input.date('Birthday').optional();
```

## Returns

A luxon `DateTime` at the start of the picked day in the UTC zone. Use `.toISODate()` to store it as `'YYYY-MM-DD'`.

## Built-in validation

The browser checks the date before sending, and the server checks every answer again:

| When | Message |
| - | - |
| No date picked | `<label>: pick a date.` |
| A date that does not exist | `<label>: pick a date that exists.` |
| Earlier than `min` | `<label> must not be earlier than <min>.` |
| Later than `max` | `<label> must not be later than <max>.` |

`<min>` and `<max>` are printed as `YYYY-MM-DD`.

## Custom validation

Chain `.validate()` for a check of your own. It runs on the server after the checks above, gets the value the handler would get and returns a message to show under the field, or nothing when the value is fine; see [Custom validation](/core/components#custom-validation).

```ts theme={null}
const shipsOn = await io.input.date('Ships on').validate((date) => {
  return date.weekday <= 5 ? undefined : 'Pick a working day.';
});
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.