Adding a Date/Time Picker to Your App

~10 min Beginner

A focused guide to BptDateSelector, BptTimeSelector, BptDateTimeSelector, and BptDateRangeSelector. Covers format strings, range constraints, and culture.

Home / Learning / Date/Time Picker
Which control should I use?
  • BptDateSelector — date only (yyyy-MM-dd).
  • BptTimeSelector — time only (HH:mm), 12- or 24-hour.
  • BptDateTimeSelector — combined date + time in a single control.
  • BptDateRangeSelector — two coupled date pickers for "from – to" ranges.

Step 1: A basic date picker

The minimum useful markup is a single bound field. Value is DateTime?, so null means "nothing selected yet".

<BptDateSelector @bind-Value="_birthday" /> @code { private DateTime? _birthday; }

The picker pops a calendar on click, lets the user navigate by month/year, and writes the selected value back through the standard ValueChanged callback.

Step 2: Constrain the range

Pass Min and Max as DateTime? to grey out invalid days. The component enforces the constraint visually and programmatically — it won't accept a keyboard entry outside the range.

<!-- Birthday: must be in the past, at most 120 years ago --> <BptDateSelector @bind-Value="_birthday" Min="DateTime.Today.AddYears(-120)" Max="DateTime.Today" /> <!-- Booking: only future dates --> <BptDateSelector @bind-Value="_checkInDate" Min="DateTime.Today" Placeholder="Check-in date" />

Step 3: Format the displayed value

The Format parameter takes any standard or custom DateTime format string. It controls how the chosen date renders in the input — the underlying bound value is always a real DateTime, so consumers of the model don't need to parse anything.

FormatExample outputWhen to use
yyyy-MM-dd (default)2026-05-16ISO 8601 — language-neutral, sortable, ideal for technical UIs and logs.
dd/MM/yyyy16/05/2026European day-first format. Friendly for general consumer apps in the EU.
MM/dd/yyyy05/16/2026US month-first format.
d MMM yyyy16 May 2026Localized month abbreviation. Avoids ambiguity between dd/MM and MM/dd.
dddd, d MMMM yyyySaturday, 16 May 2026Long form — good for confirmation screens.
Format vs. culture Format controls the structure; the active CultureInfo controls the language. dddd, d MMMM yyyy under nb-NO renders as "lørdag, 16 mai 2026". Use BptLanguage in your layout to let users switch culture at runtime.

Step 4: Time pickers

BptTimeSelector binds to a TimeSpan? rather than DateTime?. Use HourStep and MinuteStep to constrain selectable increments — common for booking systems where slots are every 15 or 30 minutes.

<BptTimeSelector @bind-Value="_meetingStart" Format="HH:mm" MinuteStep="15" Use24HourFormat="true" /> @code { private TimeSpan? _meetingStart = new TimeSpan(9, 0, 0); // 09:00 default }

Switch to Use24HourFormat="false" and the picker shows an AM/PM toggle. Pair it with a 12-hour format string like h:mm tt for the conventional US rendering.

Step 5: Combined date + time

For appointment scheduling, log entries, or anything that needs a single moment in time, BptDateTimeSelector avoids the awkward "two controls glued together" feel.

<BptDateTimeSelector @bind-Value="_appointment" Format="yyyy-MM-dd HH:mm" MinDate="DateTime.Today" MaxDate="DateTime.Today.AddMonths(3)" MinHour="8" MaxHour="18" Placeholder="Pick an appointment slot" /> @code { private DateTime? _appointment; }

Note the parameter names differ from BptDateSelector: it's MinDate / MaxDate rather than Min / Max, because there are also MinHour / MaxHour parameters that constrain the time part. This lets you express "any weekday between 8 AM and 6 PM in the next quarter" with a single control.

Step 6: Date ranges

BptDateRangeSelector renders two coupled date pickers — picking a start date enforces the end date to be after it, and vice versa.

<BptDateRangeSelector @bind-StartDate="_from" @bind-EndDate="_to" StartPlaceholder="Check-in" EndPlaceholder="Check-out" /> @code { private DateTime? _from; private DateTime? _to; }

Two-way binding here uses the field-specific form (@bind-StartDate, @bind-EndDate) because there's no single Value — the control exposes a pair. The OnRangeSelected callback (parameterless) fires once both ends are chosen, which is the right hook for "search hotels" or "filter results" actions.

Parameter quick-reference

ParameterDateTimeDateTimeRange
Value (bind)DateTime?TimeSpan?DateTime?— (use StartDate/EndDate)
Min / Max✓ (TimeSpan?)
MinDate / MaxDate
MinHour / MaxHour
Format"yyyy-MM-dd""HH:mm""yyyy-MM-dd HH:mm"per-end
HourStep / MinuteStep
Use24HourFormat
PlaceholderStart/EndPlaceholder
Disabled

Common gotchas

  • DateTimeKind matters. Both date and date-time selectors emit DateTimeKind.Unspecified values — they describe a "wall-clock" moment, not a UTC instant. If you store them in a database, decide explicitly whether to interpret them as local or UTC and convert before persisting.
  • Min/Max are inclusive. Max="DateTime.Today" lets the user pick today's date. Use DateTime.Today.AddDays(-1) if you want a strict "must be in the past" rule.
  • TimeSpan can exceed 24h. BptTimeSelector's Value is a TimeSpan?, which has no built-in cap at 24 hours. The control's UI clamps the display, but if you set Value programmatically to TimeSpan.FromHours(30) you'll see "06:00". Always normalize inputs.

An unhandled error has occurred. Reload 🗙

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please reload the page.