Index: /trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-templates-controller.php
===================================================================
--- /trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-templates-controller.php	(revision 62940)
+++ /trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-templates-controller.php	(revision 62941)
@@ -669,4 +669,6 @@
 	 * @since 6.3.0 Added `modified` property to the response.
 	 * @since 7.1.0 Added `date` property to the response.
+	 * @since 7.1.0 The `modified` property is `null` for templates that have no
+	 *              modification date.
 	 *
 	 * @param WP_Block_Template $item    Template instance.
@@ -777,9 +779,21 @@
 
 		if ( rest_is_field_included( 'modified', $fields ) ) {
-			$data['modified'] = mysql_to_rfc3339( $template->modified );
+			/*
+			 * File-backed templates have no modification date, and `mysql_to_rfc3339()`
+			 * returns `false` for an empty or malformed value, which the schema does
+			 * not allow. Return `null` in that case.
+			 */
+			$modified         = mysql_to_rfc3339( $template->modified );
+			$data['modified'] = false !== $modified ? $modified : null;
 		}
 
 		if ( rest_is_field_included( 'date', $fields ) ) {
-			$data['date'] = mysql_to_rfc3339( $template->date );
+			/*
+			 * File-backed templates have no date, and `mysql_to_rfc3339()` returns
+			 * `false` for an empty or malformed value, which the schema does not
+			 * allow. Return `null` in that case.
+			 */
+			$date         = mysql_to_rfc3339( $template->date );
+			$data['date'] = false !== $date ? $date : null;
 		}
 
@@ -1155,5 +1169,5 @@
 				'modified'        => array(
 					'description' => __( "The date the template was last modified, in the site's timezone." ),
-					'type'        => 'string',
+					'type'        => array( 'string', 'null' ),
 					'format'      => 'date-time',
 					'context'     => array( 'view', 'edit' ),
@@ -1178,5 +1192,5 @@
 					),
 				),
-				'date'        => array(
+				'date'            => array(
 					'description' => __( "The date the template was published, in the site's timezone." ),
 					'type'        => array( 'string', 'null' ),
Index: /trunk/tests/phpunit/tests/rest-api/wpRestTemplatesController.php
===================================================================
--- /trunk/tests/phpunit/tests/rest-api/wpRestTemplatesController.php	(revision 62940)
+++ /trunk/tests/phpunit/tests/rest-api/wpRestTemplatesController.php	(revision 62941)
@@ -637,4 +637,24 @@
 		$this->assertNotWPError( $response, "Fetching an unregistered template shouldn't cause an error." );
 		$this->assertSame( 404, $response->get_status(), 'Fetching an unregistered template should return 404.' );
+	}
+
+	/**
+	 * A file-backed template has no publication or modification date, which should
+	 * be exposed as `null` rather than the `false` returned by `mysql_to_rfc3339()`.
+	 *
+	 * @ticket 65728
+	 * @covers WP_REST_Templates_Controller::prepare_item_for_response
+	 */
+	public function test_get_item_dates_are_null_for_file_backed_template() {
+		wp_set_current_user( self::$admin_id );
+		switch_theme( 'block-theme' );
+
+		$request  = new WP_REST_Request( 'GET', '/wp/v2/templates/block-theme//page-home' );
+		$response = rest_get_server()->dispatch( $request );
+		$data     = $response->get_data();
+
+		$this->assertSame( 200, $response->get_status(), 'Fetching a file-backed template should return 200.' );
+		$this->assertNull( $data['date'], 'The date should be null for a file-backed template.' );
+		$this->assertNull( $data['modified'], 'The modified date should be null for a file-backed template.' );
 	}
 
