Skip to main content
iVentureTeam

float_time_selection

Time off "custom hours" in Odoo use float_time_selection: a float field dressed as a clock time, with an hour and minute dropdown popover and locale-aware display.

Siddharth JambukiyaSiddharth JambukiyaOdoo Techno-Functional Consultant
August 18, 2026Updated August 18, 20265 min read
Technical namefloat_time_selection
Field typesfloat
Viewsform (time off request forms)
Modulehr_holidays (Time Off)
Used in core6 occurrences, all in hr_holidays on the time off request and allocation forms
VersionsOdoo 20.0, Odoo 19.0, Odoo 18.0
No-code setupNo. Set in view XML; in Studio a Decimal field offers the plain Time widget instead
Alternativesfloat_time, datetime, timesheet_uom

What the Time Selection field does

Odoo stores durations and times-of-day alike as floats: 8.25 can mean eight and a quarter hours, or a quarter past eight in the morning. The plain float_time widget formats such a float as HH:MM but still asks users to type. float_time_selection goes one step further for the time-of-day case: clicking the input opens a popover with two dropdowns, hours 0 through 23 and minutes 0 through 59, so picking 07:30 for the start of a half-day leave takes two clicks and zero format knowledge.

The component extends FloatTimeField and keeps its input fully functional: users can still type either a HH:MM string or a decimal, and the widget converts between the two representations both ways. Under the hood the value remains an ordinary float of hours on the record.

Since 19.0 the readonly rendering is localized through Luxon: the same stored 13.5 reads 1:30 PM under an English (US) language and 13:30 under most European ones.

What this means for your team

The widget exists because of a very specific HR pain: employees requesting a half day from, say, 09:00 to 13:00 were previously asked to express that as decimal hours, and someone always typed 9.3 meaning 09:30. Every one of those slips flows into allocation math and payroll exports. Two dropdowns remove the format guessing entirely, which is why Odoo's own Time Off forms are the widget's only core users.

If you run custom HR or scheduling models, shift start times, booking slots, cut-off times, this is the pattern to reuse: keep the storage as a float (it sums, averages and exports trivially) and put this widget on the form. Your data team keeps clean numbers while your users see a clock. The one design note: it is a time-of-day control with a 0 to 23 hour list, so it is the wrong pick for durations that can exceed a day; use float_time there.

Supported options in Odoo 19

Verified against float_time_selection.js and its popover component in the Odoo 19.0 hr_holidays module. The widget declares nothing of its own; the descriptor spreads floatTimeField, so the float_time options apply, including that widget's known camelCase quirk, inherited here unchanged.

OptionTypeWhat it does
displaySecondsbooleanInherited from float_time: shows seconds in the formatted value. Note the camelCase spelling; the declared snake_case display_seconds is never read by extractProps.
typestringInherited from float_time: the underlying input's type attribute. Leave at text; the popover assumes the standard input.(default: text)

The inherited seconds option is mislabeled in the source. The float_time descriptor declares display_seconds, but its extractProps reads options.displaySeconds. Only the camelCase spelling works, on float_time and therefore here too. Seconds rarely matter for a time-of-day picker, but if you enable them, spell it displaySeconds.

Working examples

How core uses it (time off request)

<field name="request_hour_from"
       widget="float_time_selection"/>

No options needed; the popover and conversions are the default behavior.

Reuse on a custom shift model

<field name="shift_start"
       widget="float_time_selection"/>
<!-- shift_start = fields.Float() stores 13.5 for 1:30 PM -->

The model side stays a plain float, so aggregations and pivot views keep working on the raw hours.

Commit timing, parsing and rounding

Three mechanics from the source explain the widget's edge behaviors.

The write lands on popover close. Dropdown changes update internal state; only the popover's onClose pushes the float onto the record. A user who picks values and then clicks elsewhere still gets their choice saved, because clicking away is what closes the popover, but nothing hits the record while both dropdowns are being adjusted.

Typed input is dual-format. The change handler first tries to split on a colon; failing that it parses the raw text as a decimal float. Typing 7:45 and typing 7.75 produce the same stored value. Invalid halves (say 7:xx) fall through to the decimal path.

Minutes are rounded from the float. Converting a stored float to the dropdowns rounds minutes to the nearest whole minute, so a float like 8.333 displays as 08:20. Any sub-minute precision is preserved in storage until the user re-picks a value, at which point it is replaced by the whole-minute choice.

Version compatibility

VersionStatusNotes
Odoo 20.0Partial / changedNot released. Display reworked, base preview popover disabled here, inherited option renames. See below.
Odoo 19.0VerifiedAdds locale-aware readonly display. Verified against the shipped source.
Odoo 18.0VerifiedFirst version with this widget; readonly display was the raw HH:MM format.
Odoo 17.0Not availableWidget does not exist; the component is absent from the 17.0 tree.
Odoo 16.0Not availableWidget does not exist; the component is absent from the 16.0 tree.

Upgrade note for 18 to 19. The widget arrived in 18.0 with raw HH:MM readonly display; 19.0 added the locale-aware rendering, so the same data reads 1:30 PM instead of 13:30 for 12-hour-clock languages. Nothing changes in storage or the picker itself.

What is changing in Odoo 20

Odoo 20 is expected at Odoo Experience in Brussels, 24 to 26 September 2026. The development branch is unstable until release, and we re-verify this page against the shipped version.

Three changes are visible so far. The readonly display is reworked to compute directly from the float and always render an h:mm a style time. The base float_time widget gains a typing-preview popover on master, and this widget explicitly disables it with an empty openPopover override so the preview cannot fight the selection popover. And through the inherited descriptor it picks up float_time's master-branch option renames, where show_seconds replaces the misdeclared display_seconds and new numeric and unit options appear. None of this changes view XML that uses the widget without options.

Common problems and fixes

SymptomCause and fix
Typed decimal like 7.75 turns into 07:45By design: input parses either HH:MM or decimal hours into the same float. No fix needed; both notations are accepted.
Value seems not to save while pickingThe record is only updated when the popover closes. Click outside the popover (or otherwise close it); the chosen time commits then.
Displayed minutes differ slightly from stored valueThe dropdowns round the float to whole minutes for display; sub-minute precision stays in storage until re-picked. Accept whole-minute precision on these fields, or avoid computing sub-minute floats into them.
Widget not found on Odoo 17 or earlierIt shipped with hr_holidays in 18.0. Use float_time on older versions, or backport the two components in a custom module.
Time shows as 13:30 for some users and 1:30 PM for othersThe 19.0 readonly display follows each user's language's clock convention. By design; align user languages if a uniform format is required.
display_seconds option has no effectThe inherited descriptor reads the camelCase displaySeconds only. Spell the option displaySeconds.

Time Selection field vs the alternatives

WidgetBest forKey difference
float_time_selectionTime-of-day floats picked with the mouseAdds hour and minute dropdowns and commits on popover close
float_timeDurations and keyboard-first HH:MM entryFormats the float but offers no picker, and handles values beyond 23:59
datetimeActual calendar momentsStores a timezone-aware datetime, full calendar and clock picker
timesheet_uomTimesheet durations across encoding unitsDispatches to the company's configured duration widget instead of a clock

The practical test: is the float a moment on the clock or an amount of time? Clock moment with mouse-first entry: this widget. Amount, or keyboard-first entry: float_time. An actual calendar moment: a datetime field.

Frequently asked questions

What is the float_time_selection widget in Odoo?+
A form widget from the Time Off module that renders a float field as a clock time with a popover of hour (0 to 23) and minute (0 to 59) dropdowns. It powers the custom-hours inputs on time off requests, storing the picked time as plain float hours, 13.5 for 1:30 PM.
Can users still type instead of using the dropdowns?+
Yes. The input accepts both HH:MM and decimal notation; 7:45 and 7.75 store the same value. The popover is an accelerator, not a constraint.
When exactly is the picked time saved?+
The record updates when the popover closes; changing a dropdown alone does not write. This is explicit in the source, where the popover's onClose handler performs the record update.
Why does the same value display differently per user?+
Since 19.0 the readonly rendering is localized: 12-hour-clock languages see 1:30 PM, 24-hour ones see 13:30. Odoo 18 displayed the raw HH:MM for everyone.
Can I use float_time_selection outside Time Off?+
Yes, on any float field in a form view of a database with hr_holidays installed, since the widget lives in that module. Keep it to time-of-day semantics; its hour list stops at 23, so durations above a day belong to float_time.
Is float_time_selection available in Odoo 16 or 17?+
No. It first shipped in 18.0. Earlier versions use the plain float_time widget for these fields.

Half-day requests turning into payroll corrections?

Clean time capture upstream saves reconciliation downstream. We configure Odoo Time Off end to end, from accrual plans to the request forms, and bring the same clock-picker UX to your custom shift and scheduling models.

Book a free consultation

How this page was produced

This page was verified by reading float_time_selection.js and float_time_selection_popover.js in the Odoo 19.0 hr_holidays module, plus the inherited float_time_field.js descriptor in web, and cross-checking the popover commit and parsing logic line by line. Version availability and differences come from diffing the files across 16.0 through master, including the master-branch openPopover override. The Odoo 20 section reads the unreleased development branch and is marked as such. Corrections welcome via our contact page.