diff --git a/birb/birbdatetime.h b/birb/birbdatetime.h
new file mode 100644
--- /dev/null
+++ b/birb/birbdatetime.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2023-2024 Birb Developers
+ *
+ * Birb is the legal property of its developers, whose names are too
+ * numerous to list here. Please refer to the AUTHORS file distributed
+ * with this source distribution
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#if !defined(BIRB_GLOBAL_HEADER_INSIDE) && !defined(BIRB_COMPILATION)
+# error "only <birb.h> may be included directly"
+#endif
+
+#ifndef BIRB_DATE_TIME_H
+#define BIRB_DATE_TIME_H
+
+#include <glib.h>
+
+#include "birbversion.h"
+
+G_BEGIN_DECLS
+
+/**
+ * birb_date_time_set:
+ * @datetime_ptr: (inout) (not optional) (nullable): A pointer to a
+ *                [type@GLib.DateTime] reference.
+ * @new_datetime: (nullable) (transfer none): The new date time to set.
+ *
+ * Updates @datetime_ptr to point to @new_datetime.
+ *
+ * If @datetime_ptr had a previous reference, it will be un-referenced.
+ *
+ * If @new_datetime is not %NULL, a new reference will be added when it is
+ * assigned to @datetime_ptr.
+ *
+ * @datetime_ptr can not be %NULL but may point to a %NULL value.
+ *
+ * Returns: %TRUE if the value of @datetime_ptr changed, otherwise %FALSE.
+ *
+ * Since: 0.1
+ */
+BIRB_AVAILABLE_IN_0_1
+gboolean birb_date_time_set(GDateTime **datetime_ptr, GDateTime *new_datetime);
+
+/**
+ * birb_date_time_clear:
+ * @datetime_ptr: A pointer to a [type@GLib.DateTime] reference.
+ *
+ * Clears a reference to a [type@GLib.DateTime].
+ *
+ * If the reference is %NULL, this function does nothing. Otherwise, the
+ * reference count of the [type@GLib.DateTime] is decreased and the pointer is
+ * set to %NULL.
+ *
+ * Since: 0.1
+ */
+BIRB_AVAILABLE_IN_0_1
+void birb_date_time_clear(GDateTime **datetime_ptr);
+
+G_END_DECLS
+
+#endif /* BIRB_DATE_TIME_H */
# HG changeset patch
# Node ID a367537710d0
# Parent  8f96bb505781
diff --git a/birb/birbdatetime.c b/birb/birbdatetime.c
new file mode 100644
--- /dev/null
+++ b/birb/birbdatetime.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2023-2024 Birb Developers
+ *
+ * Birb is the legal property of its developers, whose names are too
+ * numerous to list here. Please refer to the AUTHORS file distributed
+ * with this source distribution
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "birbdatetime.h"
+
+/******************************************************************************
+ * Public API
+ *****************************************************************************/
+gboolean
+birb_date_time_set(GDateTime **datetime_ptr, GDateTime *new_datetime) {
+	GDateTime *old = NULL;
+
+	g_return_val_if_fail(datetime_ptr != NULL, FALSE);
+
+	old = *datetime_ptr;
+
+	if(old == new_datetime) {
+		return FALSE;
+	}
+
+	if(old != NULL) {
+		g_date_time_unref(old);
+	}
+
+	if(new_datetime != NULL) {
+		*datetime_ptr = g_date_time_ref(new_datetime);
+	} else {
+		*datetime_ptr = NULL;
+	}
+
+	return TRUE;
+}
+
+void
+birb_date_time_clear(GDateTime **datetime_ptr) {
+	if(datetime_ptr == NULL || *datetime_ptr == NULL) {
+		return;
+	}
+
+	g_date_time_unref(*datetime_ptr);
+	*datetime_ptr = NULL;
+}
diff --git a/birb/meson.build b/birb/meson.build
--- a/birb/meson.build
+++ b/birb/meson.build
@@ -2,12 +2,14 @@
 
 BIRB_SOURCES = [
   'birbactionmenu.c',
+  'birbdatetime.c',
   'birbqueuedoutputstream.c',
   'birbversion.c',
 ]
 
 BIRB_HEADERS = [
   'birbactionmenu.h',
+  'birbdatetime.h',
   'birbqueuedoutputstream.h',
   'birbversion.h',
 ]
diff --git a/birb/tests/meson.build b/birb/tests/meson.build
--- a/birb/tests/meson.build
+++ b/birb/tests/meson.build
@@ -1,5 +1,6 @@
 PROGRAMS = [
   'action_menu',
+  'date_time',
   'queued_output_stream',
 ]
 
diff --git a/birb/tests/test_date_time.c b/birb/tests/test_date_time.c
new file mode 100644
--- /dev/null
+++ b/birb/tests/test_date_time.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2023-2024 Birb Developers
+ *
+ * Birb is the legal property of its developers, whose names are too
+ * numerous to list here. Please refer to the AUTHORS file distributed
+ * with this source distribution
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <birb.h>
+
+/******************************************************************************
+ * set tests
+ *****************************************************************************/
+static void
+test_birb_date_time_set_null_null(void) {
+	GDateTime *dt = NULL;
+	g_assert_false(birb_date_time_set(&dt, NULL));
+}
+
+static void
+test_birb_date_time_set_null_nonnull(void) {
+	GDateTime *dt = NULL;
+	GDateTime *dt1 = NULL;
+	gboolean ret = FALSE;
+
+	dt1 = g_date_time_new_now_utc();
+	ret = birb_date_time_set(&dt, dt1);
+	g_assert_true(ret);
+
+	g_assert_true(dt == dt1);
+
+	g_clear_pointer(&dt, g_date_time_unref);
+	g_clear_pointer(&dt1, g_date_time_unref);
+}
+
+static void
+test_birb_date_time_set_nonnull_null(void) {
+	GDateTime *dt = NULL;
+	gboolean ret = FALSE;
+
+	dt = g_date_time_new_now_utc();
+	ret = birb_date_time_set(&dt, NULL);
+	g_assert_true(ret);
+
+	g_assert_null(dt);
+}
+
+static void
+test_birb_date_time_set_nonnull_nonnull(void) {
+	GDateTime *tmp = NULL;
+	GDateTime *dt = NULL;
+	GDateTime *dt1 = NULL;
+	gboolean ret = FALSE;
+
+	/* We push our existing time back 2 hours to avoid issues with day light
+	 * savings time and other weird clock skew issues.
+	 */
+	tmp = g_date_time_new_now_utc();
+	dt = g_date_time_add_hours(tmp, -2);
+	g_clear_pointer(&tmp, g_date_time_unref);
+
+	dt1 = g_date_time_new_now_utc();
+
+	ret = birb_date_time_set(&dt, dt1);
+	g_assert_true(ret);
+
+	g_assert_true(dt == dt1);
+
+	g_clear_pointer(&dt, g_date_time_unref);
+	g_clear_pointer(&dt1, g_date_time_unref);
+}
+
+/******************************************************************************
+ * clear tests
+ *****************************************************************************/
+static void
+test_birb_date_time_clear_null(void) {
+	GDateTime *dt = NULL;
+
+	birb_date_time_clear(NULL);
+	birb_date_time_clear(&dt);
+
+	g_assert_null(dt);
+}
+
+static void
+test_birb_date_time_clear_nonnull(void) {
+	GDateTime *dt = g_date_time_new_now_utc();
+
+	birb_date_time_clear(&dt);
+
+	g_assert_null(dt);
+}
+
+/******************************************************************************
+ * Main
+ *****************************************************************************/
+gint
+main(gint argc, gchar *argv[]) {
+	g_test_init(&argc, &argv, NULL);
+
+	g_test_add_func("/date-time/set/null-null",
+	                test_birb_date_time_set_null_null);
+	g_test_add_func("/date-time/set/null-nonnull",
+	                test_birb_date_time_set_null_nonnull);
+	g_test_add_func("/date-time/set/nonnull-null",
+	                test_birb_date_time_set_nonnull_null);
+	g_test_add_func("/date-time/set/nonnull-nonnull",
+	                test_birb_date_time_set_nonnull_nonnull);
+
+	g_test_add_func("/date-time/clear/null", test_birb_date_time_clear_null);
+	g_test_add_func("/date-time/clear/nonnull",
+	                test_birb_date_time_clear_nonnull);
+
+	return g_test_run();
+}
