git: 8cfe06ee4415 - main - bsdconfig: add datetime module for live system clock

Devin Teske <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a812c2e.478b2.74b98cd7__26917.8175529063$1786850377$gmane$org@gitrepo.freebsd.org>
The branch main has been updated by dteske:

URL: https://cgit.FreeBSD.org/src/commit/?id=8cfe06ee4415795cc77934fb5c17bdf2c2fd3816

commit 8cfe06ee4415795cc77934fb5c17bdf2c2fd3816
Author:     Devin Teske <[email protected]>
AuthorDate: 2026-08-16 03:17:13 +0000
Commit:     Devin Teske <[email protected]>
CommitDate: 2026-08-16 03:17:13 +0000

    bsdconfig: add datetime module for live system clock
    
    Provide bsdconfig datetime (menu), date, and time to set the running
    system clock via dialog(1)/bsddialog(1) --calendar and --timebox with
    mustberoot.  Unlike bsdinstall's time helper, this operates on the live
    system rather than a CHROOT-staged install target, and calls
    adjkerntz(8) after a successful change so the CMOS stays in sync.
    
    Reviewed by:    bcr
    Differential Revision:  https://reviews.freebsd.org/D58487
---
 usr.sbin/bsdconfig/Makefile                       |   1 +
 usr.sbin/bsdconfig/bsdconfig.8                    |  10 +-
 usr.sbin/bsdconfig/datetime/INDEX                 |  57 ++++++++
 usr.sbin/bsdconfig/datetime/Makefile              |   9 ++
 usr.sbin/bsdconfig/datetime/Makefile.depend       |  10 ++
 usr.sbin/bsdconfig/datetime/Makefile.inc          |   1 +
 usr.sbin/bsdconfig/datetime/USAGE                 |  36 +++++
 usr.sbin/bsdconfig/datetime/date                  |  73 ++++++++++
 usr.sbin/bsdconfig/datetime/datetime              | 154 ++++++++++++++++++++++
 usr.sbin/bsdconfig/datetime/include/Makefile      |   4 +
 usr.sbin/bsdconfig/datetime/include/datetime.hlp  |  19 +++
 usr.sbin/bsdconfig/datetime/include/messages.subr |  41 ++++++
 usr.sbin/bsdconfig/datetime/share/Makefile        |   4 +
 usr.sbin/bsdconfig/datetime/share/datetime.subr   | 142 ++++++++++++++++++++
 usr.sbin/bsdconfig/datetime/time                  |  73 ++++++++++
 15 files changed, 632 insertions(+), 2 deletions(-)

diff --git a/usr.sbin/bsdconfig/Makefile b/usr.sbin/bsdconfig/Makefile
index a3b72d248a14..d308c90557ef 100644
--- a/usr.sbin/bsdconfig/Makefile
+++ b/usr.sbin/bsdconfig/Makefile
@@ -3,6 +3,7 @@
 PACKAGE=	bsdconfig
 
 SUBDIR=	console \
+	datetime \
 	diskmgmt \
 	docsinstall \
 	dot \
diff --git a/usr.sbin/bsdconfig/bsdconfig.8 b/usr.sbin/bsdconfig/bsdconfig.8
index aa81785a3acc..0ad74a2e3b2f 100644
--- a/usr.sbin/bsdconfig/bsdconfig.8
+++ b/usr.sbin/bsdconfig/bsdconfig.8
@@ -1,5 +1,5 @@
 .\" Copyright (c) 2012 Ron McDowell
-.\" Copyright (c) 2012-2013 Devin Teske
+.\" Copyright (c) 2012-2026 Devin Teske
 .\" All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
@@ -23,7 +23,7 @@
 .\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd June 9, 2026
+.Dd July 27, 2026
 .Dt BSDCONFIG 8
 .Os
 .Sh NAME
@@ -95,6 +95,10 @@ listing.
 .Bl -tag -width ".Cm syscons_screenmap"
 .It Cm console
 Utilities to customize the behavior of the system console.
+.It Cm date
+Set the system date, preserving the current time-of-day.
+.It Cm datetime
+Set the system date and/or time on the running machine.
 .It Cm defaultrouter
 Shortcut to the Default Router/Gateway menu under networking.
 .It Cm diskmgmt
@@ -207,6 +211,8 @@ Shortcut to the Screenmap menu under console for
 .It Cm vt_ttys
 Shortcut to the Ttys menu under console for
 .Xr vt 4 .
+.It Cm time
+Set the system time-of-day, preserving the current calendar date.
 .It Cm timezone
 Set the regional timezone of the local machine.
 .It Cm ttys
diff --git a/usr.sbin/bsdconfig/datetime/INDEX b/usr.sbin/bsdconfig/datetime/INDEX
new file mode 100644
index 000000000000..9f85e68bdc85
--- /dev/null
+++ b/usr.sbin/bsdconfig/datetime/INDEX
@@ -0,0 +1,57 @@
+# Copyright (c) 2026 Devin Teske
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+#
+
+#
+# Title that will be shown in the bsdconfig menu.
+#
+menu_title="Date / Time"
+
+#
+# A short descriptive line shown at the bottom of the bsdconfig menu. keep it
+# short because any line longer than the terminal width will be truncated.
+#
+menu_help="Set the system date and/or time"
+
+#
+# Two-part variable that defines an action to take when `keyword' is passed on
+# a bsdconfig command line. Variable takes the form "keyword|command" and
+# multiple occurrences of the variable (with different `keyword's, or different
+# `keyword's AND `command's) are allowed.  If `command' begins with a '/' then
+# the full path to the program is needed. If `command' begins with anything
+# else it is a path relative to the directory this INDEX file is in. `keyword'
+# can be i18n'ed but `command' is the name of a script.
+#
+menu_selection="datetime|datetime"
+menu_selection="date|date"
+menu_selection="time|time"
+
+#
+# ------------ Items below this line do NOT need i18n translation ------------
+#
+# Name of the program to be run when this menu choice is selected. If it begins
+# with a '/' then the full path to the program is needed. If it begins with
+# anything else it is a path relative to the directory this INDEX file is in.
+#
+menu_program="datetime"
diff --git a/usr.sbin/bsdconfig/datetime/Makefile b/usr.sbin/bsdconfig/datetime/Makefile
new file mode 100644
index 000000000000..600340a075c0
--- /dev/null
+++ b/usr.sbin/bsdconfig/datetime/Makefile
@@ -0,0 +1,9 @@
+SUBDIR= include share
+
+FILESDIR=	${LIBEXECDIR}/bsdconfig/085.datetime
+FILES=		INDEX USAGE
+
+SCRIPTSDIR=	${FILESDIR}
+SCRIPTS=	date datetime time
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/bsdconfig/datetime/Makefile.depend b/usr.sbin/bsdconfig/datetime/Makefile.depend
new file mode 100644
index 000000000000..11aba52f82cf
--- /dev/null
+++ b/usr.sbin/bsdconfig/datetime/Makefile.depend
@@ -0,0 +1,10 @@
+# Autogenerated - do NOT edit!
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/bsdconfig/datetime/Makefile.inc b/usr.sbin/bsdconfig/datetime/Makefile.inc
new file mode 100644
index 000000000000..01b5f23410c8
--- /dev/null
+++ b/usr.sbin/bsdconfig/datetime/Makefile.inc
@@ -0,0 +1 @@
+.include "../Makefile.inc"
diff --git a/usr.sbin/bsdconfig/datetime/USAGE b/usr.sbin/bsdconfig/datetime/USAGE
new file mode 100644
index 000000000000..cb2fdc733853
--- /dev/null
+++ b/usr.sbin/bsdconfig/datetime/USAGE
@@ -0,0 +1,36 @@
+# Copyright (c) 2026 Devin Teske
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+#
+
+Usage: bsdconfig @PROGRAM_NAME@ [OPTIONS]
+
+OPTIONS:
+	-d         Provide lots of debugging info on standard-out when running.
+	-D file    Send debugging info to file. If file begins with a plus-sign
+	           debug info is sent to both standard-out and file (minus the
+	           leading plus).
+	-h         Print this usage statement and exit.
+	-S         Secure X11 mode (implies `-X'). As root, always prompt-for
+	           and validate sudo(8) username/password before starting.
+	-X         Use Xdialog(1) in place of dialog(1).
diff --git a/usr.sbin/bsdconfig/datetime/date b/usr.sbin/bsdconfig/datetime/date
new file mode 100755
index 000000000000..dde5be929090
--- /dev/null
+++ b/usr.sbin/bsdconfig/datetime/date
@@ -0,0 +1,73 @@
+#!/bin/sh
+#-
+# Copyright (c) 2026 Devin Teske
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+#
+#
+############################################################ INCLUDES
+
+BSDCFG_SHARE="/usr/share/bsdconfig"
+. $BSDCFG_SHARE/common.subr || exit 1
+f_dprintf "%s: loading includes..." "$0"
+f_include $BSDCFG_SHARE/dialog.subr
+f_include $BSDCFG_SHARE/mustberoot.subr
+f_include $BSDCFG_SHARE/datetime/datetime.subr
+
+BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="085.datetime"
+
+f_index_menusel_keyword $BSDCFG_LIBE/$APP_DIR/INDEX "$pgm" ipgm &&
+	pgm="${ipgm:-$pgm}"
+
+############################################################ MAIN
+
+# Incorporate rc-file if it exists
+[ -f "$HOME/.bsdconfigrc" ] && f_include "$HOME/.bsdconfigrc"
+
+#
+# Process command-line arguments
+#
+while getopts h$GETOPTS_STDARGS flag; do
+	case "$flag" in
+	h|\?) f_usage $BSDCFG_LIBE/$APP_DIR/USAGE "PROGRAM_NAME" "$pgm" ;;
+	esac
+done
+shift $(( $OPTIND - 1 ))
+
+#
+# Initialize
+#
+f_dialog_title "$msg_set_date"
+f_dialog_backtitle "${ipgm:+bsdconfig }$pgm"
+f_mustberoot_init
+
+#
+# Set the system date (Cancel/ESC leaves the clock unchanged)
+#
+f_dialog_calendar_set_date
+
+exit $SUCCESS
+
+################################################################################
+# END
+################################################################################
diff --git a/usr.sbin/bsdconfig/datetime/datetime b/usr.sbin/bsdconfig/datetime/datetime
new file mode 100755
index 000000000000..5f42d79278f6
--- /dev/null
+++ b/usr.sbin/bsdconfig/datetime/datetime
@@ -0,0 +1,154 @@
+#!/bin/sh
+#-
+# Copyright (c) 2026 Devin Teske
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+#
+#
+############################################################ INCLUDES
+
+BSDCFG_SHARE="/usr/share/bsdconfig"
+. $BSDCFG_SHARE/common.subr || exit 1
+f_dprintf "%s: loading includes..." "$0"
+f_include $BSDCFG_SHARE/dialog.subr
+f_include $BSDCFG_SHARE/mustberoot.subr
+
+BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="085.datetime"
+f_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr
+
+DATETIME_HELPFILE=$BSDCFG_LIBE/$APP_DIR/include/datetime.hlp
+
+f_index_menusel_keyword $BSDCFG_LIBE/$APP_DIR/INDEX "$pgm" ipgm &&
+	pgm="${ipgm:-$pgm}"
+
+############################################################ FUNCTIONS
+
+# dialog_menu_main
+#
+# Display the dialog(1)-based application main menu.
+#
+dialog_menu_main()
+{
+	local prompt=
+	local menu_list="
+		'D' '$msg_date'
+		'T' '$msg_time'
+		'X' '$msg_exit'
+	" # END-QUOTE
+	local defaultitem= # Calculated below
+	local hline="$hline_arrows_tab_enter"
+
+	local height width rows
+	eval f_dialog_menu_size height width rows \
+	                        \"\$DIALOG_TITLE\"     \
+	                        \"\$DIALOG_BACKTITLE\" \
+	                        \"\$prompt\"           \
+	                        \"\$hline\"            \
+	                        $menu_list
+
+	# Obtain default-item from previously stored selection
+	f_dialog_default_fetch defaultitem
+
+	local menu_choice
+	menu_choice=$( eval $DIALOG \
+		--title \"\$DIALOG_TITLE\"         \
+		--backtitle \"\$DIALOG_BACKTITLE\" \
+		--hline \"\$hline\"                \
+		--ok-label \"\$msg_ok\"            \
+		--cancel-label \"\$msg_cancel\"    \
+		--help-button                      \
+		--help-label \"\$msg_help\"        \
+		${USE_XDIALOG:+--help \"\"}        \
+		--default-item \"\$defaultitem\"   \
+		--menu \"\$prompt\"                \
+		$height $width $rows               \
+		$menu_list                         \
+		2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
+	)
+	local retval=$?
+	f_dialog_data_sanitize menu_choice
+	f_dialog_menutag_store "$menu_choice"
+
+	# Only update default-item on success
+	[ $retval -eq $DIALOG_OK ] && f_dialog_default_store "$menu_choice"
+
+	return $retval
+}
+
+############################################################ MAIN
+
+# Incorporate rc-file if it exists
+[ -f "$HOME/.bsdconfigrc" ] && f_include "$HOME/.bsdconfigrc"
+
+#
+# Process command-line arguments
+#
+while getopts h$GETOPTS_STDARGS flag; do
+	case "$flag" in
+	h|\?) f_usage $BSDCFG_LIBE/$APP_DIR/USAGE "PROGRAM_NAME" "$pgm" ;;
+	esac
+done
+shift $(( $OPTIND - 1 ))
+
+#
+# Initialize
+#
+f_dialog_title "$msg_date_time"
+f_dialog_backtitle "${ipgm:+bsdconfig }$pgm"
+f_mustberoot_init
+
+#
+# Launch application main menu
+#
+while :; do
+	dialog_menu_main
+	retval=$?
+	f_dialog_menutag_fetch mtag
+	f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
+
+	if [ $retval -eq $DIALOG_HELP ]; then
+		f_show_help "$DATETIME_HELPFILE"
+		continue
+	elif [ $retval -ne $DIALOG_OK ]; then
+		f_die
+	fi
+
+	command=
+	case "$mtag" in
+	X) break ;;
+	D) command=date ;; # Set Date
+	T) command=time ;; # Set Time
+	esac
+
+	if [ "$command" ]; then
+		$BSDCFG_LIBE/$APP_DIR/$command ${USE_XDIALOG:+-X}
+	else
+		f_die 1 "$msg_unknown_date_time_menu_selection"
+	fi
+done
+
+exit $SUCCESS
+
+################################################################################
+# END
+################################################################################
diff --git a/usr.sbin/bsdconfig/datetime/include/Makefile b/usr.sbin/bsdconfig/datetime/include/Makefile
new file mode 100644
index 000000000000..da1d4daaa5c0
--- /dev/null
+++ b/usr.sbin/bsdconfig/datetime/include/Makefile
@@ -0,0 +1,4 @@
+FILESDIR=	${LIBEXECDIR}/bsdconfig/085.datetime/include
+FILES=		messages.subr datetime.hlp
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/bsdconfig/datetime/include/datetime.hlp b/usr.sbin/bsdconfig/datetime/include/datetime.hlp
new file mode 100644
index 000000000000..7b0b0ed7c023
--- /dev/null
+++ b/usr.sbin/bsdconfig/datetime/include/datetime.hlp
@@ -0,0 +1,19 @@
+These screens allow you to set the system date and time on the
+running system.
+
+Date
+====
+
+Choose Date to open a calendar pre-filled with the current local
+date. Confirming applies that calendar day while preserving the
+current time-of-day.
+
+Time
+====
+
+Choose Time to open a time box pre-filled with the current local
+time. Confirming applies that time-of-day while preserving the
+current calendar date.
+
+Timezone is configured separately (bsdconfig timezone). Setting
+the clock here does not change which zone /etc/localtime names.
diff --git a/usr.sbin/bsdconfig/datetime/include/messages.subr b/usr.sbin/bsdconfig/datetime/include/messages.subr
new file mode 100644
index 000000000000..55e40553c403
--- /dev/null
+++ b/usr.sbin/bsdconfig/datetime/include/messages.subr
@@ -0,0 +1,41 @@
+# Copyright (c) 2026 Devin Teske
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+#
+
+hline_arrows_tab_enter="Press arrows, TAB or ENTER"
+msg_cancel="Cancel"
+msg_date="Date"
+msg_date_time="Date / Time"
+msg_error="ERROR!"
+msg_exit="Exit"
+msg_help="Help"
+msg_ok="OK"
+msg_set_date="Set Date"
+msg_set_time="Set Time"
+msg_system_date_set="System date set to:\n\n%s"
+msg_system_time_set="System time set to:\n\n%s"
+msg_time="Time"
+msg_unable_to_set_date="Unable to set the system date."
+msg_unable_to_set_time="Unable to set the system time."
+msg_unknown_date_time_menu_selection="Unknown date/time menu selection"
diff --git a/usr.sbin/bsdconfig/datetime/share/Makefile b/usr.sbin/bsdconfig/datetime/share/Makefile
new file mode 100644
index 000000000000..dbf9035a2c73
--- /dev/null
+++ b/usr.sbin/bsdconfig/datetime/share/Makefile
@@ -0,0 +1,4 @@
+FILESDIR=	${SHAREDIR}/bsdconfig/datetime
+FILES=		datetime.subr
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/bsdconfig/datetime/share/datetime.subr b/usr.sbin/bsdconfig/datetime/share/datetime.subr
new file mode 100644
index 000000000000..8c016ade9b7c
--- /dev/null
+++ b/usr.sbin/bsdconfig/datetime/share/datetime.subr
@@ -0,0 +1,142 @@
+if [ ! "$_DATETIME_DATETIME_SUBR" ]; then _DATETIME_DATETIME_SUBR=1
+#
+# Copyright (c) 2026 Devin Teske
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+#
+#
+############################################################ INCLUDES
+
+BSDCFG_SHARE="/usr/share/bsdconfig"
+. $BSDCFG_SHARE/common.subr || exit 1
+f_dprintf "%s: loading includes..." datetime/datetime.subr
+f_include $BSDCFG_SHARE/dialog.subr
+
+BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="085.datetime"
+f_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr
+
+############################################################ FUNCTIONS
+
+# f_datetime_adjkerntz
+#
+# Best-effort CMOS sync after changing the system clock with date(1).
+#
+f_datetime_adjkerntz()
+{
+	f_quietly adjkerntz -a
+}
+
+# f_dialog_calendar_set_date
+#
+# Prompt with dialog(1) --calendar and set the system date, preserving the
+# current time-of-day. Returns dialog status (Cancel/ESC) without dying.
+#
+f_dialog_calendar_set_date()
+{
+	local prompt="$msg_set_date"
+	local hline="$hline_arrows_tab_enter"
+	local cheight cwidth input_date ret_date retval
+	local cur_tod setstr
+
+	f_dialog_calendar_size cheight cwidth \
+		"$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$prompt" "$hline"
+
+	input_date=$( date "+%d %m %Y" )
+	ret_date=$( eval $DIALOG \
+		--title \"\$DIALOG_TITLE\"         \
+		--backtitle \"\$DIALOG_BACKTITLE\" \
+		--hline \"\$hline\"                \
+		--ok-label \"\$msg_ok\"            \
+		--cancel-label \"\$msg_cancel\"    \
+		--calendar \"\$prompt\"            \
+		$cheight $cwidth                   \
+		$input_date                        \
+		2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
+	)
+	retval=$?
+	f_dialog_data_sanitize ret_date
+	f_dprintf "retval=%u ret_date=[%s]" $retval "$ret_date"
+	[ $retval -eq $DIALOG_OK ] || return $retval
+
+	cur_tod=$( date "+%H:%M:%S" )
+	setstr=$( date -j -f "%d/%m/%Y %T" -- \
+		"$ret_date $cur_tod" "+%Y%m%d%H%M.%S" ) ||
+		f_die 1 "$msg_unable_to_set_date"
+
+	f_eval_catch "$0" date 'date "%s"' "$setstr" ||
+		f_die 1 "$msg_unable_to_set_date"
+	f_datetime_adjkerntz
+	f_show_msg "$msg_system_date_set" "$( date )"
+	return $SUCCESS
+}
+
+# f_dialog_timebox_set_time
+#
+# Prompt with dialog(1) --timebox and set the system time, preserving the
+# current calendar date. Returns dialog status (Cancel/ESC) without dying.
+#
+f_dialog_timebox_set_time()
+{
+	local prompt="$msg_set_time"
+	local hline="$hline_arrows_tab_enter"
+	local input_time ret_time retval
+	local cur_day setstr
+
+	#
+	# bsddialog(1) --timebox wants total rows (min 7), not dialog(1)-style
+	# text height. Match bsdinstall time: autosize height, width 40.
+	#
+	input_time=$( date "+%H %M %S" )
+	ret_time=$( eval $DIALOG \
+		--title \"\$DIALOG_TITLE\"         \
+		--backtitle \"\$DIALOG_BACKTITLE\" \
+		--hline \"\$hline\"                \
+		--ok-label \"\$msg_ok\"            \
+		--cancel-label \"\$msg_cancel\"    \
+		--timebox \"\$prompt\"             \
+		0 40                               \
+		$input_time                        \
+		2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
+	)
+	retval=$?
+	f_dialog_data_sanitize ret_time
+	f_dprintf "retval=%u ret_time=[%s]" $retval "$ret_time"
+	[ $retval -eq $DIALOG_OK ] || return $retval
+
+	cur_day=$( date "+%d/%m/%Y" )
+	setstr=$( date -j -f "%d/%m/%Y %T" -- \
+		"$cur_day $ret_time" "+%Y%m%d%H%M.%S" ) ||
+		f_die 1 "$msg_unable_to_set_time"
+
+	f_eval_catch "$0" date 'date "%s"' "$setstr" ||
+		f_die 1 "$msg_unable_to_set_time"
+	f_datetime_adjkerntz
+	f_show_msg "$msg_system_time_set" "$( date )"
+	return $SUCCESS
+}
+
+############################################################ MAIN
+
+f_dprintf "%s: Successfully loaded." datetime/datetime.subr
+
+fi # ! $_DATETIME_DATETIME_SUBR
diff --git a/usr.sbin/bsdconfig/datetime/time b/usr.sbin/bsdconfig/datetime/time
new file mode 100755
index 000000000000..908d756b0d8a
--- /dev/null
+++ b/usr.sbin/bsdconfig/datetime/time
@@ -0,0 +1,73 @@
+#!/bin/sh
+#-
+# Copyright (c) 2026 Devin Teske
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+#
+#
+############################################################ INCLUDES
+
+BSDCFG_SHARE="/usr/share/bsdconfig"
+. $BSDCFG_SHARE/common.subr || exit 1
+f_dprintf "%s: loading includes..." "$0"
+f_include $BSDCFG_SHARE/dialog.subr
+f_include $BSDCFG_SHARE/mustberoot.subr
+f_include $BSDCFG_SHARE/datetime/datetime.subr
+
+BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="085.datetime"
+
+f_index_menusel_keyword $BSDCFG_LIBE/$APP_DIR/INDEX "$pgm" ipgm &&
+	pgm="${ipgm:-$pgm}"
+
+############################################################ MAIN
+
+# Incorporate rc-file if it exists
+[ -f "$HOME/.bsdconfigrc" ] && f_include "$HOME/.bsdconfigrc"
+
+#
+# Process command-line arguments
+#
+while getopts h$GETOPTS_STDARGS flag; do
+	case "$flag" in
+	h|\?) f_usage $BSDCFG_LIBE/$APP_DIR/USAGE "PROGRAM_NAME" "$pgm" ;;
+	esac
+done
+shift $(( $OPTIND - 1 ))
+
+#
+# Initialize
+#
+f_dialog_title "$msg_set_time"
+f_dialog_backtitle "${ipgm:+bsdconfig }$pgm"
+f_mustberoot_init
+
+#
+# Set the system time (Cancel/ESC leaves the clock unchanged)
+#
+f_dialog_timebox_set_time
+
+exit $SUCCESS
+
+################################################################################
+# END
+################################################################################
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.