Skip to content

UXDatePicker

UXDatePicker holds a UXDate and steps its year, month, and day fields. The stepping uses UXDate’s exact civil-calendar arithmetic instead of re-deriving it, so the calendar comes out right:

  • Jan 31 + 1 day is Feb 1. Day stepping goes through the day number, so it rolls across months and years exactly.
  • Jan 31 + 1 month is Feb 28, or Feb 29 in a leap year.
  • Feb 29 stepped into a non-leap year clamps to Feb 28.

The stepping model is pure and testable. Drawing the fields and wiring steppers go through the UXControl seam.

#use <UXKit>
UXDatePicker* due = new UXDatePicker();
due.setDate(UXDate.make(2026, 1, 31));
due.stepMonth(1); // Feb 28 2026 — clamped, not invented
due.stepDay(1); // Mar 1 2026 — rolled, not clamped
  • Inherits UXControl: enablement and the realization seam.

The date · date · setDate · year · month · day Stepping · stepDay · stepMonth · stepYear Calendar · daysInMonth

UXDate* date(void)

The held date, which the fields display.

void setDate(UXDate* d)

Replaces the held date.

i32 year(void)
i32 month(void)
i32 day(void)

The civil fields, read from the held date.

void stepDay(i32 delta)

Steps by whole days through the day number, so month and year rollovers are exact. Jan 31 + 1 is Feb 1, Dec 31 + 1 is next year’s Jan 1, and negative deltas step backward correctly.

void stepMonth(i32 delta)

Steps the month with year carry, clamping the day when the target month is shorter: Jan 31 + 1 month is Feb 28/29. Field steppers clamp instead of rolling because the user asked for “next month”, not “31 days later”.

void stepYear(i32 delta)

Steps the year, clamping Feb 29 to Feb 28 in a non-leap target.

static i32 daysInMonth(i32 y, i32 m)

The month’s length in the given year, leap Februaries included. It is public so the tests can check the clamping against it.

UXDatePicker on Web

App-drawn through the shared drawRect seam: the same rendering on every backend, captured here from this platform’s own paint path.

A deadline row, with field text from the formatter and steppers driving the picker:

void refresh(void) {
UXDateFormatter* f = UXDateFormatter.withPattern((u8*)"yyyy-MM-dd");
label.setText(f.format(picker.date()));
}
void onDayUp(UXControl* c) { picker.stepDay(1); refresh(); }
void onMonthUp(UXControl* c) { picker.stepMonth(1); refresh(); }