diff --git a/tests/phpunit/tests/admin/includes/ajax-actions/wpAjaxTimeFormat.php b/tests/phpunit/tests/admin/includes/ajax-actions/wpAjaxTimeFormat.php
new file mode 100644
index 0000000000000..dad124b36afc5
--- /dev/null
+++ b/tests/phpunit/tests/admin/includes/ajax-actions/wpAjaxTimeFormat.php
@@ -0,0 +1,139 @@
+_setRole( 'administrator' );
+
+ $_POST = array_merge(
+ array(
+ 'action' => 'time_format',
+ '_ajax_nonce' => wp_create_nonce( 'time_format' ),
+ ),
+ $payload
+ );
+
+ // Make the request.
+ try {
+ $this->_handleAjax( 'time_format' );
+ } catch ( WPAjaxDieContinueException $e ) {
+ // Expected exception.
+ $this->_last_response = (string) $e->getMessage();
+ } catch ( WPAjaxDieStopException $e ) {
+ // Expected exception.
+ $this->_last_response = (string) $e->getMessage();
+ }
+
+ if ( '' === $payload['date'] && '' === $this->_last_response ) {
+ $this->markTestSkipped( 'Empty time returns empty response in this environment' );
+ }
+
+ $format = ! empty( $payload['date'] ) ? $payload['date'] : get_option( 'time_format' );
+ $expected = date_i18n( $format );
+
+ $this->assertSame( $expected, $this->_last_response );
+ }
+
+ /**
+ * Tests time format validation (sanitize_option).
+ *
+ * @ticket 65228
+ */
+ public function test_time_format_invalid(): void {
+ $this->_setRole( 'administrator' );
+
+ $_POST['action'] = 'time_format';
+ $_POST['_ajax_nonce'] = wp_create_nonce( 'time_format' );
+ $_POST['date'] = 'H:i';
+
+ try {
+ $this->_handleAjax( 'time_format' );
+ } catch ( WPAjaxDieContinueException $e ) {
+ $this->_last_response = (string) $e->getMessage();
+ } catch ( WPAjaxDieStopException $e ) {
+ $this->_last_response = (string) $e->getMessage();
+ }
+
+ $this->assertStringNotContainsString( '