Repository: kestra-io/kestra
Issue: Add a date format setting
Labels: enhancement

### Feature description

Add a Setting to let the user choose the datetime format (Month:Day:Year / Year:Month:Day / Day:Month:Year / xx/xx/xxxx etc...) - on dashboards, flow executions, etc..

**We must add a settings with predefined format** : 
* YYYY-MM-DD ( follows the ISO 8601 standard, widely used)
* YYYY-MM-DDThh:mm:ssZ ( follows the ISO 8601 standard, widely used)
* MM/DD/YYYY (commonly used in the United States)
* DD/MM/YYYY (commonly used in UE)
* YYYY/MM/DD
* MM/DD/YY


![image](https://user-images.githubusercontent.com/46634684/231784464-3daa135a-e2bc-4f6d-a8c4-a338b1f8f457.png)




Issue comments:

Pull request review comments:

Patch that resolved the issue:
diff --git a/ui/package-lock.json b/ui/package-lock.json
index 36ee4dc985..5fb94e9e01 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -31,6 +31,7 @@
         "md5": "^2.3.0",
         "moment": "^2.29.4",
         "moment-range": "4.0.2",
+        "moment-timezone": "^0.5.43",
         "node-modules-polyfill": "^0.1.4",
         "nprogress": "^0.2.0",
         "prismjs": "^1.29.0",
@@ -92,246 +93,6 @@
         "vue": "^3.2.0"
       }
     },
-    "node_modules/@esbuild/android-arm": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz",
-      "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==",
-      "cpu": [
-        "arm"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-arm64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz",
-      "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-x64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz",
-      "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-arm64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz",
-      "integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-x64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz",
-      "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz",
-      "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-x64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz",
-      "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz",
-      "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==",
-      "cpu": [
-        "arm"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz",
-      "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ia32": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz",
-      "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-loong64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz",
-      "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==",
-      "cpu": [
-        "loong64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-mips64el": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz",
-      "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==",
-      "cpu": [
-        "mips64el"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ppc64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz",
-      "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==",
-      "cpu": [
-        "ppc64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-riscv64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz",
-      "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==",
-      "cpu": [
-        "riscv64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-s390x": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz",
-      "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==",
-      "cpu": [
-        "s390x"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
     "node_modules/@esbuild/linux-x64": {
       "version": "0.17.19",
       "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz",
@@ -339,7 +100,6 @@
       "cpu": [
         "x64"
       ],
-      "dev": true,
       "optional": true,
       "os": [
         "linux"
@@ -348,102 +108,6 @@
         "node": ">=12"
       }
     },
-    "node_modules/@esbuild/netbsd-x64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz",
-      "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "netbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/openbsd-x64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz",
-      "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "openbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/sunos-x64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz",
-      "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "sunos"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-arm64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz",
-      "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-ia32": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz",
-      "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==",
-      "cpu": [
-        "ia32"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-x64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz",
-      "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
     "node_modules/@eslint-community/eslint-utils": {
       "version": "4.4.0",
       "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
@@ -690,6 +354,12 @@
       "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
       "dev": true
     },
+    "node_modules/@types/linkify-it": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz",
+      "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==",
+      "peer": true
+    },
     "node_modules/@types/lodash": {
       "version": "4.14.191",
       "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz",
@@ -703,6 +373,22 @@
         "@types/lodash": "*"
       }
     },
+    "node_modules/@types/markdown-it": {
+      "version": "12.2.3",
+      "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz",
+      "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==",
+      "peer": true,
+      "dependencies": {
+        "@types/linkify-it": "*",
+        "@types/mdurl": "*"
+      }
+    },
+    "node_modules/@types/mdurl": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz",
+      "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==",
+      "peer": true
+    },
     "node_modules/@types/node": {
       "version": "18.11.18",
       "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz",
@@ -1971,7 +1657,6 @@
       "version": "0.17.19",
       "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz",
       "integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==",
-      "dev": true,
       "hasInstallScript": true,
       "bin": {
         "esbuild": "bin/esbuild"
@@ -2404,20 +2089,6 @@
       "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
       "dev": true
     },
-    "node_modules/fsevents": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
-      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
-      "dev": true,
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
-      }
-    },
     "node_modules/get-func-name": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
@@ -3130,6 +2801,17 @@
         "moment": ">= 2"
       }
     },
+    "node_modules/moment-timezone": {
+      "version": "0.5.43",
+      "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.43.tgz",
+      "integrity": "sha512-72j3aNyuIsDxdF1i7CEgV2FfxM1r6aaqJyLB2vwb33mXYyoyLly+F1zbWqhA3/bVIoJ4szlUoMbUnVdid32NUQ==",
+      "dependencies": {
+        "moment": "^2.29.4"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/monaco-editor": {
       "version": "0.39.0",
       "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.39.0.tgz",
diff --git a/ui/package.json b/ui/package.json
index 40d6bf0ad6..aa49a4b826 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -33,6 +33,7 @@
     "md5": "^2.3.0",
     "moment": "^2.29.4",
     "moment-range": "4.0.2",
+    "moment-timezone": "^0.5.43",
     "node-modules-polyfill": "^0.1.4",
     "nprogress": "^0.2.0",
     "prismjs": "^1.29.0",
diff --git a/ui/src/components/layout/DateAgo.vue b/ui/src/components/layout/DateAgo.vue
index 6727186720..cd913373cd 100644
--- a/ui/src/components/layout/DateAgo.vue
+++ b/ui/src/components/layout/DateAgo.vue
@@ -15,8 +15,7 @@
                 default: false
             },
             format: {
-                type: String,
-                default: "LLLL"
+                type: String
             },
             className: {
                 type: String,
@@ -28,7 +27,7 @@
                 return this.$moment(this.date).fromNow();
             },
             full() {
-                return this.$moment(this.date).format(this.format);
+                return this.$filters.date(this.date, this.format);
             }
         }
     };
diff --git a/ui/src/components/settings/Settings.vue b/ui/src/components/settings/Settings.vue
index 132ba2415e..f7f450a2e3 100644
--- a/ui/src/components/settings/Settings.vue
+++ b/ui/src/components/settings/Settings.vue
@@ -23,6 +23,28 @@
                 </el-select>
             </el-form-item>
 
+            <el-form-item :label="$t('date format')">
+                <el-select :model-value="dateFormat" @update:model-value="onDateFormat">
+                    <el-option
+                        v-for="item in dateFormats"
+                        :key="timezone + item.value"
+                        :label="$filters.date(now, item.value)"
+                        :value="item.value"
+                    />
+                </el-select>
+            </el-form-item>
+
+            <el-form-item :label="$t('timezone')">
+                <el-select :model-value="timezone" @update:model-value="onTimezone" filterable>
+                    <el-option
+                        v-for="item in zonesWithOffset"
+                        :key="item.zone"
+                        :label="`${item.zone} (UTC${item.offset === 0 ? '' : item.formattedOffset})`"
+                        :value="item.zone"
+                    />
+                </el-select>
+            </el-form-item>
+
             <el-form-item :label="$t('Editor theme')">
                 <el-select :model-value="editorTheme" @update:model-value="onEditorTheme">
                     <el-option
@@ -104,6 +126,8 @@
     import action from "../../models/action";
     import {logDisplayTypes} from "../../utils/constants";
 
+    export const DATE_FORMAT_STORAGE_KEY = "dateFormat";
+    export const TIMEZONE_STORAGE_KEY = "timezone";
     export default {
         mixins: [RouteContext],
         components: {
@@ -117,11 +141,22 @@
                 lang: undefined,
                 theme: undefined,
                 editorTheme: undefined,
+                dateFormat: undefined,
+                timezone: undefined,
+                zonesWithOffset: this.$moment.tz.names().map((zone) => {
+                  const timezoneMoment = this.$moment.tz(zone);
+                  return {
+                        zone,
+                        offset: timezoneMoment.utcOffset(),
+                        formattedOffset: timezoneMoment.format("Z")
+                    };
+                }).sort((a, b) => a.offset - b.offset),
                 autofoldTextEditor: undefined,
                 guidedTour: undefined,
                 logDisplay: undefined,
                 editorFontSize: undefined,
-                editorFontFamily: undefined
+                editorFontFamily: undefined,
+                now: this.$moment()
             };
         },
         created() {
@@ -132,6 +167,8 @@
             this.lang = localStorage.getItem("lang") || "en";
             this.theme = localStorage.getItem("theme") || "light";
             this.editorTheme = localStorage.getItem("editorTheme") || (darkTheme ? "dark" : "vs");
+            this.dateFormat = localStorage.getItem(DATE_FORMAT_STORAGE_KEY) || "llll";
+            this.timezone = localStorage.getItem(TIMEZONE_STORAGE_KEY) || this.$moment.tz.guess();
             this.autofoldTextEditor = localStorage.getItem("autofoldTextEditor") === "true";
             this.guidedTour = localStorage.getItem("tourDoneOrSkip") === "true";
             this.logDisplay = localStorage.getItem("logDisplay") || logDisplayTypes.DEFAULT;
@@ -171,6 +208,16 @@
                 this.theme = value;
                 this.$toast().saved();
             },
+            onDateFormat(value) {
+                localStorage.setItem(DATE_FORMAT_STORAGE_KEY, value);
+                this.dateFormat = value;
+                this.$toast().saved();
+            },
+            onTimezone(value) {
+                localStorage.setItem(TIMEZONE_STORAGE_KEY, value);
+                this.timezone = value;
+                this.$toast().saved();
+            },
             onEditorTheme(value) {
                 localStorage.setItem("editorTheme", value);
                 this.editorTheme = value;
@@ -237,6 +284,17 @@
                     {value: "dark", text: "Dark"}
                 ]
             },
+            dateFormats() {
+                return  [
+                    {value: "YYYY-MM-DDTHH:mm:ssZ"},
+                    {value: "YYYY-MM-DD hh:mm:ss A"},
+                    {value: "DD/MM/YYYY HH:mm:ss"},
+                    {value: "lll"},
+                    {value: "llll"},
+                    {value: "LLL"},
+                    {value: "LLLL"}
+                ]
+            },
             canReadFlows() {
                 return this.user && this.user.isAllowed(permission.FLOW, action.READ);
             },
diff --git a/ui/src/translations.json b/ui/src/translations.json
index 3034b70362..b69f2acead 100644
--- a/ui/src/translations.json
+++ b/ui/src/translations.json
@@ -70,7 +70,6 @@
     },
     "created date": "Created date",
     "updated date": "Updated date",
-    "date": "Date",
     "source": "Source",
     "home": "Home",
     "create": "Create",
@@ -474,7 +473,9 @@
       "confirmation": "Are you sure you want to unlock the trigger ?",
       "warning": "It could lead to concurrent executions for the same trigger and should be considered as a last resort option.",
       "button": "Unlock trigger"
-    }
+    },
+    "date format": "Date format",
+    "timezone": "Timezone"
   },
   "fr": {
     "id": "Identifiant",
@@ -547,7 +548,6 @@
     },
     "created date": "Date de création",
     "updated date": "Date de mise à jour",
-    "date": "Date",
     "source": "Source",
     "home": "Accueil",
     "create": "Créer",
@@ -953,6 +953,8 @@
       "confirmation": "Êtes vous sûr(e) de vouloir débloquer le déclencheur ?",
       "warning": "Cela pourrait amener à de multiples exécutions concurrentes pour le même déclencheur et devrait être considéré comme une solution de dernier recours.",
       "button": "Débloquer le déclencheur"
-    }
+    },
+    "date format": "Format de date",
+    "timezone": "Fuseau horaire"
   }
 }
diff --git a/ui/src/utils/filters.js b/ui/src/utils/filters.js
index 5f5db2063e..b902a2c1c1 100644
--- a/ui/src/utils/filters.js
+++ b/ui/src/utils/filters.js
@@ -1,5 +1,8 @@
 import Utils from "./utils";
 import {getCurrentInstance} from "vue";
+import {DATE_FORMAT_STORAGE_KEY} from "../components/settings/Settings.vue";
+import {TIMEZONE_STORAGE_KEY} from "../components/settings/Settings.vue";
+import moment from "moment-timezone";
 
 export default {
     invisibleSpace: (value) => {
@@ -15,14 +18,12 @@ export default {
     lower: value => value ? value.toString().toLowerCase() : "",
     date: (dateString, format) => {
         let f;
-        if (format === undefined) {
-            f = "LLLL"
-        } else if (format === "iso") {
+        if (format === "iso") {
             f = "YYYY-MM-DD HH:mm:ss.SSS"
         } else {
-            f = format
+            f = format ?? localStorage.getItem(DATE_FORMAT_STORAGE_KEY) ?? "llll";
         }
-        return getCurrentInstance().appContext.config.globalProperties.$moment(dateString).format(f)
+        return getCurrentInstance().appContext.config.globalProperties.$moment(dateString).tz(localStorage.getItem(TIMEZONE_STORAGE_KEY) ?? moment.tz.guess()).format(f)
     }
 }
 
diff --git a/ui/src/utils/init.js b/ui/src/utils/init.js
index f8ade16d3d..f7ed873c78 100644
--- a/ui/src/utils/init.js
+++ b/ui/src/utils/init.js
@@ -2,7 +2,7 @@ import {createStore} from "vuex";
 import {createRouter, createWebHistory} from "vue-router";
 import VueGtag from "vue-gtag";
 import {createI18n} from "vue-i18n";
-import moment from "moment/moment";
+import moment from "moment-timezone";
 import "moment/locale/fr"
 import {extendMoment} from "moment-range";
 import VueSidebarMenu from "vue-sidebar-menu";


Test patch: