Date and time controls

UIDateTimeEdit is one segmented UITextInput surface with date, time, and local date-time modes. UIDatePicker adds a calendar popup, UITimePicker configures time mode without a popup, and UIDateTimePicker combines a calendar and time editor in one popup. UICalendar can also be used as a standalone widget.

Native XML

<datepicker id="birthday" value="1990-06-17" />
<timepicker id="start" value="20:30:00" minute-step="15" />
<datetimepicker id="scheduled" value="2026-09-28T20:30:00" />
<datetimeedit mode="date" value="2026-09-28" />
<calendar first-day-of-week="1" value="2026-09-28" />

Values are optional typed civil values: CalendarDate, TimeOfDay, and LocalDateTime, from <eepp/system/datetime.hpp>. They do not carry time zones. Use setDate(), setTime(), or setDateTime() and the corresponding optional getters. clear() removes a value when allow-empty is true (the default). Canonical setters clamp to the active mode’s bounds and emit OnValueChange only when the typed value changes. The value property exposes ISO serialization for ordinary data binding. Hidden seconds and milliseconds remain part of the value; serialization preserves nonzero milliseconds even if they are not displayed.

Serialization and Unix timestamps

DateTimeFormatter in <eepp/system/datetimeformat.hpp> formats ISO values independently of the display locale and parses them with an explicit pattern:

using namespace EE;
using namespace EE::System;

const CalendarDate date{ 2026, 9, 28 };
const std::string storedDate = DateTimeFormatter::toISODate( date ); // "2026-09-28"
const auto restoredDate = DateTimeFormatter::parseDate( storedDate, DateTimeFormat( "yyyy-MM-dd" ) );

const LocalDateTime value{ date, { 20, 14, 32, 125 } };
const std::string storedValue = DateTimeFormatter::toISOLocalDateTime( value, true );
const auto restoredValue = DateTimeFormatter::parseDateTime(
    storedValue, DateTimeFormat( "yyyy-MM-dd'T'HH:mm:ss.SSS" ) );

// The application knows this value uses UTC-03:00; the types do not store a timezone.
const Int32 utcOffsetSeconds = -3 * 60 * 60;
const auto timestamp = value.toUnixTimestampMilliseconds( utcOffsetSeconds );
if ( timestamp ) {
    const auto restored = LocalDateTime::fromUnixTimestampMilliseconds(
        *timestamp, utcOffsetSeconds );
}

Unix timestamps count seconds or milliseconds since 1970-01-01T00:00:00Z, without leap seconds. CalendarDate::toUnixTimestamp() uses midnight UTC; fromUnixTimestamp() extracts the UTC date containing that instant. LocalDateTime conversions default to UTC and accept an offset in seconds, where local = UTC + offset. The offset is not inferred from the system timezone and does not resolve daylight-saving gaps or ambiguous times. Applications using named timezones must resolve the offset for the particular date/time before conversion.

The seconds methods discard milliseconds, rounding down even before the epoch. The toUnixTimestampMilliseconds() / fromUnixTimestampMilliseconds() methods preserve them. Conversions return std::optional : invalid civil values, an out-of-range year, or an unrepresentable Int64 millisecond timestamp produce std::nullopt. The full Int32 year range fits in Int64 seconds, but only part of it fits in Int64 milliseconds. These conversions are independent of locale, time_t size, and the machine’s timezone. For a date-only database column, ISO date text or typed date fields preserve its civil meaning directly.

Editing

Click a section to select it. Left/Right navigate sections; Home/End select the first/last. Up/Down step the active section. Numeric entry automatically advances when a complete value has been entered. Pending digits are shown with underscores, commit on navigation, Enter, focus loss, or timeout, and can be canceled with Escape. Configure the timeout in C++ with setPendingDigitTimeout() (default: one second). Delete/Backspace clear the value when allowed. Copy and select-all use normal input commands. Paste replaces the whole value, including when only one section is selected, and accepts ISO regardless of the display format. Invalid input preserves the previous valid value. Wheel edits require both focus and wheel-editing: true; wheel editing is disabled by default. allow-editing: false prevents user mutation.

Month/year edits clamp the day at month ends. Time-only arithmetic wraps within the day; local date-time arithmetic carries across date boundaries. AM/PM entry changes the period without advancing the date. Utility arithmetic outside the representable Int32 year range leaves the value unchanged.

Locale and properties

Display defaults come from DateTimeLocale::system() (Windows regional settings on Windows), with a centralized locale-name fallback for information unavailable through the standard library. setLocale() accepts explicit date order/separator, hour cycle, month and weekday names, AM/PM labels, and first weekday; this also supports locales unavailable on the host. fromLocaleName() resolves ordering and cycle fallbacks; applications can supply translated names in the returned structure.

Property

Meaning

Show seconds without milliseconds; default Show milliseconds and seconds; default Positive integer steps Date-mode ISO bounds Time-mode ISO bounds Local date-time ISO bounds Empty-value and focused wheel editing policies

Parent picker popup to scene root instead of its window container Inspectable picker open state Calendar weekday: Sunday Calendar Calendar ISO navigation state