Skip to main content
iVentureTeam

daterange

Time off requests, events and planned tasks all edit two dates in one calendar popover. That is the daterange widget: one field element, a paired date field, and more options than any other date widget in Odoo.

Siddharth JambukiyaSiddharth JambukiyaOdoo Techno-Functional Consultant
August 12, 2026Updated August 12, 20267 min read
Studio nameDate Range
Technical namedaterange
Field typesdate, datetime
Viewsform, list (single unprefixed registration, so it renders wherever the field appears)
Also registered asdefined in the same file and registry chain as date and datetime
Moduleweb, present in every Odoo database
Used in core21 occurrences across 9 modules, including hr_holidays, calendar, project, event, mail, sale
VersionsOdoo 20.0, Odoo 19.0, Odoo 18.0
No-code setupYes, via Odoo Studio (Enterprise), with a dedicated documented flow
Alternativesdate, datetime, remaining_days

What the Date Range widget does

The daterange widget displays a period, start date to end date, on a single line and edits both ends in one calendar popover. Time off requests in hr_holidays, event dates, and planned task dates all use it.

The mechanic that confuses most people: the widget sits on one field and is told where its partner is. Put it on the start field and set options="{'end_date_field': 'date_end'}", or put it on the end field and set start_date_field. The source then injects the partner field into the view automatically as an editable dependency, so you do not need a second visible field element.

It is defined in datetime_field.js in the web module, in the same registry chain as date and datetime, and inherits everything those widgets can do: precision limits, min and max dates, minute rounding, future date warnings. On top it adds the range pairing, a range toggler for optional ranges, and cross-field validation.

What this means for your team

Anywhere your team schedules something with a beginning and an end, a rental, an intervention, a leave, a campaign, two separate date fields make people scroll and make invalid pairs possible. The range widget removes both problems: one line, one popover, and the picker itself makes an end date before the start date impossible to select in a single motion.

The subtle win is the optional range. A field service visit may have a confirmed start and an open end. With daterange the end date stays hidden behind a toggler until someone needs it, which keeps forms clean without losing the ability to record a full period.

The equally subtle trap is validation. If the end field is required and someone fills only the start, the record refuses to save with a message pointing at a field that is not visibly on the form. That is the widget's cross-field check doing its job; it belongs in your user training.

Setting it up in Odoo Studio (no code)

Studio documents this widget by name, with its own flow (see the Date Range section of the Studio fields docs).

  1. Identify or create the underlying second field: an existing Date or Date & Time field that will act as the start or end.

  2. Add a Date & Time field, then in its properties set Widget to Date Range.

  3. Enter the label, then pick the partner field in the Start date field or End date field dropdown.

  4. Enable Always range if both dates must always be filled.

  5. Optionally set the Date & Time properties Studio exposes: precision, time interval, future date warning, accepted date limits.

Studio's tip is worth repeating: make the underlying partner field invisible or remove it from the view, otherwise the same date appears twice.

What Studio cannot do here

Studio covers this widget unusually well. What still needs XML is anything conditional: a range whose end field becomes required only in certain states, domain-dependent min and max dates, or applying the widget inside embedded list views of a one2many. The option set itself is fully reachable from Studio's properties panel.

Supported options in Odoo 19

Verified against datetime_field.js in the Odoo 19.0 web module. The descriptor composes the date and datetime descriptors, so the table below is the full effective set for daterange; rounding, show_time and show_seconds only apply on datetime fields.

OptionTypeWhat it does
start_date_fieldfield nameNames the date or datetime field that holds the start of the range, when the widget sits on the end field. The named field is injected into the view automatically as an editable dependency.
end_date_fieldfield nameNames the field holding the end of the range, when the widget sits on the start field. Mutually exclusive with start_date_field: setting both logs a console warning and only start_date_field is used.
always_rangebooleanAlways displays both inputs, even when empty, and removes the range toggler. Use it when a record only makes sense with both dates filled.(default: false)
min_datestringEarliest selectable date, ISO formatted (2026-12-31) or the literal today. Earlier dates are grayed out in the picker.
max_datestringLatest selectable date, same format as min_date. Later dates are grayed out.
warn_futurebooleanShows a warning icon with the message This date is in the future when either selected date is past today.(default: false)
min_precisionselectionSmallest unit the picker forces the user through: days, months, years or decades. Set months to make the picker a month selector.
max_precisionselectionLargest unit available when zooming out in the picker: days, months, years or decades.
numericbooleanSwitches display from the written format (Dec 31, 2026) to the numeric format of the user's language (12/31/2026). List columns switch to the narrower numeric width.(default: false)(since Odoo 19.0)
roundingintegerMinute step of the time selector on datetime fields. Set 15 to work in quarter hours. If rounding is not a number and show_seconds is enabled, the source drops to second-level steps.(default: 5)
show_timebooleanOn datetime fields, hides the time part of the displayed value when set to false. Useful to declutter list views while keeping full timestamps in the database.(default: true)
show_secondsbooleanShows seconds in the readable datetime format. Odoo 18 defaulted this to true; 19.0 flipped the default to false.(default: false)
placeholder_fieldfield nameReads the placeholder text from another field on the record instead of a fixed placeholder attribute.(since Odoo 19.0)

Never set both start_date_field and end_date_field. The source treats this as a mistake, logs a console warning, and honors only start_date_field. Also worth knowing: if rounding is not a number and show_seconds is on, the picker switches to second-level rounding automatically.

Working examples

Start field paired with an end field

<field name="date_start" widget="daterange"
       options="{'end_date_field': 'date_end'}"/>

The date_end field does not need its own element; the widget injects it as an editable view dependency.

Mandatory full range

<field name="date_start" widget="daterange"
       options="{'end_date_field': 'date_end', 'always_range': True}"/>

Both inputs are always displayed, even while empty, and the range toggler disappears.

Quarter-hour datetime range with limits

<field name="booking_start" widget="daterange"
       options="{'end_date_field': 'booking_end', 'rounding': 15, 'min_date': 'today'}"/>

The time selector moves in 15 minute steps and past dates are grayed out.

Numeric display format

<field name="date_start" widget="daterange"
       options="{'end_date_field': 'date_end', 'numeric': True}"/>

Dates render as 12/31/2026 style instead of Dec 31, 2026; in list views the column also gets the narrower numeric width.

How the two fields stay in sync

Four behaviors in the source explain most of what users see.

The partner field is auto-injected. fieldDependencies adds the field named in start_date_field or end_date_field to the view model with readonly: false. This is why the second date saves even though it has no visible field element of its own.

The range toggler only shows when the range is optional. The picker offers the toggle arrow only if a partner field exists and the field is neither required nor always_range. Toggling on seeds the missing date one hour after the start (or one hour before the end); if both are empty it starts from now.

Validation is cross-field. isValid rejects the record when one end of the range is set, the other is empty, and that other field is required. The error names the injected field, which may not be visible on the form.

Display width and same-day rendering. In lists the column reserves twice the single-date width plus 30 pixels for the arrow. On datetime ranges that start and end the same day, the end value drops the date part and shows only the time.

Version compatibility

VersionStatusNotes
Odoo 20.0In developmentNot released. The development branch shows no option changes, only an internal framework rewrite; see below.
Odoo 19.0VerifiedAll 13 options in the table confirmed against the shipped source.
Odoo 18.0Partial / changedNo numeric or placeholder_field yet, a condensed option existed, and seconds displayed by default. Verified against the 18.0 source.

Upgrading from Odoo 18? Three changes: the undocumented condensed display option was removed in 19.0, the numeric format option and placeholder_field were added, and the seconds default flipped (18.0 showed seconds by default, 19.0 hides them unless show_seconds is set). XML using condensed keeps working but the option is ignored.

What is changing in Odoo 20

Odoo 20 is expected at Odoo Experience in Brussels, 24 to 26 September 2026. The changes below are read from the public development branch and are not final until release.

The option surface is unchanged. We compared every option name and every options.* read in datetime_field.js between 19.0 and the development branch: identical, and the date / daterange / datetime registrations are untouched. The file is being rewritten internally for the new Owl framework (signals, useProps), so JavaScript patches that extend the class will need review, but view XML should carry over untouched. We re-verify this page after release.

Common problems and fixes

SymptomCause and fix
Console warning about start_date_field and end_date_fieldBoth options are set on the same field, which the source treats as a configuration error. Keep exactly one of the two options; the widget belongs on one field of the pair.
Record will not save and names a field that is not on the formThe injected partner field is required but empty; the widget's cross-field validation blocks the save. Fill both dates, make the partner field not required, or show it on the form so the error is visible.
No toggle arrow to add an end dateThe toggler is hidden when the field is required or always_range is set, and when no partner field option is configured. Check the options: an optional range needs start_date_field or end_date_field set and no always_range.
End date shows only a timeOn datetime ranges that end the same day they start, the widget intentionally drops the repeated date part. Nothing to fix; select an end date on another day and the date part returns.
Time selector skips minutesThe default rounding is 5 minutes. Set options="{'rounding': 1}" for minute precision, or a larger step like 15 for quarter hours.

Date Range widget vs the alternatives

WidgetBest forKey difference
daterangeA period with a start and an end edited togetherOne widget drives two fields through a shared picker with cross-field validation
dateA single date with no paired endSame picker, no pairing, no range logic
datetimeA single timestampOne value; daterange composes this widget for each end of the pair
remaining_daysDeadlines your team scans by urgencyDisplays In 5 days instead of the date itself

The practical test: two dates that mean one period belong in a daterange. Two dates with independent meanings, such as an order date and a delivery date, belong in two plain fields. A single deadline your team tracks by urgency is a job for remaining_days.

Frequently asked questions

How do I add a date range in Odoo without code?+
With Studio (Enterprise): add a Date & Time field, set its Widget to Date Range, then pick the partner field under Start date field or End date field. Odoo's Studio documentation describes this exact flow, including making the underlying second field invisible.
Which field does the widget go on, the start or the end?+
Either. Put it on the start field and set end_date_field, or on the end field and set start_date_field. The only rule from the source: never both options at once.
Does the second field need to be in the view?+
No. The widget declares it as a field dependency with readonly: false, so it is loaded and saved even without its own element. Keeping it out of the view avoids showing the same date twice.
Can the end date be optional?+
Yes, that is the default when the field is not required and always_range is off. Users add the second date through the toggle arrow in the picker, and the widget seeds it one hour from the existing date.
Why does saving fail with a message about a hidden field?+
The widget validates the pair: if one end is filled and the other is a required field left empty, the record is invalid. Show the partner field, make it not required, or fill both dates.
Does daterange work on date fields or only datetime?+
Both. supportedTypes in the source lists date and datetime. On date fields the time-related options (rounding, show_time, show_seconds) are simply not applicable.

Scheduling screens your team actually trusts?

Leave requests that block on hidden required fields, rental periods that save half filled, planners that allow impossible ranges: date logic is where Odoo forms quietly leak errors. We build and repair scheduling flows, cross-field validation and planning views on Odoo 16 through 19.

Book a free consultation

How this page was produced

The option table was read from datetime_field.js in the Odoo 19.0 web module, including the extractProps and fieldDependencies code paths, and the same file was compared on the 18.0 branch (which is where the condensed removal and seconds default flip were found) and on the development branch for the Odoo 20 section. Studio steps follow Odoo's own Studio documentation for the Date Range widget. Spotted an error or a version difference? Tell us and we will correct the page.