Index: uspace/app/aboutos/aboutos.c
===================================================================
--- uspace/app/aboutos/aboutos.c	(revision 25fdb2d4b3c3247fe62c1154a416ce3a91019563)
+++ uspace/app/aboutos/aboutos.c	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
@@ -1,3 +1,4 @@
 /*
+ * Copyright (c) 2025 Wayne Michael Thornton (WMT) <wmthornton-dev@outlook.com>
  * Copyright (c) 2024 Jiri Svoboda
  * Copyright (c) 2012 Petr Koupy
@@ -167,4 +168,5 @@
 	ui_wnd_params_init(&params);
 	params.caption = "About HelenOS";
+	params.placement = ui_wnd_place_center;
 
 	/* FIXME: Auto layout */
Index: uspace/app/clock_widget/clock_widget.c
===================================================================
--- uspace/app/clock_widget/clock_widget.c	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
+++ uspace/app/clock_widget/clock_widget.c	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2025 Wayne Michael Thornton (WMT) <wmthornton-dev@outlook.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup clock_widget
+ * @{
+ */
+/** @file Clock widget application (in UI)
+ */
+
+#include <gfx/coord.h>
+#include <stdio.h>
+#include <str.h>
+#include <stdlib.h>
+#include <ui/fixed.h>
+#include <ui/label.h>
+#include <ui/pbutton.h>
+#include <ui/entry.h>
+#include <ui/resource.h>
+#include <ui/ui.h>
+#include <ui/window.h>
+#include <device/clock_dev.h>
+#include <loc.h>
+#include <time.h>
+#include "clock_widget.h"
+
+static void wnd_close(ui_window_t *, void *);
+
+static ui_window_cb_t window_cb = {
+	.close = wnd_close
+};
+
+/** Window close button was clicked.
+ *
+ * @param window Window
+ * @param arg Argument (clock_widget)
+ */
+static void wnd_close(ui_window_t *window, void *arg)
+{
+	clock_widget_t *clock_widget = (clock_widget_t *) arg;
+	ui_quit(clock_widget->ui);
+}
+
+/** Run Clock Widget on display server. */
+static errno_t clock_widget(const char *display_spec)
+{
+	ui_t *ui = NULL;
+	ui_wnd_params_t params;
+	ui_window_t *window = NULL;
+	clock_widget_t clock_widget;
+	errno_t rc;
+
+	rc = ui_create(display_spec, &ui);
+	if (rc != EOK) {
+		printf("Error creating UI on display %s.\n", display_spec);
+		return rc;
+	}
+
+	ui_wnd_params_init(&params);
+	params.caption = "Clock Widget";
+	params.placement = ui_wnd_place_center;
+
+	if (ui_is_textmode(ui)) {
+		params.rect.p0.x = 0;
+		params.rect.p0.y = 0;
+		params.rect.p1.x = 45;
+		params.rect.p1.y = 15;
+	} else {
+		params.rect.p0.x = 0;
+		params.rect.p0.y = 0;
+		params.rect.p1.x = 350;
+		params.rect.p1.y = 275;
+	}
+
+	memset((void *) &clock_widget, 0, sizeof(clock_widget));
+	clock_widget.ui = ui;
+
+	rc = ui_window_create(ui, &params, &window);
+	if (rc != EOK) {
+		printf("Error creating window.\n");
+		return rc;
+	}
+
+	ui_window_set_cb(window, &window_cb, (void *) &clock_widget);
+	clock_widget.window = window;
+
+	rc = ui_fixed_create(&clock_widget.fixed);
+	if (rc != EOK) {
+		printf("Error creating fixed layout.\n");
+		return rc;
+	}
+
+	rc = ui_window_paint(window);
+	if (rc != EOK) {
+		printf("Error painting window.\n");
+		return rc;
+	}
+
+	ui_run(ui);
+
+	ui_window_destroy(window);
+	ui_destroy(ui);
+
+	return EOK;
+}
+
+static void print_syntax(void)
+{
+	printf("Syntax: clock_widget [-d <display-spec>]\n");
+}
+
+int main(int argc, char *argv[])
+{
+	const char *display_spec = UI_ANY_DEFAULT;
+	errno_t rc;
+	int i;
+
+	i = 1;
+	while (i < argc && argv[i][0] == '-') {
+		if (str_cmp(argv[i], "-d") == 0) {
+			++i;
+			if (i >= argc) {
+				printf("Argument missing.\n");
+				print_syntax();
+				return 1;
+			}
+
+			display_spec = argv[i++];
+		} else {
+			printf("Invalid option '%s'.\n", argv[i]);
+			print_syntax();
+			return 1;
+		}
+	}
+
+	if (i < argc) {
+		print_syntax();
+		return 1;
+	}
+
+	rc = clock_widget(display_spec);
+	if (rc != EOK)
+		return 1;
+
+	return 0;
+}
+
+/** @}
+ */
Index: uspace/app/clock_widget/clock_widget.h
===================================================================
--- uspace/app/clock_widget/clock_widget.h	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
+++ uspace/app/clock_widget/clock_widget.h	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2025 Wayne Michael Thornton (WMT) <wmthornton-dev@outlook.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup clock_widget
+ * @{
+ */
+/**
+ * @file Clock widget application (in UI)
+ */
+
+#ifndef CLOCK_WIDGET_H
+#define CLOCK_WIDGET_H
+
+#include <ui/fixed.h>
+#include <ui/label.h>
+#include <ui/pbutton.h>
+#include <ui/ui.h>
+#include <ui/window.h>
+#include <ui/entry.h>
+
+/** Clock widget UI application */
+typedef struct {
+	ui_t *ui;
+	ui_window_t *window;
+	ui_fixed_t *fixed;
+	ui_label_t *date_label;
+	ui_label_t *time_label;
+	ui_entry_t *date_entry;
+	ui_entry_t *time_entry;
+	ui_pbutton_t *ok_button;
+	ui_pbutton_t *set_button;
+	struct tm current_time;
+} clock_widget_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/app/clock_widget/doc/doxygroups.h
===================================================================
--- uspace/app/clock_widget/doc/doxygroups.h	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
+++ uspace/app/clock_widget/doc/doxygroups.h	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
@@ -0,0 +1,4 @@
+/** @addtogroup clock_widget clock_widget
+ * @brief Clock widget application (in UI)
+ * @ingroup apps
+ */
Index: uspace/app/clock_widget/meson.build
===================================================================
--- uspace/app/clock_widget/meson.build	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
+++ uspace/app/clock_widget/meson.build	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2025 Wayne Michael Thornton (WMT) <wmthornton-dev@outlook.com>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+deps = [ 'ui' ]
+src = files('clock_widget.c')
Index: uspace/app/date/date.c
===================================================================
--- uspace/app/date/date.c	(revision 25fdb2d4b3c3247fe62c1154a416ce3a91019563)
+++ uspace/app/date/date.c	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
@@ -1,3 +1,4 @@
 /*
+ * Copyright (c) 2025 Wayne Michael Thornton (WMT) <wmthornton-dev@outlook.com>
  * Copyright (c) 2012 Maurizio Lombardi
  * All rights reserved.
@@ -195,5 +196,5 @@
 
 /** Read the day, month and year from a string
- *  with the following format: DD/MM/YYYY
+ *  with the following format: DD/MM/YYYY or MM/DD/YYYY
  */
 static errno_t
@@ -202,4 +203,6 @@
 	errno_t rc;
 	uint32_t tmp;
+	uint32_t first_num;
+	uint32_t second_num;
 
 	if (str_size(wdate) != 10) /* str_size("DD/MM/YYYY") == 10 */
@@ -211,20 +214,36 @@
 	}
 
-	rc = str_uint32_t(&wdate[0], NULL, 10, false, &tmp);
-	if (rc != EOK)
-		return rc;
-
-	t->tm_mday = tmp;
-
-	rc = str_uint32_t(&wdate[3], NULL, 10, false, &tmp);
-	if (rc != EOK)
-		return rc;
-
-	t->tm_mon = tmp - 1;
+	/* Parse first number */
+	rc = str_uint32_t(&wdate[0], NULL, 10, false, &first_num);
+	if (rc != EOK)
+		return rc;
+
+	/* Parse second number */
+	rc = str_uint32_t(&wdate[3], NULL, 10, false, &second_num);
+	if (rc != EOK)
+		return rc;
+
+	/* Determine format based on first number */
+	if (first_num > 12) {
+		/* First number is day (DD/MM/YYYY format) */
+		t->tm_mday = first_num;
+		t->tm_mon = second_num - 1;
+	} else if (second_num > 12) {
+		/* Second number is day (MM/DD/YYYY format) */
+		t->tm_mon = first_num - 1;
+		t->tm_mday = second_num;
+	} else {
+		/* Ambiguous case - assume DD/MM/YYYY format */
+		t->tm_mday = first_num;
+		t->tm_mon = second_num - 1;
+	}
 
 	rc = str_uint32_t(&wdate[6], NULL, 10, false, &tmp);
+	if (rc != EOK)
+		return rc;
+
 	t->tm_year = tmp - 1900;
 
-	return rc;
+	return EOK;
 }
 
@@ -331,6 +350,6 @@
 usage(void)
 {
-	printf("Usage: date [-d DD/MM/YYYY] [-t HH:MM[:SS]]\n");
-	printf("       -d   Change the current date\n");
+	printf("Usage: date [-d DD/MM/YYYY|MM/DD/YYYY] [-t HH:MM[:SS]]\n");
+	printf("       -d   Change the current date (supports both DD/MM/YYYY and MM/DD/YYYY formats)\n");
 	printf("       -t   Change the current time\n");
 	printf("       -h   Display this information\n");
Index: uspace/app/date_cfg/date_cfg.c
===================================================================
--- uspace/app/date_cfg/date_cfg.c	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
+++ uspace/app/date_cfg/date_cfg.c	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
@@ -0,0 +1,556 @@
+/*
+ * Copyright (c) 2025 Wayne Michael Thornton (WMT) <wmthornton-dev@outlook.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup date_cfg
+ * @{
+ */
+/** @file Date configuration application (in UI)
+ */
+
+#include <gfx/coord.h>
+#include <stdio.h>
+#include <str.h>
+#include <stdlib.h>
+#include <ui/fixed.h>
+#include <ui/label.h>
+#include <ui/pbutton.h>
+#include <ui/entry.h>
+#include <ui/resource.h>
+#include <ui/ui.h>
+#include <ui/window.h>
+#include <device/clock_dev.h>
+#include <loc.h>
+#include <time.h>
+#include "date_cfg.h"
+
+static void wnd_close(ui_window_t *, void *);
+static void ok_clicked(ui_pbutton_t *, void *);
+static void set_clicked(ui_pbutton_t *, void *);
+static errno_t get_current_time(struct tm *);
+static errno_t set_system_time(struct tm *);
+static void update_time_display(date_cfg_t *);
+static errno_t parse_date_time(date_cfg_t *);
+
+static ui_window_cb_t window_cb = {
+	.close = wnd_close
+};
+
+static ui_pbutton_cb_t button_cb = {
+	.clicked = ok_clicked
+};
+
+static ui_pbutton_cb_t set_button_cb = {
+	.clicked = set_clicked
+};
+
+/** Window close button was clicked.
+ *
+ * @param window Window
+ * @param arg Argument (date_cfg)
+ */
+static void wnd_close(ui_window_t *window, void *arg)
+{
+	date_cfg_t *date_cfg = (date_cfg_t *) arg;
+	ui_quit(date_cfg->ui);
+}
+
+/** OK button was clicked.
+ *
+ * @param button Button that was clicked
+ * @param arg Argument (date_cfg)
+ */
+static void ok_clicked(ui_pbutton_t *button, void *arg)
+{
+	date_cfg_t *date_cfg = (date_cfg_t *) arg;
+	ui_quit(date_cfg->ui);
+}
+
+/** Set button was clicked.
+ *
+ * @param button Button that was clicked
+ * @param arg Argument (date_cfg)
+ */
+static void set_clicked(ui_pbutton_t *button, void *arg)
+{
+	date_cfg_t *date_cfg = (date_cfg_t *) arg;
+	errno_t rc;
+
+	rc = parse_date_time(date_cfg);
+	if (rc != EOK) {
+		printf("Error parsing date/time. Please use format DD/MM/YYYY and HH:MM:SS\n");
+		return;
+	}
+
+	rc = set_system_time(&date_cfg->current_time);
+	if (rc != EOK) {
+		printf("Error setting system time.\n");
+		return;
+	}
+
+	update_time_display(date_cfg);
+}
+
+/** Get current system time.
+ *
+ * @param t Pointer to tm structure to store time
+ * @return EOK on success, error code otherwise
+ */
+static errno_t get_current_time(struct tm *t)
+{
+	category_id_t cat_id;
+	service_id_t *svc_ids = NULL;
+	size_t svc_cnt;
+	service_id_t svc_id;
+	char *svc_name = NULL;
+	errno_t rc;
+
+	rc = loc_category_get_id("clock", &cat_id, IPC_FLAG_BLOCKING);
+	if (rc != EOK)
+		return rc;
+
+	rc = loc_category_get_svcs(cat_id, &svc_ids, &svc_cnt);
+	if (rc != EOK)
+		return rc;
+
+	if (svc_cnt == 0) {
+		free(svc_ids);
+		return ENOENT;
+	}
+
+	rc = loc_service_get_name(svc_ids[0], &svc_name);
+	if (rc != EOK) {
+		free(svc_ids);
+		return rc;
+	}
+
+	rc = loc_service_get_id(svc_name, &svc_id, 0);
+	if (rc != EOK) {
+		free(svc_name);
+		free(svc_ids);
+		return rc;
+	}
+
+	async_sess_t *sess = loc_service_connect(svc_id, INTERFACE_DDF, 0);
+	if (!sess) {
+		free(svc_name);
+		free(svc_ids);
+		return EIO;
+	}
+
+	rc = clock_dev_time_get(sess, t);
+
+	free(svc_name);
+	free(svc_ids);
+	return rc;
+}
+
+/** Set system time.
+ *
+ * @param t Pointer to tm structure containing new time
+ * @return EOK on success, error code otherwise
+ */
+static errno_t set_system_time(struct tm *t)
+{
+	category_id_t cat_id;
+	service_id_t *svc_ids = NULL;
+	size_t svc_cnt;
+	service_id_t svc_id;
+	char *svc_name = NULL;
+	errno_t rc;
+
+	rc = loc_category_get_id("clock", &cat_id, IPC_FLAG_BLOCKING);
+	if (rc != EOK)
+		return rc;
+
+	rc = loc_category_get_svcs(cat_id, &svc_ids, &svc_cnt);
+	if (rc != EOK)
+		return rc;
+
+	if (svc_cnt == 0) {
+		free(svc_ids);
+		return ENOENT;
+	}
+
+	rc = loc_service_get_name(svc_ids[0], &svc_name);
+	if (rc != EOK) {
+		free(svc_ids);
+		return rc;
+	}
+
+	rc = loc_service_get_id(svc_name, &svc_id, 0);
+	if (rc != EOK) {
+		free(svc_name);
+		free(svc_ids);
+		return rc;
+	}
+
+	async_sess_t *sess = loc_service_connect(svc_id, INTERFACE_DDF, 0);
+	if (!sess) {
+		free(svc_name);
+		free(svc_ids);
+		return EIO;
+	}
+
+	rc = clock_dev_time_set(sess, t);
+
+	free(svc_name);
+	free(svc_ids);
+	return rc;
+}
+
+/** Update time display entry fields.
+ *
+ * @param date_cfg Date configuration structure
+ */
+static void update_time_display(date_cfg_t *date_cfg)
+{
+	char date_str[32];
+	char time_str[32];
+
+	snprintf(date_str, sizeof(date_str), "%02d/%02d/%d",
+	    date_cfg->current_time.tm_mday,
+	    date_cfg->current_time.tm_mon + 1,
+	    1900 + date_cfg->current_time.tm_year);
+
+	snprintf(time_str, sizeof(time_str), "%02d:%02d:%02d",
+	    date_cfg->current_time.tm_hour,
+	    date_cfg->current_time.tm_min,
+	    date_cfg->current_time.tm_sec);
+
+	ui_entry_set_text(date_cfg->date_entry, date_str);
+	ui_entry_set_text(date_cfg->time_entry, time_str);
+}
+
+/** Parse date and time from entry fields.
+ *
+ * @param date_cfg Date configuration structure
+ * @return EOK on success, error code otherwise
+ */
+static errno_t parse_date_time(date_cfg_t *date_cfg)
+{
+	const char *date_str = ui_entry_get_text(date_cfg->date_entry);
+	const char *time_str = ui_entry_get_text(date_cfg->time_entry);
+	int first_num, second_num, year;
+	int hour, min, sec;
+
+	if (sscanf(date_str, "%d/%d/%d", &first_num, &second_num, &year) != 3)
+		return EINVAL;
+
+	if (sscanf(time_str, "%d:%d:%d", &hour, &min, &sec) != 3)
+		return EINVAL;
+
+	/* Determine format based on first number */
+	if (first_num > 12) {
+		/* First number is day (DD/MM/YYYY format) */
+		date_cfg->current_time.tm_mday = first_num;
+		date_cfg->current_time.tm_mon = second_num - 1;
+	} else if (second_num > 12) {
+		/* Second number is day (MM/DD/YYYY format) */
+		date_cfg->current_time.tm_mon = first_num - 1;
+		date_cfg->current_time.tm_mday = second_num;
+	} else {
+		/* Ambiguous case - assume DD/MM/YYYY format */
+		date_cfg->current_time.tm_mday = first_num;
+		date_cfg->current_time.tm_mon = second_num - 1;
+	}
+
+	if (date_cfg->current_time.tm_mday < 1 || date_cfg->current_time.tm_mday > 31 || 
+	    date_cfg->current_time.tm_mon < 0 || date_cfg->current_time.tm_mon > 11 || 
+	    year < 1900)
+		return EINVAL;
+
+	if (hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 || sec > 59)
+		return EINVAL;
+
+	date_cfg->current_time.tm_year = year - 1900;
+	date_cfg->current_time.tm_hour = hour;
+	date_cfg->current_time.tm_min = min;
+	date_cfg->current_time.tm_sec = sec;
+
+	return EOK;
+}
+
+/** Run Date Configuration on display server. */
+static errno_t date_cfg(const char *display_spec)
+{
+	ui_t *ui = NULL;
+	ui_wnd_params_t params;
+	ui_window_t *window = NULL;
+	date_cfg_t date_cfg;
+	gfx_rect_t rect;
+	ui_resource_t *ui_res;
+	errno_t rc;
+
+	rc = ui_create(display_spec, &ui);
+	if (rc != EOK) {
+		printf("Error creating UI on display %s.\n", display_spec);
+		return rc;
+	}
+
+	ui_wnd_params_init(&params);
+	params.caption = "Date Configuration";
+	params.placement = ui_wnd_place_center;
+
+	if (ui_is_textmode(ui)) {
+		params.rect.p0.x = 0;
+		params.rect.p0.y = 0;
+		params.rect.p1.x = 45;
+		params.rect.p1.y = 15;
+	} else {
+		params.rect.p0.x = 0;
+		params.rect.p0.y = 0;
+		params.rect.p1.x = 350;
+		params.rect.p1.y = 275;
+	}
+
+	memset((void *) &date_cfg, 0, sizeof(date_cfg));
+	date_cfg.ui = ui;
+
+	rc = ui_window_create(ui, &params, &window);
+	if (rc != EOK) {
+		printf("Error creating window.\n");
+		return rc;
+	}
+
+	ui_window_set_cb(window, &window_cb, (void *) &date_cfg);
+	date_cfg.window = window;
+
+	ui_res = ui_window_get_res(window);
+
+	rc = ui_fixed_create(&date_cfg.fixed);
+	if (rc != EOK) {
+		printf("Error creating fixed layout.\n");
+		return rc;
+	}
+
+	/* Create date label */
+	rc = ui_label_create(ui_res, "Date:", &date_cfg.date_label);
+	if (rc != EOK) {
+		printf("Error creating date label.\n");
+		return rc;
+	}
+
+	if (ui_is_textmode(ui)) {
+		rect.p0.x = 2;
+		rect.p0.y = 5;
+		rect.p1.x = 7;
+		rect.p1.y = 6;
+	} else {
+		rect.p0.x = 20;
+		rect.p0.y = 80;
+		rect.p1.x = 100;
+		rect.p1.y = 100;
+	}
+
+	ui_label_set_rect(date_cfg.date_label, &rect);
+	ui_fixed_add(date_cfg.fixed, ui_label_ctl(date_cfg.date_label));
+
+	/* Create date entry */
+	rc = ui_entry_create(window, "", &date_cfg.date_entry);
+	if (rc != EOK) {
+		printf("Error creating date entry.\n");
+		return rc;
+	}
+
+	if (ui_is_textmode(ui)) {
+		rect.p0.x = 8;
+		rect.p0.y = 5;
+		rect.p1.x = 28;
+		rect.p1.y = 6;
+	} else {
+		rect.p0.x = 120;
+		rect.p0.y = 80;
+		rect.p1.x = 250;
+		rect.p1.y = 100;
+	}
+
+	ui_entry_set_rect(date_cfg.date_entry, &rect);
+	ui_fixed_add(date_cfg.fixed, ui_entry_ctl(date_cfg.date_entry));
+
+	/* Create time label */
+	rc = ui_label_create(ui_res, "Time:", &date_cfg.time_label);
+	if (rc != EOK) {
+		printf("Error creating time label.\n");
+		return rc;
+	}
+
+	if (ui_is_textmode(ui)) {
+		rect.p0.x = 2;
+		rect.p0.y = 7;
+		rect.p1.x = 7;
+		rect.p1.y = 8;
+	} else {
+		rect.p0.x = 20;
+		rect.p0.y = 120;
+		rect.p1.x = 100;
+		rect.p1.y = 140;
+	}
+
+	ui_label_set_rect(date_cfg.time_label, &rect);
+	ui_fixed_add(date_cfg.fixed, ui_label_ctl(date_cfg.time_label));
+
+	/* Create time entry */
+	rc = ui_entry_create(window, "", &date_cfg.time_entry);
+	if (rc != EOK) {
+		printf("Error creating time entry.\n");
+		return rc;
+	}
+
+	if (ui_is_textmode(ui)) {
+		rect.p0.x = 8;
+		rect.p0.y = 7;
+		rect.p1.x = 28;
+		rect.p1.y = 8;
+	} else {
+		rect.p0.x = 120;
+		rect.p0.y = 120;
+		rect.p1.x = 250;
+		rect.p1.y = 140;
+	}
+
+	ui_entry_set_rect(date_cfg.time_entry, &rect);
+	ui_fixed_add(date_cfg.fixed, ui_entry_ctl(date_cfg.time_entry));
+
+	/* Create Set button */
+	rc = ui_pbutton_create(ui_res, "Set", &date_cfg.set_button);
+	if (rc != EOK) {
+		printf("Error creating Set button.\n");
+		return rc;
+	}
+
+	ui_pbutton_set_cb(date_cfg.set_button, &set_button_cb, (void *) &date_cfg);
+
+	if (ui_is_textmode(ui)) {
+		rect.p0.x = 2;
+		rect.p0.y = 13;
+		rect.p1.x = 13;
+		rect.p1.y = 14;
+	} else {
+		rect.p0.x = 20;
+		rect.p0.y = 235;
+		rect.p1.x = 120;
+		rect.p1.y = rect.p0.y + 28;
+	}
+
+	ui_pbutton_set_rect(date_cfg.set_button, &rect);
+	ui_fixed_add(date_cfg.fixed, ui_pbutton_ctl(date_cfg.set_button));
+
+	/* Create OK button */
+	rc = ui_pbutton_create(ui_res, "OK", &date_cfg.ok_button);
+	if (rc != EOK) {
+		printf("Error creating OK button.\n");
+		return rc;
+	}
+
+	ui_pbutton_set_cb(date_cfg.ok_button, &button_cb, (void *) &date_cfg);
+
+	if (ui_is_textmode(ui)) {
+		rect.p0.x = 17;
+		rect.p0.y = 13;
+		rect.p1.x = 28;
+		rect.p1.y = 14;
+	} else {
+		rect.p0.x = 125;
+		rect.p0.y = 235;
+		rect.p1.x = 225;
+		rect.p1.y = rect.p0.y + 28;
+	}
+
+	ui_pbutton_set_rect(date_cfg.ok_button, &rect);
+	ui_pbutton_set_default(date_cfg.ok_button, true);
+
+	ui_fixed_add(date_cfg.fixed, ui_pbutton_ctl(date_cfg.ok_button));
+
+	ui_window_add(window, ui_fixed_ctl(date_cfg.fixed));
+
+	/* Get current time and update display */
+	rc = get_current_time(&date_cfg.current_time);
+	if (rc != EOK) {
+		printf("Error getting current time.\n");
+		return rc;
+	}
+
+	update_time_display(&date_cfg);
+
+	rc = ui_window_paint(window);
+	if (rc != EOK) {
+		printf("Error painting window.\n");
+		return rc;
+	}
+
+	ui_run(ui);
+
+	ui_window_destroy(window);
+	ui_destroy(ui);
+
+	return EOK;
+}
+
+static void print_syntax(void)
+{
+	printf("Syntax: date_cfg [-d <display-spec>]\n");
+}
+
+int main(int argc, char *argv[])
+{
+	const char *display_spec = UI_ANY_DEFAULT;
+	errno_t rc;
+	int i;
+
+	i = 1;
+	while (i < argc && argv[i][0] == '-') {
+		if (str_cmp(argv[i], "-d") == 0) {
+			++i;
+			if (i >= argc) {
+				printf("Argument missing.\n");
+				print_syntax();
+				return 1;
+			}
+
+			display_spec = argv[i++];
+		} else {
+			printf("Invalid option '%s'.\n", argv[i]);
+			print_syntax();
+			return 1;
+		}
+	}
+
+	if (i < argc) {
+		print_syntax();
+		return 1;
+	}
+
+	rc = date_cfg(display_spec);
+	if (rc != EOK)
+		return 1;
+
+	return 0;
+}
+
+/** @}
+ */
Index: uspace/app/date_cfg/date_cfg.h
===================================================================
--- uspace/app/date_cfg/date_cfg.h	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
+++ uspace/app/date_cfg/date_cfg.h	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2025 Wayne Michael Thornton (WMT) <wmthornton-dev@outlook.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup date_cfg
+ * @{
+ */
+/**
+ * @file Date configuration application (in UI)
+ */
+
+#ifndef DATE_CFG_H
+#define DATE_CFG_H
+
+#include <ui/fixed.h>
+#include <ui/label.h>
+#include <ui/pbutton.h>
+#include <ui/ui.h>
+#include <ui/window.h>
+#include <ui/entry.h>
+
+/** Date configuration UI application */
+typedef struct {
+	ui_t *ui;
+	ui_window_t *window;
+	ui_fixed_t *fixed;
+	ui_label_t *date_label;
+	ui_label_t *time_label;
+	ui_entry_t *date_entry;
+	ui_entry_t *time_entry;
+	ui_pbutton_t *ok_button;
+	ui_pbutton_t *set_button;
+	struct tm current_time;
+} date_cfg_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/app/date_cfg/doc/doxygroups.h
===================================================================
--- uspace/app/date_cfg/doc/doxygroups.h	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
+++ uspace/app/date_cfg/doc/doxygroups.h	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
@@ -0,0 +1,4 @@
+/** @addtogroup date_cfg date_cfg
+ * @brief Date configuration application (in UI)
+ * @ingroup apps
+ */
Index: uspace/app/date_cfg/meson.build
===================================================================
--- uspace/app/date_cfg/meson.build	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
+++ uspace/app/date_cfg/meson.build	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2025 Wayne Michael Thornton (WMT) <wmthornton-dev@outlook.com>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+deps = [ 'ui' ]
+src = files('date_cfg.c')
Index: uspace/app/meson.build
===================================================================
--- uspace/app/meson.build	(revision 25fdb2d4b3c3247fe62c1154a416ce3a91019563)
+++ uspace/app/meson.build	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
@@ -34,7 +34,9 @@
 	'blkdump',
 	'calculator',
+	'clock_widget',
 	'corecfg',
 	'cpptest',
 	'date',
+	'date_cfg',
 	'devctl',
 	'df',
Index: uspace/app/taskbar/clock.c
===================================================================
--- uspace/app/taskbar/clock.c	(revision 25fdb2d4b3c3247fe62c1154a416ce3a91019563)
+++ uspace/app/taskbar/clock.c	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
@@ -1,3 +1,4 @@
 /*
+ * Copyright (c) 2025 Wayne Michael Thornton (WMT) <wmthornton-dev@outlook.com>
  * Copyright (c) 2022 Jiri Svoboda
  * All rights reserved.
@@ -219,4 +220,12 @@
 }
 
+/** Launch date configuration application */
+static errno_t taskbar_clock_launch_date_cfg(void)
+{
+	task_id_t id;
+	const char *args[] = { "/app/date_cfg", NULL };
+	return task_spawnv(&id, NULL, args[0], args);
+}
+
 /** Handle taskbar clock position event.
  *
@@ -233,4 +242,8 @@
 	if (!gfx_pix_inside_rect(&pos, &clock->rect))
 		return ui_unclaimed;
+
+	if (event->type == POS_PRESS) {
+		taskbar_clock_launch_date_cfg();
+	}
 
 	return ui_claimed;
Index: uspace/lib/ui/include/types/ui/clock.h
===================================================================
--- uspace/lib/ui/include/types/ui/clock.h	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
+++ uspace/lib/ui/include/types/ui/clock.h	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2024
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libui
+ * @{
+ */
+/**
+ * @file Clock widget types
+ */
+
+#ifndef _UI_TYPES_CLOCK_H
+#define _UI_TYPES_CLOCK_H
+
+#include <gfx/coord.h>
+#include <types/ui/control.h>
+#include <types/ui/resource.h>
+
+struct ui_clock {
+	/** Base control */
+	struct ui_control *control;
+	/** UI resource */
+	ui_resource_t *res;
+	/** Clock rectangle */
+	gfx_rect_t rect;
+	/** Current hour */
+	int hour;
+	/** Current minute */
+	int minute;
+	/** Current second */
+	int second;
+};
+
+typedef struct ui_clock ui_clock_t;
+
+#endif
+
+/** @}
+ */ 
Index: uspace/lib/ui/include/ui/clock.h
===================================================================
--- uspace/lib/ui/include/ui/clock.h	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
+++ uspace/lib/ui/include/ui/clock.h	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2024
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libui
+ * @{
+ */
+/**
+ * @file Clock widget
+ */
+
+#ifndef _UI_CLOCK_H
+#define _UI_CLOCK_H
+
+#include <errno.h>
+#include <gfx/coord.h>
+#include <types/ui/clock.h>
+#include <types/ui/control.h>
+#include <types/ui/resource.h>
+
+extern errno_t ui_clock_create(ui_resource_t *, ui_clock_t **);
+extern void ui_clock_destroy(ui_clock_t *);
+extern ui_control_t *ui_clock_ctl(ui_clock_t *);
+extern void ui_clock_set_rect(ui_clock_t *, gfx_rect_t *);
+extern errno_t ui_clock_paint(ui_clock_t *);
+extern void ui_clock_update_time(ui_clock_t *);
+
+#endif
+
+/** @}
+ */ 
Index: uspace/lib/ui/src/clock.c
===================================================================
--- uspace/lib/ui/src/clock.c	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
+++ uspace/lib/ui/src/clock.c	(revision 6b03a3c268f08b3ed1f12f5dbfd540728ef6679e)
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2024
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libui
+ * @{
+ */
+
+#include <errno.h>
+#include <gfx/color.h>
+#include <gfx/context.h>
+#include <gfx/coord.h>
+#include <math.h>
+#include <stdlib.h>
+#include <time.h>
+#include <ui/clock.h>
+#include <ui/paint.h>
+#include <ui/resource.h>
+
+#define CLOCK_HAND_WIDTH 2
+#define CLOCK_HOUR_HAND_LENGTH 0.6
+#define CLOCK_MINUTE_HAND_LENGTH 0.8
+#define CLOCK_SECOND_HAND_LENGTH 0.9
+
+static void ui_clock_ctl_destroy(void *);
+static errno_t ui_clock_ctl_paint(void *);
+
+/** Clock control ops */
+ui_control_ops_t ui_clock_ops = {
+	.destroy = ui_clock_ctl_destroy,
+	.paint = ui_clock_ctl_paint
+};
+
+/** Create clock widget.
+ *
+ * @param resource UI resource
+ * @param rclock Place to store pointer to new clock
+ * @return EOK on success, ENOMEM if out of memory
+ */
+errno_t ui_clock_create(ui_resource_t *resource, ui_clock_t **rclock)
+{
+	ui_clock_t *clock;
+	errno_t rc;
+
+	clock = calloc(1, sizeof(ui_clock_t));
+	if (clock == NULL)
+		return ENOMEM;
+
+	rc = ui_control_new(&ui_clock_ops, (void *) clock, &clock->control);
+	if (rc != EOK) {
+		free(clock);
+		return rc;
+	}
+
+	clock->res = resource;
+	*rclock = clock;
+	return EOK;
+}
+
+/** Destroy clock widget.
+ *
+ * @param clock Clock widget or @c NULL
+ */
+void ui_clock_destroy(ui_clock_t *clock)
+{
+	if (clock == NULL)
+		return;
+
+	ui_control_delete(clock->control);
+	free(clock);
+}
+
+/** Get base control from clock.
+ *
+ * @param clock Clock
+ * @return Control
+ */
+ui_control_t *ui_clock_ctl(ui_clock_t *clock)
+{
+	return clock->control;
+}
+
+/** Set clock rectangle.
+ *
+ * @param clock Clock
+ * @param rect New clock rectangle
+ */
+void ui_clock_set_rect(ui_clock_t *clock, gfx_rect_t *rect)
+{
+	clock->rect = *rect;
+}
+
+/** Draw clock hand.
+ *
+ * @param gc Graphic context
+ * @param center Center point
+ * @param angle Angle in radians
+ * @param length Length as fraction of radius
+ * @param width Width of hand
+ * @param color Color to use
+ * @return EOK on success or an error code
+ */
+static errno_t ui_clock_draw_hand(gfx_context_t *gc, gfx_coord2_t *center,
+    double angle, double length, gfx_coord_t width, gfx_color_t *color)
+{
+	gfx_coord_t radius;
+	gfx_coord2_t end;
+	gfx_rect_t rect;
+	errno_t rc;
+
+	/* Calculate radius as minimum of width/height */
+	radius = min(clock->rect.p1.x - clock->rect.p0.x,
+	    clock->rect.p1.y - clock->rect.p0.y) / 2;
+
+	/* Calculate end point */
+	end.x = center->x + (gfx_coord_t)(radius * length * sin(angle));
+	end.y = center->y - (gfx_coord_t)(radius * length * cos(angle));
+
+	/* Draw hand as a rectangle */
+	rect.p0.x = center->x - width/2;
+	rect.p0.y = center->y - width/2;
+	rect.p1.x = end.x + width/2;
+	rect.p1.y = end.y + width/2;
+
+	rc = gfx_set_color(gc, color);
+	if (rc != EOK)
+		return rc;
+
+	return gfx_fill_rect(gc, &rect);
+}
+
+/** Paint clock.
+ *
+ * @param clock Clock
+ * @return EOK on success or an error code
+ */
+errno_t ui_clock_paint(ui_clock_t *clock)
+{
+	gfx_coord2_t center;
+	gfx_coord_t radius;
+	double hour_angle, min_angle, sec_angle;
+	errno_t rc;
+
+	/* Calculate center and radius */
+	center.x = (clock->rect.p0.x + clock->rect.p1.x) / 2;
+	center.y = (clock->rect.p0.y + clock->rect.p1.y) / 2;
+	radius = min(clock->rect.p1.x - clock->rect.p0.x,
+	    clock->rect.p1.y - clock->rect.p0.y) / 2;
+
+	/* Paint clock face */
+	rc = gfx_set_color(clock->res->gc, clock->res->wnd_face_color);
+	if (rc != EOK)
+		return rc;
+
+	rc = ui_paint_filled_circle(clock->res->gc, &center, radius,
+	    ui_fcircle_entire);
+	if (rc != EOK)
+		return rc;
+
+	/* Paint clock frame */
+	rc = ui_paint_outset_frame(clock->res, &clock->rect, NULL);
+	if (rc != EOK)
+		return rc;
+
+	/* Calculate hand angles */
+	hour_angle = (clock->hour % 12 + clock->minute / 60.0) * M_PI / 6;
+	min_angle = clock->minute * M_PI / 30;
+	sec_angle = clock->second * M_PI / 30;
+
+	/* Draw hour hand */
+	rc = ui_clock_draw_hand(clock->res->gc, &center, hour_angle,
+	    CLOCK_HOUR_HAND_LENGTH, CLOCK_HAND_WIDTH * 2,
+	    clock->res->btn_text_color);
+	if (rc != EOK)
+		return rc;
+
+	/* Draw minute hand */
+	rc = ui_clock_draw_hand(clock->res->gc, &center, min_angle,
+	    CLOCK_MINUTE_HAND_LENGTH, CLOCK_HAND_WIDTH,
+	    clock->res->btn_text_color);
+	if (rc != EOK)
+		return rc;
+
+	/* Draw second hand */
+	rc = ui_clock_draw_hand(clock->res->gc, &center, sec_angle,
+	    CLOCK_SECOND_HAND_LENGTH, CLOCK_HAND_WIDTH,
+	    clock->res->wnd_highlight_color);
+	if (rc != EOK)
+		return rc;
+
+	return gfx_update(clock->res->gc);
+}
+
+/** Update clock time.
+ *
+ * @param clock Clock
+ */
+void ui_clock_update_time(ui_clock_t *clock)
+{
+	time_t now;
+	struct tm *tm;
+
+	time(&now);
+	tm = localtime(&now);
+
+	clock->hour = tm->tm_hour;
+	clock->minute = tm->tm_min;
+	clock->second = tm->tm_sec;
+}
+
+/** Destroy clock control.
+ *
+ * @param arg Argument (ui_clock_t *)
+ */
+static void ui_clock_ctl_destroy(void *arg)
+{
+	ui_clock_t *clock = (ui_clock_t *) arg;
+
+	ui_clock_destroy(clock);
+}
+
+/** Paint clock control.
+ *
+ * @param arg Argument (ui_clock_t *)
+ * @return EOK on success or an error code
+ */
+static errno_t ui_clock_ctl_paint(void *arg)
+{
+	ui_clock_t *clock = (ui_clock_t *) arg;
+
+	return ui_clock_paint(clock);
+}
+
+/** @}
+ */ 
