Slint Kit Documentation

Times and zones

Date and Time Field for Slint

KitDateTimeField · Slint Kit 0.3.1

Two text drafts accepted as one local date and time.

Two text drafts accepted as one local date and time.
Native app built from the example below.

Try the component

Download the complete project, extract it and run cargo run --locked in its folder. Rust 1.92+; Slint Kit 0.3.0 from crates.io. You can also copy the four files below.

Edit both fields, then accept. Rust validates and accepts one complete LocalDateTime; it never accepts half a date/time pair.

ui/app.slint

export { KitFormValidation, HtmlInputKind, NumberInputFormat, KitInputConstraints, KitValidationResult, KitValidityState } from "@kit/kit.slint";
import {KitDateTimeField,KitButton,KitThemes,CivilDateView,LocalTimeView,LocalDateTimeView,LocalDateTimeDraft,ZonedDateTimeDraft,ZonedTimePresentation,AmbiguousTimeChoice} from "@kit/kit.slint";
export {CivilDateView,LocalTimeView,LocalDateTimeView,LocalDateTimeDraft,ZonedDateTimeDraft,ZonedTimePresentation,AmbiguousTimeChoice}
export component App inherits Window {
 title:"date-time-field";preferred-width:560px;preferred-height:440px;max-width:100000px;max-height:100000px;background:KitThemes.light.canvas;
 in-out property <string> date-text:"2026-10-17";in-out property <string> time-text:"09:30";in-out property <string> zone-text:"America/Toronto";
 in property <LocalDateTimeView> accepted-local;in property <string> error;in property <string> accepted;
 in property <ZonedTimePresentation> resolution;callback commit(LocalDateTimeDraft);callback edit();callback choose(AmbiguousTimeChoice);callback cancel();
 VerticalLayout {padding:24px;spacing:16px;alignment:start;
 control:=KitDateTimeField{label:"Appointment";date-text<=>root.date-text;time-text<=>root.time-text;date-error:root.error;
 accepted-value:root.accepted-local;commit-requested(draft)=>{root.commit(draft);}
 edited(draft)=>{root.edit();}cancelled=>{root.cancel();}
 }
 KitButton{text:"Accept";activated=>{root.commit({date:root.date-text,time:root.time-text});}}
 Text{text:"Accepted: "+root.accepted;color:KitThemes.light.text-primary;wrap:word-wrap;}
 }
}

src/main.rs

use slint::ComponentHandle;
use slint_kit::{CivilDate, DraftValue, LocalDateTime, LocalTime, TimePrecision};
use std::{cell::RefCell, rc::Rc};
mod ui {
    slint::include_modules!();
}
fn local(date: &str, time: &str) -> Option<LocalDateTime> {
    match (
        CivilDate::parse_iso(date),
        LocalTime::parse(time, TimePrecision::Minute),
    ) {
        (DraftValue::Parsed(date), DraftValue::Parsed(time)) => {
            Some(LocalDateTime::new(date, time))
        }
        _ => None,
    }
}
fn view(value: LocalDateTime) -> ui::LocalDateTimeView {
    ui::LocalDateTimeView {
        date: ui::CivilDateView {
            year: value.date.year(),
            month: value.date.month() as i32,
            day: value.date.day() as i32,
        },
        time: ui::LocalTimeView {
            hour: value.time.hour() as i32,
            minute: value.time.minute() as i32,
            second: value.time.second() as i32,
        },
    }
}
fn main() -> Result<(), slint::PlatformError> {
    let app = ui::App::new()?;
    slint_kit::init_form_validation!(ui, app);
    let initial = local("2026-10-17", "09:30").unwrap();
    app.set_accepted_local(view(initial));
    app.set_accepted("2026-10-17 09:30".into());
    let state = Rc::new(RefCell::new(initial));
    let weak = app.as_weak();
    let shared = state.clone();
    app.on_commit(move |draft| {
        if let Some(app) = weak.upgrade() {
            let Some(value) = local(&draft.date, &draft.time) else {
                app.set_error("Use a valid YYYY-MM-DD date and HH:mm time".into());
                return;
            };
            *shared.borrow_mut() = value;
            app.set_accepted_local(view(value));
            app.set_error("".into());
            app.set_accepted(
                format!(
                    "{} {}",
                    value.date.iso_string(),
                    value.time.format(
                        TimePrecision::Minute,
                        slint_kit::ClockFormat::TwentyFourHour
                    )
                )
                .into(),
            );
        }
    });
    let weak = app.as_weak();
    app.on_edit(move || {
        if let Some(app) = weak.upgrade() {
            app.set_error("".into());
        }
    });
    let weak = app.as_weak();
    let shared = state.clone();
    app.on_cancel(move || {
        if let Some(app) = weak.upgrade() {
            let value = *shared.borrow();
            app.set_date_text(value.date.iso_string().into());
            app.set_time_text(
                value
                    .time
                    .format(
                        TimePrecision::Minute,
                        slint_kit::ClockFormat::TwentyFourHour,
                    )
                    .into(),
            );
            app.set_error("".into());
        }
    });

    app.run()
}

Cargo.toml and build.rs

Cargo.toml

[package]
name = "slint-kit-date-time-field-example"
version = "0.1.0"
edition = "2024"
rust-version = "1.92"
license = "GPL-3.0-or-later"
publish = false

[dependencies]
slint-kit = "=0.3.0"
slint = { version = "=1.18.1", default-features = false, features = ["std", "compat-1-18", "backend-winit", "renderer-skia", "accessibility"] }

[build-dependencies]
slint-kit-build = "=0.3.0"

[workspace]

build.rs

fn main() {
    slint_kit_build::compile("ui/app.slint").expect("compile component example");
}

Files: Cargo.toml · build.rs · ui/app.slint · src/main.rs

Parse the date as YYYY-MM-DD and time as 24-hour HH:MM, then build LocalDateTime only when both are valid.

Commit is atomic: an invalid part leaves the accepted pair unchanged. This value has no time zone.

Choose between built-in options and custom composition

Shared options

Visual composition

The file below produces the screenshot. For controller-driven components, it shows the displayed state without supplying the Rust wiring. Create a project.

Show the screenshot source
Two text drafts accepted as one local date and time.
Native screenshot of the same example, rendered with Skia.
// SPDX-License-Identifier: GPL-3.0-or-later
// Display projections are fixtures. Validate accepted domain values in Rust.
import { KitDateTimeField, KitTheme, KitThemes } from "@kit/kit.slint";

export component Example inherits Window {
    title: "KitDateTimeField example";
    preferred-width: 440px;
    preferred-height: 290px;
    max-width: 100000px;
    max-height: 100000px;
    background: root.theme.canvas;
    in-out property <KitTheme> theme: KitThemes.light;
    in-out property <string> status;
    VerticalLayout {
        padding: 24px; spacing: 16px; alignment: start;
        Text { text: "Date Time Field"; color: root.theme.text-primary; font-size: 20px * root.theme.text-scale; font-weight: 600; }
        KitDateTimeField { theme: root.theme; label: "Meeting"; date-text: "2026-10-17"; time-text: "09:30"; }
        if root.status != "": Text { text: root.status; color: root.theme.text-secondary; font-size: 12px * root.theme.text-scale; wrap: word-wrap; }
    }
}

Download this example

Public API

Inherits Rectangle.

Properties

Name Type Direction
required bool in
min string in
max string in
step string in
default-value string in
custom-validity string in-out
validity KitValidityState out
will-validate bool out
validation-message string out
theme KitTheme in
control-size ControlSize in
access FieldAccess in
accepted-value LocalDateTimeView in
clock-format ClockFormat in
precision TimePrecision in
label string in
date-placeholder string in
date-description string in
time-description string in
date-label string in
time-label string in
date-error string in
time-error string in
date-text string in-out
time-text string in-out
editor-focused bool out

Types and variants

Type Declaration
struct CivilDateView year: int, month: int, day: int
enum ClockFormat twenty-four-hour, twelve-hour
enum ControlSize compact, medium, comfortable
enum FieldAccess editable, read-only, disabled
struct KitValidityState valid: bool, value-missing: bool, type-mismatch: bool, pattern-mismatch: bool, too-long: bool, too-short: bool, range-underflow: bool, range-overflow: bool, step-mismatch: bool, bad-input: bool, custom-error: bool,
struct LocalDateTimeDraft date: string, time: string
struct LocalDateTimeView date: CivilDateView, time: LocalTimeView
struct LocalTimeView hour: int, minute: int, second: int
enum TimePrecision minute, second

Callbacks

Functions

See also