From c1387fdaf95b6e20c0ebf8e234a2f2dc73170112 Mon Sep 17 00:00:00 2001 From: AlexZ005 Date: Thu, 1 Jan 2026 14:30:45 +0000 Subject: [PATCH 1/5] add hours minutes and seconds --- .../java/net/gsantner/markor/format/todotxt/TodoTxtTask.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtTask.java b/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtTask.java index 2f62431053..1b7091d779 100644 --- a/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtTask.java +++ b/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtTask.java @@ -33,8 +33,8 @@ public class TodoTxtTask { // Static memebers // - public static final SimpleDateFormat DATEF_YYYY_MM_DD = new SimpleDateFormat("yyyy-MM-dd", Locale.ROOT); - public static final int DATEF_YYYY_MM_DD_LEN = "yyyy-MM-dd".length(); + public static final SimpleDateFormat DATEF_YYYY_MM_DD = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ROOT); + public static final int DATEF_YYYY_MM_DD_LEN = "yyyy-MM-dd HH:mm:ss".length(); public static final String PT_DATE = "\\d{4}-\\d{2}-\\d{2}"; public static final Pattern PATTERN_PROJECTS = Pattern.compile("(?:^|\\s)(?:\\++)(\\S+)"); public static final Pattern PATTERN_CONTEXTS = Pattern.compile("(?:^|\\s)(?:\\@+)(\\S+)"); From de670a00065b6dcff2c4fe3ce0589af8c83e3411 Mon Sep 17 00:00:00 2001 From: AlexZ005 Date: Thu, 1 Jan 2026 18:09:10 +0000 Subject: [PATCH 2/5] date format preference in settings --- .../markor/format/todotxt/TodoTxtActionButtons.java | 6 +++--- .../format/todotxt/TodoTxtAutoTextFormatter.java | 2 +- .../gsantner/markor/format/todotxt/TodoTxtTask.java | 12 +++++++++--- .../java/net/gsantner/markor/model/AppSettings.java | 4 ++++ app/src/main/res/values/string-not_translatable.xml | 1 + app/src/main/res/values/strings.xml | 3 +++ app/src/main/res/xml/preferences_master.xml | 7 +++++++ 7 files changed, 28 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtActionButtons.java b/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtActionButtons.java index 4c51992032..237d63589e 100644 --- a/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtActionButtons.java +++ b/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtActionButtons.java @@ -365,7 +365,7 @@ private static Calendar parseDateString(final String dateString, final Calendar try { Calendar calendar = Calendar.getInstance(); - calendar.setTime(TodoTxtTask.DATEF_YYYY_MM_DD.parse(dateString)); + calendar.setTime(TodoTxtTask.getDateFormat().parse(dateString)); return calendar; } catch (ParseException e) { return fallback; @@ -384,7 +384,7 @@ private void setDate() { final DatePickerDialog.OnDateSetListener listener = (_view, year, month, day) -> { Calendar fmtCal = Calendar.getInstance(); fmtCal.set(year, month, day); - final String newDate = TodoTxtTask.DATEF_YYYY_MM_DD.format(fmtCal.getTime()); + final String newDate = TodoTxtTask.getDateFormat().format(fmtCal.getTime()); text.replace(sel[0], sel[1], newDate); }; @@ -403,7 +403,7 @@ private void setDueDate(final int offset) { final DatePickerDialog.OnDateSetListener listener = (_view, year, month, day) -> { Calendar fmtCal = Calendar.getInstance(); fmtCal.set(year, month, day); - final String newDue = "due:" + TodoTxtTask.DATEF_YYYY_MM_DD.format(fmtCal.getTime()); + final String newDue = "due:" + TodoTxtTask.getDateFormat().format(fmtCal.getTime()); runRegexReplaceAction( // Replace due date new ReplacePattern(TodoTxtTask.PATTERN_DUE_DATE, "$1" + newDue + "$4"), diff --git a/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtAutoTextFormatter.java b/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtAutoTextFormatter.java index 5d781f84a3..10d65478e5 100644 --- a/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtAutoTextFormatter.java +++ b/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtAutoTextFormatter.java @@ -29,6 +29,6 @@ public CharSequence filter(CharSequence source, int start, int end, Spanned dest } private CharSequence autoIndent(CharSequence source) { - return source + TodoTxtTask.DATEF_YYYY_MM_DD.format(new Date()) + " "; + return source + TodoTxtTask.getDateFormat().format(new Date()) + " "; } } diff --git a/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtTask.java b/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtTask.java index 1b7091d779..d2d2ab2db0 100644 --- a/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtTask.java +++ b/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtTask.java @@ -14,6 +14,7 @@ import net.gsantner.markor.frontend.textview.TextViewUtils; import net.gsantner.opoc.format.GsTextUtils; +import net.gsantner.markor.ApplicationObject; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -33,8 +34,13 @@ public class TodoTxtTask { // Static memebers // - public static final SimpleDateFormat DATEF_YYYY_MM_DD = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ROOT); - public static final int DATEF_YYYY_MM_DD_LEN = "yyyy-MM-dd HH:mm:ss".length(); + public static final String DATEF_YYYY_MM_DD_DEFAULT = "yyyy-MM-dd HH:mm:ss"; + public static final int DATEF_YYYY_MM_DD_LEN = DATEF_YYYY_MM_DD_DEFAULT.length(); + + public static SimpleDateFormat getDateFormat() { + final String fmt = ApplicationObject.settings() != null ? ApplicationObject.settings().getTodoDateFormat() : DATEF_YYYY_MM_DD_DEFAULT; + return new SimpleDateFormat(fmt, Locale.ROOT); + } public static final String PT_DATE = "\\d{4}-\\d{2}-\\d{2}"; public static final Pattern PATTERN_PROJECTS = Pattern.compile("(?:^|\\s)(?:\\++)(\\S+)"); public static final Pattern PATTERN_CONTEXTS = Pattern.compile("(?:^|\\s)(?:\\@+)(\\S+)"); @@ -61,7 +67,7 @@ public enum TodoDueState { } public static String getToday() { - return DATEF_YYYY_MM_DD.format(new Date()); + return getDateFormat().format(new Date()); } public static List getTasks(final CharSequence text, final int[] sel) { diff --git a/app/src/main/java/net/gsantner/markor/model/AppSettings.java b/app/src/main/java/net/gsantner/markor/model/AppSettings.java index 3b657c12ed..07f025e90e 100644 --- a/app/src/main/java/net/gsantner/markor/model/AppSettings.java +++ b/app/src/main/java/net/gsantner/markor/model/AppSettings.java @@ -347,6 +347,10 @@ public boolean isTodoAddCompletionDateEnabled() { return getBool(R.string.pref_key__todotxt__add_completion_date_for_todos, true); } + public String getTodoDateFormat() { + return getString(R.string.pref_key__todotxt__set_date_format, "hh-mm"); + } + public boolean isAppCurrentVersionFirstStart(boolean doSet) { int value = getInt(R.string.pref_key__app_first_start_current_version, -1); if (doSet) { diff --git a/app/src/main/res/values/string-not_translatable.xml b/app/src/main/res/values/string-not_translatable.xml index 932f1fe99b..204418d53d 100644 --- a/app/src/main/res/values/string-not_translatable.xml +++ b/app/src/main/res/values/string-not_translatable.xml @@ -422,6 +422,7 @@ work. If not, see . pref_key__editor_tab_to_indent **** "pref_key__todotxt__additional_projects_contexts" + "pref_key__todotxt__set_date_format" pref_key__todotxt_due_date_offset action_format_keyvalue action_format_plaintext diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9d7403767c..bf124c1d6b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -413,6 +413,9 @@ work. If not, see . Code block Add completion date Add completion date for todos when marking them as done + Set date format + Set date format used in todo tasks + Set date format used in todo tasks. Use following format: File description format Format for the description under each file in the file browser. Follows Android\'s SimpleDateFormat rules, with the addition of FS for showing file size. Leave blank to use the default format for your locale.\n\nExample input:\nFS yyyy MMM dd hh:mm:ss aa\nOutput format:\n30KB 2020 Mar 20 11:24:52 PM Loading default value diff --git a/app/src/main/res/xml/preferences_master.xml b/app/src/main/res/xml/preferences_master.xml index 9c81a41d34..b295ac8022 100644 --- a/app/src/main/res/xml/preferences_master.xml +++ b/app/src/main/res/xml/preferences_master.xml @@ -515,6 +515,13 @@ android:key="@string/pref_key__todotxt__add_completion_date_for_todos" android:summary="@string/add_completion_date_for_todos_when_marking_them_as_done" android:title="@string/add_completion_date" /> + Date: Thu, 1 Jan 2026 19:08:11 +0000 Subject: [PATCH 3/5] default date format fallback --- .../markor/format/todotxt/TodoTxtActionButtons.java | 3 ++- .../gsantner/markor/format/todotxt/TodoTxtTask.java | 13 +++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtActionButtons.java b/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtActionButtons.java index 237d63589e..1c37915bde 100644 --- a/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtActionButtons.java +++ b/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtActionButtons.java @@ -359,7 +359,8 @@ private void setPriority(char priority) { } private static Calendar parseDateString(final String dateString, final Calendar fallback) { - if (dateString == null || dateString.length() != TodoTxtTask.DATEF_YYYY_MM_DD_LEN) { + final String dateFormat = TodoTxtTask.getDateFormat().toPattern(); + if (dateString == null || dateString.length() != dateFormat.length()) { return fallback; } diff --git a/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtTask.java b/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtTask.java index d2d2ab2db0..1f24a4b5ca 100644 --- a/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtTask.java +++ b/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtTask.java @@ -34,12 +34,17 @@ public class TodoTxtTask { // Static memebers // - public static final String DATEF_YYYY_MM_DD_DEFAULT = "yyyy-MM-dd HH:mm:ss"; - public static final int DATEF_YYYY_MM_DD_LEN = DATEF_YYYY_MM_DD_DEFAULT.length(); + public static final String DATE_FORMAT = "yyyy-MM-dd"; public static SimpleDateFormat getDateFormat() { - final String fmt = ApplicationObject.settings() != null ? ApplicationObject.settings().getTodoDateFormat() : DATEF_YYYY_MM_DD_DEFAULT; - return new SimpleDateFormat(fmt, Locale.ROOT); + final String fmt = ApplicationObject.settings() != null ? ApplicationObject.settings().getTodoDateFormat() : DATE_FORMAT; + + try { + return new SimpleDateFormat(fmt, Locale.ROOT); + } catch (IllegalArgumentException e) { + // Fallback: return a default format instead of throwing + return new SimpleDateFormat("yyyy-MM-dd", Locale.ROOT); + } } public static final String PT_DATE = "\\d{4}-\\d{2}-\\d{2}"; public static final Pattern PATTERN_PROJECTS = Pattern.compile("(?:^|\\s)(?:\\++)(\\S+)"); From 596036cd0efec8e5ec91bbbfb3e1df3e46e03ba7 Mon Sep 17 00:00:00 2001 From: AlexZ005 Date: Thu, 1 Jan 2026 21:19:27 +0000 Subject: [PATCH 4/5] array of data formats --- .../gsantner/markor/format/todotxt/TodoTxtTask.java | 2 +- app/src/main/res/values/arrays.xml | 12 ++++++++++++ app/src/main/res/values/strings.xml | 4 +++- app/src/main/res/xml/preferences_master.xml | 10 ++++++---- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtTask.java b/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtTask.java index 1f24a4b5ca..55db09a608 100644 --- a/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtTask.java +++ b/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtTask.java @@ -46,7 +46,7 @@ public static SimpleDateFormat getDateFormat() { return new SimpleDateFormat("yyyy-MM-dd", Locale.ROOT); } } - public static final String PT_DATE = "\\d{4}-\\d{2}-\\d{2}"; + public static final String PT_DATE = "\\d{4}-\\d{2}-\\d{2}(?:[ T]\\d{2}:\\d{2}(?::\\d{2})?)?"; public static final Pattern PATTERN_PROJECTS = Pattern.compile("(?:^|\\s)(?:\\++)(\\S+)"); public static final Pattern PATTERN_CONTEXTS = Pattern.compile("(?:^|\\s)(?:\\@+)(\\S+)"); public static final Pattern PATTERN_DONE = Pattern.compile("(?m)(^[Xx]) (.*)$"); diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 77b1e4733d..7c7b3a0d5b 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -132,6 +132,18 @@ + + + @string/todo_date_format_year_month_day + @string/todo_date_format_year_month_day_hour_minute + @string/todo_date_format_year_month_day_hour_minute_second + + + + yyyy-MM-dd + yyyy-MM-dd HH:mm + yyyy-MM-dd HH:mm:ss + + @string/heading_1 @string/heading_2 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bf124c1d6b..3b6bb81de7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -415,7 +415,9 @@ work. If not, see . Add completion date for todos when marking them as done Set date format Set date format used in todo tasks - Set date format used in todo tasks. Use following format: + yyyy-MM-dd (2026-12-31) + yyyy-MM-dd HH:mm (2026-12-31 14:30) + yyyy-MM-dd HH:mm:ss (2026-12-31 14:30:45) File description format Format for the description under each file in the file browser. Follows Android\'s SimpleDateFormat rules, with the addition of FS for showing file size. Leave blank to use the default format for your locale.\n\nExample input:\nFS yyyy MMM dd hh:mm:ss aa\nOutput format:\n30KB 2020 Mar 20 11:24:52 PM Loading default value diff --git a/app/src/main/res/xml/preferences_master.xml b/app/src/main/res/xml/preferences_master.xml index b295ac8022..3c9d23a7b1 100644 --- a/app/src/main/res/xml/preferences_master.xml +++ b/app/src/main/res/xml/preferences_master.xml @@ -515,11 +515,13 @@ android:key="@string/pref_key__todotxt__add_completion_date_for_todos" android:summary="@string/add_completion_date_for_todos_when_marking_them_as_done" android:title="@string/add_completion_date" /> - Date: Sat, 3 Jan 2026 13:48:47 +0000 Subject: [PATCH 5/5] spacing, comments and typos --- .../format/todotxt/TodoTxtActionButtons.java | 9 ++++----- .../markor/format/todotxt/TodoTxtTask.java | 15 +++++++++++---- .../net/gsantner/markor/model/AppSettings.java | 2 +- app/src/main/res/xml/preferences_master.xml | 2 +- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtActionButtons.java b/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtActionButtons.java index 1c37915bde..4c51992032 100644 --- a/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtActionButtons.java +++ b/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtActionButtons.java @@ -359,14 +359,13 @@ private void setPriority(char priority) { } private static Calendar parseDateString(final String dateString, final Calendar fallback) { - final String dateFormat = TodoTxtTask.getDateFormat().toPattern(); - if (dateString == null || dateString.length() != dateFormat.length()) { + if (dateString == null || dateString.length() != TodoTxtTask.DATEF_YYYY_MM_DD_LEN) { return fallback; } try { Calendar calendar = Calendar.getInstance(); - calendar.setTime(TodoTxtTask.getDateFormat().parse(dateString)); + calendar.setTime(TodoTxtTask.DATEF_YYYY_MM_DD.parse(dateString)); return calendar; } catch (ParseException e) { return fallback; @@ -385,7 +384,7 @@ private void setDate() { final DatePickerDialog.OnDateSetListener listener = (_view, year, month, day) -> { Calendar fmtCal = Calendar.getInstance(); fmtCal.set(year, month, day); - final String newDate = TodoTxtTask.getDateFormat().format(fmtCal.getTime()); + final String newDate = TodoTxtTask.DATEF_YYYY_MM_DD.format(fmtCal.getTime()); text.replace(sel[0], sel[1], newDate); }; @@ -404,7 +403,7 @@ private void setDueDate(final int offset) { final DatePickerDialog.OnDateSetListener listener = (_view, year, month, day) -> { Calendar fmtCal = Calendar.getInstance(); fmtCal.set(year, month, day); - final String newDue = "due:" + TodoTxtTask.getDateFormat().format(fmtCal.getTime()); + final String newDue = "due:" + TodoTxtTask.DATEF_YYYY_MM_DD.format(fmtCal.getTime()); runRegexReplaceAction( // Replace due date new ReplacePattern(TodoTxtTask.PATTERN_DUE_DATE, "$1" + newDue + "$4"), diff --git a/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtTask.java b/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtTask.java index 55db09a608..7403c5bf9b 100644 --- a/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtTask.java +++ b/app/src/main/java/net/gsantner/markor/format/todotxt/TodoTxtTask.java @@ -31,21 +31,28 @@ public class TodoTxtTask { // - // Static memebers + // Static members - date format helpers, regex generators & constants // - public static final String DATE_FORMAT = "yyyy-MM-dd"; + public static final SimpleDateFormat DATEF_YYYY_MM_DD = new SimpleDateFormat("yyyy-MM-dd", Locale.ROOT); + public static final int DATEF_YYYY_MM_DD_LEN = "yyyy-MM-dd".length(); + /** + * Returns a SimpleDateFormat for the configured todo date format. + * Falls back to {@link #DATE_FORMAT} if settings are not available or the configured pattern is invalid. + * Note: This does not cache the SimpleDateFormat instance because the pattern may change at runtime. + */ public static SimpleDateFormat getDateFormat() { - final String fmt = ApplicationObject.settings() != null ? ApplicationObject.settings().getTodoDateFormat() : DATE_FORMAT; + final String fmt = ApplicationObject.settings() != null ? ApplicationObject.settings().getTodoDateFormat() : "yyyy-MM-dd"; try { return new SimpleDateFormat(fmt, Locale.ROOT); } catch (IllegalArgumentException e) { // Fallback: return a default format instead of throwing - return new SimpleDateFormat("yyyy-MM-dd", Locale.ROOT); + return DATEF_YYYY_MM_DD; } } + public static final String PT_DATE = "\\d{4}-\\d{2}-\\d{2}(?:[ T]\\d{2}:\\d{2}(?::\\d{2})?)?"; public static final Pattern PATTERN_PROJECTS = Pattern.compile("(?:^|\\s)(?:\\++)(\\S+)"); public static final Pattern PATTERN_CONTEXTS = Pattern.compile("(?:^|\\s)(?:\\@+)(\\S+)"); diff --git a/app/src/main/java/net/gsantner/markor/model/AppSettings.java b/app/src/main/java/net/gsantner/markor/model/AppSettings.java index 07f025e90e..a8e67c4624 100644 --- a/app/src/main/java/net/gsantner/markor/model/AppSettings.java +++ b/app/src/main/java/net/gsantner/markor/model/AppSettings.java @@ -348,7 +348,7 @@ public boolean isTodoAddCompletionDateEnabled() { } public String getTodoDateFormat() { - return getString(R.string.pref_key__todotxt__set_date_format, "hh-mm"); + return getString(R.string.pref_key__todotxt__set_date_format, "yyyy-MM-dd"); } public boolean isAppCurrentVersionFirstStart(boolean doSet) { diff --git a/app/src/main/res/xml/preferences_master.xml b/app/src/main/res/xml/preferences_master.xml index 3c9d23a7b1..2c0579adfd 100644 --- a/app/src/main/res/xml/preferences_master.xml +++ b/app/src/main/res/xml/preferences_master.xml @@ -516,7 +516,7 @@ android:summary="@string/add_completion_date_for_todos_when_marking_them_as_done" android:title="@string/add_completion_date" />