Merge branch 'new_datetime_mods' into 'main'

Add support for case modifiers to DateTime

Closes #3115

See merge request GNOME/glib!3584
This commit is contained in:
Philip Withnall 2023-10-03 08:43:03 +00:00
commit a9f2ffe788
2 changed files with 74 additions and 10 deletions

View File

@ -3048,8 +3048,10 @@ g_date_time_format_utf8 (GDateTime *datetime,
gunichar c; gunichar c;
gboolean alt_digits = FALSE; gboolean alt_digits = FALSE;
gboolean pad_set = FALSE; gboolean pad_set = FALSE;
gboolean mod_case = FALSE;
gboolean name_is_utf8; gboolean name_is_utf8;
const gchar *pad = ""; const gchar *pad = "";
const gchar *mod = "";
const gchar *name; const gchar *name;
const gchar *tz; const gchar *tz;
@ -3071,6 +3073,7 @@ g_date_time_format_utf8 (GDateTime *datetime,
colons = 0; colons = 0;
alt_digits = FALSE; alt_digits = FALSE;
pad_set = FALSE; pad_set = FALSE;
mod_case = FALSE;
next_mod: next_mod:
c = g_utf8_get_char (utf8_format); c = g_utf8_get_char (utf8_format);
@ -3078,7 +3081,8 @@ g_date_time_format_utf8 (GDateTime *datetime,
switch (c) switch (c)
{ {
case 'a': case 'a':
name = WEEKDAY_ABBR (datetime); name = mod_case ? g_utf8_strup (WEEKDAY_ABBR (datetime), -1)
: WEEKDAY_ABBR (datetime);
if (g_strcmp0 (name, "") == 0) if (g_strcmp0 (name, "") == 0)
return FALSE; return FALSE;
@ -3089,7 +3093,8 @@ g_date_time_format_utf8 (GDateTime *datetime,
break; break;
case 'A': case 'A':
name = WEEKDAY_FULL (datetime); name = mod_case ? g_utf8_strup (WEEKDAY_FULL (datetime), -1)
: WEEKDAY_FULL (datetime);
if (g_strcmp0 (name, "") == 0) if (g_strcmp0 (name, "") == 0)
return FALSE; return FALSE;
@ -3104,6 +3109,8 @@ g_date_time_format_utf8 (GDateTime *datetime,
: MONTH_ABBR_WITH_DAY (datetime); : MONTH_ABBR_WITH_DAY (datetime);
if (g_strcmp0 (name, "") == 0) if (g_strcmp0 (name, "") == 0)
return FALSE; return FALSE;
if (mod_case)
name = g_utf8_strup (name, -1);
name_is_utf8 = locale_is_utf8 || name_is_utf8 = locale_is_utf8 ||
((alt_digits && !MONTH_ABBR_STANDALONE_IS_LOCALE) || ((alt_digits && !MONTH_ABBR_STANDALONE_IS_LOCALE) ||
@ -3118,6 +3125,8 @@ g_date_time_format_utf8 (GDateTime *datetime,
: MONTH_FULL_WITH_DAY (datetime); : MONTH_FULL_WITH_DAY (datetime);
if (g_strcmp0 (name, "") == 0) if (g_strcmp0 (name, "") == 0)
return FALSE; return FALSE;
if (mod_case)
name = g_utf8_strup (name, -1);
name_is_utf8 = locale_is_utf8 || name_is_utf8 = locale_is_utf8 ||
((alt_digits && !MONTH_FULL_STANDALONE_IS_LOCALE) || ((alt_digits && !MONTH_FULL_STANDALONE_IS_LOCALE) ||
@ -3171,6 +3180,8 @@ g_date_time_format_utf8 (GDateTime *datetime,
: MONTH_ABBR_WITH_DAY (datetime); : MONTH_ABBR_WITH_DAY (datetime);
if (g_strcmp0 (name, "") == 0) if (g_strcmp0 (name, "") == 0)
return FALSE; return FALSE;
if (mod_case)
name = g_utf8_strup (name, -1);
name_is_utf8 = locale_is_utf8 || name_is_utf8 = locale_is_utf8 ||
((alt_digits && !MONTH_ABBR_STANDALONE_IS_LOCALE) || ((alt_digits && !MONTH_ABBR_STANDALONE_IS_LOCALE) ||
@ -3215,11 +3226,15 @@ g_date_time_format_utf8 (GDateTime *datetime,
alt_digits = TRUE; alt_digits = TRUE;
goto next_mod; goto next_mod;
case 'p': case 'p':
if (!format_ampm (datetime, outstr, locale_is_utf8, TRUE)) if (!format_ampm (datetime, outstr, locale_is_utf8,
mod_case && g_strcmp0 (mod, "#") == 0 ? FALSE
: TRUE))
return FALSE; return FALSE;
break; break;
case 'P': case 'P':
if (!format_ampm (datetime, outstr, locale_is_utf8, FALSE)) if (!format_ampm (datetime, outstr, locale_is_utf8,
mod_case && g_strcmp0 (mod, "^") == 0 ? TRUE
: FALSE))
return FALSE; return FALSE;
break; break;
case 'r': case 'r':
@ -3299,7 +3314,8 @@ g_date_time_format_utf8 (GDateTime *datetime,
} }
break; break;
case 'Z': case 'Z':
tz = g_date_time_get_timezone_abbreviation (datetime); tz = mod_case && g_strcmp0 (mod, "#") == 0 ? g_utf8_strdown (g_date_time_get_timezone_abbreviation (datetime), -1)
: g_date_time_get_timezone_abbreviation (datetime);
g_string_append (outstr, tz); g_string_append (outstr, tz);
break; break;
case '%': case '%':
@ -3323,6 +3339,14 @@ g_date_time_format_utf8 (GDateTime *datetime,
return FALSE; return FALSE;
colons++; colons++;
goto next_mod; goto next_mod;
case '^':
mod_case = TRUE;
mod = "^";
goto next_mod;
case '#':
mod_case = TRUE;
mod = "#";
goto next_mod;
default: default:
return FALSE; return FALSE;
} }
@ -3418,8 +3442,9 @@ g_date_time_format_utf8 (GDateTime *datetime,
* - `%%`: a literal `%` character * - `%%`: a literal `%` character
* *
* Some conversion specifications can be modified by preceding the * Some conversion specifications can be modified by preceding the
* conversion specifier by one or more modifier characters. The * conversion specifier by one or more modifier characters.
* following modifiers are supported for many of the numeric *
* The following modifiers are supported for many of the numeric
* conversions: * conversions:
* *
* - `O`: Use alternative numeric symbols, if the current locale supports those. * - `O`: Use alternative numeric symbols, if the current locale supports those.
@ -3430,6 +3455,13 @@ g_date_time_format_utf8 (GDateTime *datetime,
* - `0`: Pad a numeric result with zeros. This overrides the default padding * - `0`: Pad a numeric result with zeros. This overrides the default padding
* for the specifier. * for the specifier.
* *
* The following modifiers are supported for many of the alphabetic conversions:
*
* - `^`: Use upper case if possible. This is a gnulib `strftime()` extension.
* Since: 2.80
* - `#`: Use opposite case if possible. This is a gnulib `strftime()`
* extension. Since: 2.80
*
* Additionally, when `O` is used with `B`, `b`, or `h`, it produces the alternative * Additionally, when `O` is used with `B`, `b`, or `h`, it produces the alternative
* form of a month name. The alternative form should be used when the month * form of a month name. The alternative form should be used when the month
* name is used without a day number (e.g., standalone). It is required in * name is used without a day number (e.g., standalone). It is required in

View File

@ -1792,6 +1792,30 @@ test_modifiers (void)
TEST_PRINTF_DATE (2009, 1, 21, "%-e", "21"); TEST_PRINTF_DATE (2009, 1, 21, "%-e", "21");
TEST_PRINTF_DATE (2009, 1, 21, "%0e", "21"); TEST_PRINTF_DATE (2009, 1, 21, "%0e", "21");
TEST_PRINTF_DATE (2009, 1, 1, "%a", "Thu");
TEST_PRINTF_DATE (2009, 1, 1, "%^a", "THU");
TEST_PRINTF_DATE (2009, 1, 1, "%#a", "THU");
TEST_PRINTF_DATE (2009, 1, 1, "%A", "Thursday");
TEST_PRINTF_DATE (2009, 1, 1, "%^A", "THURSDAY");
TEST_PRINTF_DATE (2009, 1, 1, "%#A", "THURSDAY");
TEST_PRINTF_DATE (2009, 1, 1, "%b", "Jan");
TEST_PRINTF_DATE (2009, 1, 1, "%^b", "JAN");
TEST_PRINTF_DATE (2009, 1, 1, "%#b", "JAN");
TEST_PRINTF_DATE (2009, 1, 1, "%B", "January");
TEST_PRINTF_DATE (2009, 1, 1, "%^B", "JANUARY");
TEST_PRINTF_DATE (2009, 1, 1, "%#B", "JANUARY");
TEST_PRINTF_DATE (2009, 1, 1, "%h", "Jan");
TEST_PRINTF_DATE (2009, 1, 1, "%^h", "JAN");
TEST_PRINTF_DATE (2009, 1, 1, "%#h", "JAN");
TEST_PRINTF_DATE (2009, 1, 1, "%Z", "UTC");
TEST_PRINTF_DATE (2009, 1, 1, "%^Z", "UTC");
TEST_PRINTF_DATE (2009, 1, 1, "%#Z", "utc");
TEST_PRINTF_TIME ( 1, 0, 0, "%H", "01"); TEST_PRINTF_TIME ( 1, 0, 0, "%H", "01");
TEST_PRINTF_TIME ( 1, 0, 0, "%_H", " 1"); TEST_PRINTF_TIME ( 1, 0, 0, "%_H", " 1");
TEST_PRINTF_TIME ( 1, 0, 0, "%-H", "1"); TEST_PRINTF_TIME ( 1, 0, 0, "%-H", "1");
@ -1824,6 +1848,14 @@ test_modifiers (void)
TEST_PRINTF_TIME (23, 0, 0, "%-l", "11"); TEST_PRINTF_TIME (23, 0, 0, "%-l", "11");
TEST_PRINTF_TIME (23, 0, 0, "%0l", "11"); TEST_PRINTF_TIME (23, 0, 0, "%0l", "11");
TEST_PRINTF_TIME (1, 0, 0, "%p", "AM");
TEST_PRINTF_TIME (1, 0, 0, "%^p", "AM");
TEST_PRINTF_TIME (1, 0, 0, "%#p", "am");
TEST_PRINTF_TIME (1, 0, 0, "%P", "am");
TEST_PRINTF_TIME (1, 0, 0, "%^P", "AM");
TEST_PRINTF_TIME (1, 0, 0, "%#P", "am");
oldlocale = g_strdup (setlocale (LC_ALL, NULL)); oldlocale = g_strdup (setlocale (LC_ALL, NULL));
setlocale (LC_ALL, "fa_IR.utf-8"); setlocale (LC_ALL, "fa_IR.utf-8");
#ifdef HAVE_LANGINFO_OUTDIGIT #ifdef HAVE_LANGINFO_OUTDIGIT