diff --git a/CHANGELOG.md b/CHANGELOG.md
index 74d3746bad94bb5988121ad3555656e218353a4d..7d4f2b091f576a7d7468c6aa83bd41a628dcec83 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 * `caosdb-v-property-linkified` css class to denote properties that have been
   linkified already.
+* `caosdb-f-property-datetime-value` css class for special handling of datetime properties.  Also
+  there is now very basic customization (via variable `BUILD_MODULE_EXT_COSMETICS_CUSTOMDATETIME`)
+  for how datetime values can be displayed, which comes along with the new css classes
+  `caosdb-v-property-datetime-customized` and `caosdb-v-property-datetime-customized-newvalue`.
+* `form_elements.make_form_modal` and
+  `form_elements.make_scripting_submission_button` functions to create a form
+  modal and an SSS submission button, respectively.
 
 ### Changed (for changes in existing functionality)
 
diff --git a/build.properties.d/00_default.properties b/build.properties.d/00_default.properties
index 795a360792b1683b7f4ba8f6dfd6e7f3047590fc..d21943b6fc51abf370b2939a7ac8a6bad72e9a04 100644
--- a/build.properties.d/00_default.properties
+++ b/build.properties.d/00_default.properties
@@ -52,6 +52,7 @@ BUILD_MODULE_EXT_BOOKMARKS=ENABLED
 BUILD_MODULE_EXT_ADD_QUERY_TO_BOOKMARKS=DISABLED
 BUILD_MODULE_EXT_ANNOTATION=ENABLED
 BUILD_MODULE_EXT_COSMETICS_LINKIFY=DISABLED
+BUILD_MODULE_EXT_COSMETICS_CUSTOMDATETIME=DISABLED
 BUILD_MODULE_EXT_QRCODE=ENABLED
 BUILD_MODULE_SHOW_ID_IN_LABEL=DISABLED
 BUILD_MODULE_LEGACY_QUERY_FORM=ENABLED
diff --git a/src/core/js/ext_cosmetics.js b/src/core/js/ext_cosmetics.js
index da05f294f2022a469e74ec05d64211fe1f8b26b7..c29f07e42294ff3d8c0b4b86da829865b8a650c5 100644
--- a/src/core/js/ext_cosmetics.js
+++ b/src/core/js/ext_cosmetics.js
@@ -4,6 +4,7 @@
  * Copyright (C) 2021-2023 IndiScale GmbH <info@indiscale.com>
  * Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
  * Copyright (C) 2023 Florian Spreckelsen <f.spreckelsen@indiscale.com>
+ * Copyright (C) 2023 Daniel Hornung <d.hornung@indiscale.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License as
@@ -31,11 +32,35 @@ var cosmetics = new function () {
 
     /**
      * Cut-off length of links. When linkify processes the links any href
-     * longer than this will be cut off at character 25 and "[...]" will be
+     * longer than this will be cut off at the end and "[...]" will be
      * appended for the link text.
      */
     var _link_cut_off_length = 40;
 
+    var _custom_datetime = function () {
+        $('.caosdb-f-property-datetime-value').each(function (index) {
+            if (!($(this).hasClass("caosdb-v-property-datetime-customized"))) {
+                var result = this.innerText.replace(/T/, " ").replace(/\+.*/, "");
+                result = `<span class="caosdb-v-property-datetime-customized-newvalue">${result}</span>`;
+
+                // add class to highlight that this has been customized already
+                $(this).addClass("caosdb-v-property-datetime-customized")
+                $(this).hide();
+                $(this).after(result);
+            }
+        });
+    }
+
+  /**
+   * Remove all the custom datetime elements again, for example when entering the edit mode.
+   */
+  var _custom_datetime_clear = function() {
+    $('.caosdb-v-property-datetime-customized-newvalue').each(function () {
+      $(this).remove();
+    }
+                                                             )
+  }
+
     var _linkify = function () {
         $('.caosdb-f-property-text-value').each(function (index) {
             if (!($(this).hasClass("caosdb-v-property-linkified")) && (/https?:\/\//.test(this.innerText))) {
@@ -57,6 +82,22 @@ var cosmetics = new function () {
         });
     }
 
+    /**
+     * Customize datetime formatting.
+     *
+     * A listener detects edit-mode changes and previews
+     */
+    var custom_datetime = function () {
+        _custom_datetime();
+
+        // edit-mode-listener to delete replacement
+        document.body.addEventListener(edit_mode.start_edit.type, _custom_datetime_clear, true);
+        // edit-mode-listener to recreate
+        document.body.addEventListener(edit_mode.end_edit.type, _custom_datetime, true);
+        // preview listener
+        document.body.addEventListener(preview.previewReadyEvent.type, _custom_datetime, true);
+    }
+
     /**
      * Convert any substring of a text-value beginning with 'http(s)://' into a
      * link.
@@ -73,6 +114,10 @@ var cosmetics = new function () {
     }
 
     this.init = function () {
+        this.custom_datetime = custom_datetime;
+        if ("${BUILD_MODULE_EXT_COSMETICS_CUSTOMDATETIME}" == "ENABLED") {
+            custom_datetime();
+        }
         this.linkify = linkify;
         if ("${BUILD_MODULE_EXT_COSMETICS_LINKIFY}" == "ENABLED") {
             linkify();
diff --git a/src/core/js/ext_trigger_crawler_form.js b/src/core/js/ext_trigger_crawler_form.js
index 0796ef77da36e730b05d70dbbd2e8728c6e65c79..a6e1e3a18a3582cc9b3e511880b72d15f730b346 100644
--- a/src/core/js/ext_trigger_crawler_form.js
+++ b/src/core/js/ext_trigger_crawler_form.js
@@ -41,7 +41,7 @@
  * variable `BUILD_MODULE_EXT_TRIGGER_CRAWLER_FORM_TOOLBOX`. The default is
  * `Tools`.
  */
-var ext_trigger_crawler_form = function () {
+var ext_trigger_crawler_form = function ($, form_elements) {
 
     var init = function (toolbox) {
         const _toolbox = toolbox || "${BUILD_MODULE_EXT_TRIGGER_CRAWLER_FORM_TOOLBOX}";
@@ -52,7 +52,7 @@ var ext_trigger_crawler_form = function () {
 
         const crawler_form = make_scripting_caller_form(
             script, button_name);
-        const modal = make_form_modal(crawler_form);
+        const modal = form_elements.make_form_modal(crawler_form, "Trigger the crawler", "Crawl the selected path");
 
 
         navbar.add_tool(button_name, _toolbox, {
@@ -63,32 +63,6 @@ var ext_trigger_crawler_form = function () {
         });
     }
 
-    /**
-     * Wrap the form into a Bootstrap modal.
-     */
-    var make_form_modal = function (form) {
-        const title = "Trigger the Crawler";
-        const modal = $(`
-          <div class="modal fade" tabindex="-1" role="dialog">
-            <div class="modal-dialog" role="document">
-              <div class="modal-content">
-                <div class="modal-header">
-                  <button type="button"
-                    class="btn-close"
-                    data-bs-dismiss="modal"
-                    aria-label="Close">
-                    <span aria-hidden="true">&times;</span>
-                  </button>
-                  <h4 class="modal-title">${title}</h4>
-                </div>
-                <div class="modal-body">
-                </div>
-              </div>
-            </div>`);
-        modal.find(".modal-body").append(form);
-        return modal[0];
-    }
-
     /**
      * Create the trigger crawler form.
      */
@@ -104,15 +78,7 @@ var ext_trigger_crawler_form = function () {
         });
         $(warning_checkbox).find("input").attr("value", "TRUE");
 
-        const scripting_caller = $(`
-        <form method="POST" action="/scripting">
-          <input type="hidden" name="call" value="${script}"/>
-          <input type="hidden" name="-p0" value=""/>
-          <div class="form-control">
-            <input type="submit"
-              class="form-control btn btn-primary" value="${button_name}"/>
-          </div>
-        </form>`);
+        const scripting_caller = form_elements.make_scripting_submission_button(script, button_name);
 
         scripting_caller.prepend(warning_checkbox).prepend(path_field);
 
@@ -123,7 +89,7 @@ var ext_trigger_crawler_form = function () {
         init: init,
     };
 
-}();
+}($, form_elements);
 
 $(document).ready(function () {
     if ("${BUILD_MODULE_EXT_TRIGGER_CRAWLER_FORM}" === "ENABLED") {
diff --git a/src/core/js/form_elements.js b/src/core/js/form_elements.js
index 6815acd791213c6b239a693c3c64667965c369ed..20ff4ead80d897bd8b90497c7c0f03351c0d92ff 100644
--- a/src/core/js/form_elements.js
+++ b/src/core/js/form_elements.js
@@ -1437,6 +1437,10 @@ var form_elements = new function () {
     /**
      * Return a select field.
      *
+     * IMPORTANT: The select picker has to be initialized by the client by
+     * calling ``form_elements.init_select_picker(ret, config.value)`` (see
+     * below and https://gitlab.com/caosdb/caosdb-webui/-/issues/208).
+     *
      * @param {SelectFieldConfig} config
      * @returns {HTMLElement} a select field.
      */
@@ -1454,7 +1458,7 @@ var form_elements = new function () {
         // case when this method is called and is controlled by the client. So
         // there is currently no other work-around than to call
         // init_select_picker after the form creation explicitely :(
-        //form_elements.init_select_picker(select[0], config.value);
+        // form_elements.init_select_picker(ret, config.value);
 
         return ret;
     }
@@ -1563,6 +1567,58 @@ var form_elements = new function () {
         }
     }
 
+    /**
+     * Return a modal HTML element containing the given form.
+     *
+     * @param {HTMLElement} form - the form to be shown in the modal
+     * @param {string} title - the title of the form modal
+     * @param {string} explanationText - An optional paragraph shown between
+     *                                    modal title and form.
+     */
+    this.make_form_modal = function (form, title, explanationText) {
+        const modal = $(`
+              <div class="modal fade" tabindex="-1" role="dialog">
+                <div class="modal-dialog" role="document">
+                  <div class="modal-content">
+                    <div class="modal-header">
+                      <h4 class="modal-title">${title}</h4>
+                      <button type="button"
+                        class="btn-close"
+                        data-bs-dismiss="modal"
+                        aria-label="Close">
+                      </button>
+                    </div>
+                    <div class="modal-body">
+                      <p>${explanationText}</p>
+                    </div>
+                  </div>
+                </div>`);
+
+        modal.find(".modal-body").append(form);
+        return modal[0];
+    }
+
+    /**
+     * Return a submission button that triggers a given server-side-script.
+     *
+     * @param {string} script - Name of the server-side script to be triggered
+     * @param {string} buttonName - Display name of the submission button
+     */
+    this.make_scripting_submission_button = function (script, buttonName) {
+        let button_name = buttonName || "Submit";
+        const scripting_caller = $(`
+            <form method="POST" action="/scripting">
+              <input type="hidden" name="call" value="${script}"/>
+              <input type="hidden" name="-p0" value=""/>
+              <div class="form-group">
+                <input type="submit"
+                  class="form-control btn btn-primary" value="${button_name}"/>
+              </div>
+            </form>`);
+
+        return scripting_caller
+    }
+
 
     /**
      * Return an input and a label, wrapped in a div with class
diff --git a/src/core/xsl/entity.xsl b/src/core/xsl/entity.xsl
index 264136f09828dce4e2ba7d324ff09fc14db5842c..3881e722608c6013b433a815f2db72a1896cd76e 100644
--- a/src/core/xsl/entity.xsl
+++ b/src/core/xsl/entity.xsl
@@ -297,6 +297,7 @@
     <xsl:param name="value"/>
     <xsl:param name="reference"/>
     <xsl:param name="boolean"/>
+    <xsl:param name="datetime"/>
     <xsl:choose>
       <xsl:when test="normalize-space($value)!=''">
         <xsl:choose>
@@ -322,6 +323,14 @@
               <xsl:value-of select="normalize-space($value)"/>
             </xsl:element>
           </xsl:when>
+          <xsl:when test="$datetime='true'">
+            <xsl:element name="span">
+              <xsl:attribute name="class">
+                <xsl:value-of select="'caosdb-f-property-single-raw-value caosdb-property-datetime-value caosdb-f-property-datetime-value caosdb-v-property-datetime-value'"/>
+              </xsl:attribute>
+              <xsl:value-of select="$value"/>
+            </xsl:element>
+          </xsl:when>
           <xsl:otherwise>
             <xsl:element name="span">
               <xsl:attribute name="class">
@@ -362,6 +371,9 @@
             <xsl:with-param name="boolean">
               <xsl:value-of select="'false'"/>
             </xsl:with-param>
+            <xsl:with-param name="datetime">
+              <xsl:value-of select="'false'"/>
+            </xsl:with-param>
           </xsl:call-template>
         </xsl:for-each>
         <xsl:for-each select="Record|RecordType|File|Property">
@@ -375,6 +387,9 @@
             <xsl:with-param name="boolean">
               <xsl:value-of select="'false'"/>
             </xsl:with-param>
+            <xsl:with-param name="datetime">
+              <xsl:value-of select="'false'"/>
+            </xsl:with-param>
           </xsl:call-template>
         </xsl:for-each>
       </xsl:element>
@@ -398,6 +413,9 @@
               <xsl:with-param name="boolean">
                 <xsl:value-of select="../@datatype='LIST&lt;BOOLEAN>'"/>
               </xsl:with-param>
+              <xsl:with-param name="datetime">
+                <xsl:value-of select="../@datatype='LIST&lt;DATETIME>'"/>
+              </xsl:with-param>
             </xsl:call-template>
           </xsl:element>
         </xsl:for-each>
@@ -449,6 +467,9 @@
               <xsl:with-param name="boolean">
                 <xsl:value-of select="@datatype='BOOLEAN'"/>
               </xsl:with-param>
+              <xsl:with-param name="datetime">
+                <xsl:value-of select="@datatype='DATETIME'"/>
+              </xsl:with-param>
             </xsl:call-template>
           </xsl:otherwise>
         </xsl:choose>
diff --git a/src/doc/extension/module.md b/src/doc/extension/module.md
index 207d3fff9d013cda657ef8c01f3cca5988622f4a..36731ee72d7a1e4be2f4624961486152579a0ff5 100644
--- a/src/doc/extension/module.md
+++ b/src/doc/extension/module.md
@@ -1,16 +1,15 @@
 # How to add a module to CaosDB WebUI
-The CaosDB WebUI is organized in modules which can easily be added and on a module basis enabled or disabled.
+The CaosDB WebUI is organized in modules which can easily be added and enabled or disabled per module.
 
-There are a few steps necessary to create a new module.
+Only a few steps are necessary to create a new module.
 
 ## Create the module file
 
-Create a new file for each new module. We have the convention, that extensions
-which are optional and should stay that way and also custom extensions for
-special purposes to name the file starting with `ext_`. E.g.
-`ext_flight_preview.js`.
+Create a new file for each new module.  We have the convention that extensions which are optional
+(and also custom extensions for special purposes) are saved in files starting with `ext_`,
+e.g. `ext_flight_preview.js`.
 
-This file should define one function that wraps every thing and which is
+This file should define one function that wraps everything, this function is then
 enabled at the bottom of the file:
 
 ```js
diff --git a/test/core/js/modules/ext_cosmetics.js.js b/test/core/js/modules/ext_cosmetics.js.js
index 969c8297b8b5cf85d0a668d7c30e8b0f45e34d4d..f51226ee01a1607c9ba1580c3760500fdec760b1 100644
--- a/test/core/js/modules/ext_cosmetics.js.js
+++ b/test/core/js/modules/ext_cosmetics.js.js
@@ -1,8 +1,9 @@
 /*
  * This file is a part of the CaosDB Project.
  *
- * Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
+ * Copyright (C) 2021-2023 IndiScale GmbH <info@indiscale.com>
  * Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
+ * Copyright (C) 2023 Daniel Hornung <d.hornung@indiscale.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License as
@@ -36,6 +37,30 @@ QUnit.module("ext_cosmetics.js", {
     }
 });
 
+QUnit.test("custom datetime", function (assert) {
+    assert.ok(cosmetics.custom_datetime, "custom_datetime available");
+    var test_cases = [
+        ["1234-56-78", "1234-56-78"],
+        ["9876-54-32T12:34:56", "9876-54-32 12:34:56"],
+        ["2023-03-78T99:99:99+0800", "2023-03-78 99:99:99"],
+    ];
+
+    for (let test_case of test_cases) {
+        const container = $('<div></div>');
+        $(document.body).append(container);
+        const text_value = $(`<span class="caosdb-f-property-datetime-value">${test_case[0]}</span>`);
+        container.append(text_value);
+        assert.equal($(container).find(" ").length, 0, "Test original datetime.");
+      cosmetics.custom_datetime();
+      const newValueElement =
+            container[0].querySelector("span.caosdb-v-property-datetime-customized-newvalue");
+      assert.ok(newValueElement, "Datetime customization: Test if result exists.");
+      assert.equal(newValueElement.innerHTML, test_case[1],
+                   "Datetime customization: compared result.");
+        container.remove();
+    }
+});
+
 QUnit.test("linkify - https", function (assert) {
     assert.ok(cosmetics.linkify, "linkify available");
     var test_cases = [