GDateTime: enhance g_date_time_format()

Make g_date_time_format() support some useful format modifiers from
strftime(). This commit adds support for the POSIX 'O' modifier
(alternative digits), as well as the -/_/0 padding modifiers, which
are a GNU strftime() extension.
https://bugzilla.gnome.org/show_bug.cgi?id=648678
This commit is contained in:
Matthias Clasen 2011-05-05 13:16:30 -04:00
parent 8932a1a7a3
commit d23c33a04b

View File

@ -2040,6 +2040,46 @@ g_date_time_to_utc (GDateTime *datetime)
} }
/* Format {{{1 */ /* Format {{{1 */
static void
get_numeric_format (gchar *fmt,
gsize len,
gboolean alt_digits,
gchar pad,
gint width)
{
const gchar *width_str;
if (pad == 0)
width_str = "";
else
{
switch (width)
{
case 0:
width_str = "";
break;
default:
g_warning ("get_numeric_format: width %d not handled", width);
/* fall thru */
case 2:
if (pad == '0')
width_str = "02";
else
width_str = "2";
break;
case 3:
if (pad == '0')
width_str = "03";
else
width_str = "3";
break;
}
}
g_snprintf (fmt, len, "%%%s%sd", alt_digits ? "I": "", width_str);
}
/** /**
* g_date_time_format: * g_date_time_format:
* @datetime: A #GDateTime * @datetime: A #GDateTime
@ -2238,6 +2278,10 @@ g_date_time_format (GDateTime *datetime,
gchar *tmp; gchar *tmp;
gunichar c; gunichar c;
gboolean in_mod; gboolean in_mod;
gboolean alt_digits;
gboolean pad_set;
gchar pad;
gchar fmt[20];
g_return_val_if_fail (datetime != NULL, NULL); g_return_val_if_fail (datetime != NULL, NULL);
g_return_val_if_fail (format != NULL, NULL); g_return_val_if_fail (format != NULL, NULL);
@ -2256,6 +2300,8 @@ g_date_time_format (GDateTime *datetime,
if (!in_mod) if (!in_mod)
{ {
in_mod = TRUE; in_mod = TRUE;
alt_digits = FALSE;
pad_set = FALSE;
break; break;
} }
/* Fall through */ /* Fall through */
@ -2277,10 +2323,12 @@ g_date_time_format (GDateTime *datetime,
g_string_append (outstr, MONTH_FULL (datetime)); g_string_append (outstr, MONTH_FULL (datetime));
break; break;
case 'd': case 'd':
g_string_append_printf (outstr, "%02d", g_date_time_get_day_of_month (datetime)); get_numeric_format (fmt, sizeof(fmt), alt_digits, pad_set ? pad : '0', 2);
g_string_append_printf (outstr, fmt, g_date_time_get_day_of_month (datetime));
break; break;
case 'e': case 'e':
g_string_append_printf (outstr, "%2d", g_date_time_get_day_of_month (datetime)); get_numeric_format (fmt, sizeof(fmt), alt_digits, pad_set ? pad : 0, 2);
g_string_append_printf (outstr, fmt, g_date_time_get_day_of_month (datetime));
break; break;
case 'F': case 'F':
g_string_append_printf (outstr, "%d-%02d-%02d", g_string_append_printf (outstr, "%d-%02d-%02d",
@ -2292,35 +2340,49 @@ g_date_time_format (GDateTime *datetime,
g_string_append (outstr, MONTH_ABBR (datetime)); g_string_append (outstr, MONTH_ABBR (datetime));
break; break;
case 'H': case 'H':
g_string_append_printf (outstr, "%02d", g_date_time_get_hour (datetime)); get_numeric_format (fmt, sizeof(fmt), alt_digits, pad_set ? pad : '0', 2);
g_string_append_printf (outstr, fmt, g_date_time_get_hour (datetime));
break; break;
case 'I': case 'I':
if ((g_date_time_get_hour (datetime) % 12) == 0) {
g_string_append (outstr, "12"); gint hour = g_date_time_get_hour (datetime) % 12;
else if (hour == 0)
g_string_append_printf (outstr, "%02d", g_date_time_get_hour (datetime) % 12); hour = 12;
get_numeric_format (fmt, sizeof(fmt), alt_digits, pad_set ? pad : '0', 2);
g_string_append_printf (outstr, fmt, hour);
}
break; break;
case 'j': case 'j':
g_string_append_printf (outstr, "%03d", g_date_time_get_day_of_year (datetime)); get_numeric_format (fmt, sizeof(fmt), FALSE, pad_set ? pad : '0', 3);
g_string_append_printf (outstr, fmt, g_date_time_get_day_of_year (datetime));
break; break;
case 'k': case 'k':
g_string_append_printf (outstr, "%2d", g_date_time_get_hour (datetime)); get_numeric_format (fmt, sizeof(fmt), alt_digits, pad_set ? pad : ' ', 2);
g_string_append_printf (outstr, fmt, g_date_time_get_hour (datetime));
break; break;
case 'l': case 'l':
if ((g_date_time_get_hour (datetime) % 12) == 0) {
g_string_append (outstr, "12"); gint hour = g_date_time_get_hour (datetime) % 12;
else if (hour == 0)
g_string_append_printf (outstr, "%2d", g_date_time_get_hour (datetime) % 12); hour = 12;
get_numeric_format (fmt, sizeof(fmt), alt_digits, pad_set ? pad : ' ', 2);
g_string_append_printf (outstr, fmt, hour);
}
break; break;
case 'm': case 'm':
g_string_append_printf (outstr, "%02d", g_date_time_get_month (datetime)); get_numeric_format (fmt, sizeof(fmt), alt_digits, pad_set ? pad : '0', 2);
g_string_append_printf (outstr, fmt, g_date_time_get_month (datetime));
break; break;
case 'M': case 'M':
g_string_append_printf (outstr, "%02d", g_date_time_get_minute (datetime)); get_numeric_format (fmt, sizeof(fmt), alt_digits, pad_set ? pad : '0', 2);
g_string_append_printf (outstr, fmt, g_date_time_get_minute (datetime));
break; break;
case 'N': case 'N':
g_string_append_printf (outstr, "%"G_GUINT64_FORMAT, datetime->usec % USEC_PER_SECOND); g_string_append_printf (outstr, "%"G_GUINT64_FORMAT, datetime->usec % USEC_PER_SECOND);
break; break;
case 'O':
alt_digits = TRUE;
goto next_mod;
case 'p': case 'p':
g_string_append (outstr, GET_AMPM (datetime, FALSE)); g_string_append (outstr, GET_AMPM (datetime, FALSE));
break; break;
@ -2348,16 +2410,19 @@ g_date_time_format (GDateTime *datetime,
g_string_append_printf (outstr, "%" G_GINT64_FORMAT, g_date_time_to_unix (datetime)); g_string_append_printf (outstr, "%" G_GINT64_FORMAT, g_date_time_to_unix (datetime));
break; break;
case 'S': case 'S':
g_string_append_printf (outstr, "%02d", g_date_time_get_second (datetime)); get_numeric_format (fmt, sizeof(fmt), alt_digits, pad_set ? pad : '0', 2);
g_string_append_printf (outstr, fmt, g_date_time_get_second (datetime));
break; break;
case 't': case 't':
g_string_append_c (outstr, '\t'); g_string_append_c (outstr, '\t');
break; break;
case 'u': case 'u':
g_string_append_printf (outstr, "%d", g_date_time_get_day_of_week (datetime)); get_numeric_format (fmt, sizeof(fmt), alt_digits, 0, 0);
g_string_append_printf (outstr, fmt, g_date_time_get_day_of_week (datetime));
break; break;
case 'W': case 'W':
g_string_append_printf (outstr, "%d", g_date_time_get_day_of_year (datetime) / 7); get_numeric_format (fmt, sizeof(fmt), alt_digits, 0, 0);
g_string_append_printf (outstr, fmt, g_date_time_get_day_of_year (datetime) / 7);
break; break;
case 'x': case 'x':
{ {
@ -2374,10 +2439,12 @@ g_date_time_format (GDateTime *datetime,
} }
break; break;
case 'y': case 'y':
g_string_append_printf (outstr, "%02d", g_date_time_get_year (datetime) % 100); get_numeric_format (fmt, sizeof(fmt), alt_digits, pad_set ? pad : '0', 2);
g_string_append_printf (outstr, fmt, g_date_time_get_year (datetime) % 100);
break; break;
case 'Y': case 'Y':
g_string_append_printf (outstr, "%d", g_date_time_get_year (datetime)); get_numeric_format (fmt, sizeof(fmt), alt_digits, 0, 0);
g_string_append_printf (outstr, fmt, g_date_time_get_year (datetime));
break; break;
case 'z': case 'z':
if (datetime->tz != NULL) if (datetime->tz != NULL)
@ -2401,6 +2468,18 @@ g_date_time_format (GDateTime *datetime,
case 'n': case 'n':
g_string_append_c (outstr, '\n'); g_string_append_c (outstr, '\n');
break; break;
case '-':
pad_set = TRUE;
pad = 0;
goto next_mod;
case '_':
pad_set = TRUE;
pad = ' ';
goto next_mod;
case '0':
pad_set = TRUE;
pad = '0';
goto next_mod;
default: default:
goto bad_format; goto bad_format;
} }
@ -2409,6 +2488,7 @@ g_date_time_format (GDateTime *datetime,
else else
g_string_append_unichar (outstr, c); g_string_append_unichar (outstr, c);
} }
next_mod: ;
} }
return g_string_free (outstr, FALSE); return g_string_free (outstr, FALSE);