diff --git a/lib/rb-cut-and-paste-code.c b/lib/rb-cut-and-paste-code.c index 5b4d66831..7880dd9ae 100644 --- a/lib/rb-cut-and-paste-code.c +++ b/lib/rb-cut-and-paste-code.c @@ -79,230 +79,64 @@ eel_create_colorized_pixbuf (GdkPixbuf *src, return dest; } -/* Legal conversion specifiers, as specified in the C standard. */ -#define C_STANDARD_STRFTIME_CHARACTERS "aAbBcdHIjmMpSUwWxXyYZ" -#define C_STANDARD_NUMERIC_STRFTIME_CHARACTERS "dHIjmMSUwWyY" -#define SUS_EXTENDED_STRFTIME_MODIFIERS "EO" - -/** - * eel_strdup_strftime: - * - * Cover for standard date-and-time-formatting routine strftime that returns - * a newly-allocated string of the correct size. The caller is responsible - * for g_free-ing the returned string. - * - * Besides the buffer management, there are two differences between this - * and the library strftime: - * - * 1) The modifiers "-" and "_" between a "%" and a numeric directive - * are defined as for the GNU version of strftime. "-" means "do not - * pad the field" and "_" means "pad with spaces instead of zeroes". - * 2) Non-ANSI extensions to strftime are flagged at runtime with a - * warning, so it's easy to notice use of the extensions without - * testing with multiple versions of the library. - * - * @format: format string to pass to strftime. See strftime documentation - * for details. - * @time_pieces: date/time, in struct format. - * - * Return value: Newly allocated string containing the formatted time. - **/ -char * -eel_strdup_strftime (const char *format, struct tm *time_pieces) -{ - GString *string; - const char *remainder, *percent; - char code[4], buffer[512]; - char *piece, *result, *converted; - size_t string_length; - gboolean strip_leading_zeros, turn_leading_zeros_to_spaces; - char modifier; - int i; - - /* Format could be translated, and contain UTF-8 chars, - * so convert to locale encoding which strftime uses */ - converted = g_locale_from_utf8 (format, -1, NULL, NULL, NULL); - g_return_val_if_fail (converted != NULL, NULL); - - string = g_string_new (""); - remainder = converted; - - /* Walk from % character to % character. */ - for (;;) { - percent = strchr (remainder, '%'); - if (percent == NULL) { - g_string_append (string, remainder); - break; - } - g_string_append_len (string, remainder, - percent - remainder); - - /* Handle the "%" character. */ - remainder = percent + 1; - switch (*remainder) { - case '-': - strip_leading_zeros = TRUE; - turn_leading_zeros_to_spaces = FALSE; - remainder++; - break; - case '_': - strip_leading_zeros = FALSE; - turn_leading_zeros_to_spaces = TRUE; - remainder++; - break; - case '%': - g_string_append_c (string, '%'); - remainder++; - continue; - case '\0': - g_warning ("Trailing %% passed to eel_strdup_strftime"); - g_string_append_c (string, '%'); - continue; - default: - strip_leading_zeros = FALSE; - turn_leading_zeros_to_spaces = FALSE; - break; - } - - modifier = 0; - if (strchr (SUS_EXTENDED_STRFTIME_MODIFIERS, *remainder) != NULL) { - modifier = *remainder; - remainder++; - - if (*remainder == 0) { - g_warning ("Unfinished %%%c modifier passed to eel_strdup_strftime", modifier); - break; - } - } - - if (strchr (C_STANDARD_STRFTIME_CHARACTERS, *remainder) == NULL) { - g_warning ("eel_strdup_strftime does not support " - "non-standard escape code %%%c", - *remainder); - } - - /* Convert code to strftime format. We have a fixed - * limit here that each code can expand to a maximum - * of 512 bytes, which is probably OK. There's no - * limit on the total size of the result string. - */ - i = 0; - code[i++] = '%'; - if (modifier != 0) { -#ifdef HAVE_STRFTIME_EXTENSION - code[i++] = modifier; -#endif - } - code[i++] = *remainder; - code[i++] = '\0'; - string_length = strftime (buffer, sizeof (buffer), - code, time_pieces); - if (string_length == 0) { - /* We could put a warning here, but there's no - * way to tell a successful conversion to - * empty string from a failure. - */ - buffer[0] = '\0'; - } - - /* Strip leading zeros if requested. */ - piece = buffer; - if (strip_leading_zeros || turn_leading_zeros_to_spaces) { - if (strchr (C_STANDARD_NUMERIC_STRFTIME_CHARACTERS, *remainder) == NULL) { - g_warning ("eel_strdup_strftime does not support " - "modifier for non-numeric escape code %%%c%c", - remainder[-1], - *remainder); - } - if (*piece == '0') { - do { - piece++; - } while (*piece == '0'); - if (!g_ascii_isdigit (*piece)) { - piece--; - } - } - if (turn_leading_zeros_to_spaces) { - memset (buffer, ' ', piece - buffer); - piece = buffer; - } - } - remainder++; - - /* Add this piece. */ - g_string_append (string, piece); - } - - /* Convert the string back into utf-8. */ - result = g_locale_to_utf8 (string->str, -1, NULL, NULL, NULL); - - g_string_free (string, TRUE); - g_free (converted); - - return result; -} - /* Based on evolution/mail/message-list.c:filter_date() */ char * rb_utf_friendly_time (time_t date) { - time_t nowdate; - time_t yesdate; - struct tm then, now, yesterday; + GDateTime *datetime, *now, *yesterday; + int d, m, y; + int nd, nm, ny; + int yd, ym, yy; const char *format = NULL; char *str = NULL; - gboolean done = FALSE; - nowdate = time (NULL); + if (date == 0) { + return g_strdup (_("Never")); + } - if (date == 0) - return NULL; + now = g_date_time_new_now_local (); + datetime = g_date_time_new_from_unix_local (date); - localtime_r (&date, &then); - localtime_r (&nowdate, &now); + g_date_time_get_ymd (datetime, &y, &m, &d); + g_date_time_get_ymd (now, &ny, &nm, &nd); - if (then.tm_mday == now.tm_mday && - then.tm_mon == now.tm_mon && - then.tm_year == now.tm_year) { + if (y == ny && m == nm && d == nd) { /* Translators: "friendly time" string for the current day, strftime format. like "Today 12:34 am" */ format = _("Today %I:%M %p"); - done = TRUE; } - if (! done) { - yesdate = nowdate - 60 * 60 * 24; - localtime_r (&yesdate, &yesterday); - if (then.tm_mday == yesterday.tm_mday && - then.tm_mon == yesterday.tm_mon && - then.tm_year == yesterday.tm_year) { + if (format == NULL) { + yesterday = g_date_time_add_days (now, -1); + + g_date_time_get_ymd (yesterday, &yy, &ym, &yd); + if (y == yy && m == ym && d == yd) { /* Translators: "friendly time" string for the previous day, * strftime format. e.g. "Yesterday 12:34 am" */ format = _("Yesterday %I:%M %p"); - done = TRUE; } + g_date_time_unref (yesterday); } - if (! done) { + if (format == NULL) { int i; for (i = 2; i < 7; i++) { - yesdate = nowdate - 60 * 60 * 24 * i; - localtime_r (&yesdate, &yesterday); - if (then.tm_mday == yesterday.tm_mday && - then.tm_mon == yesterday.tm_mon && - then.tm_year == yesterday.tm_year) { + yesterday = g_date_time_add_days (now, -i); + g_date_time_get_ymd (yesterday, &yy, &ym, &yd); + if (y == yy && m == ym && d == yd) { /* Translators: "friendly time" string for a day in the current week, * strftime format. e.g. "Wed 12:34 am" */ format = _("%a %I:%M %p"); - done = TRUE; + g_date_time_unref (yesterday); break; } + g_date_time_unref (yesterday); } } - if (! done) { - if (then.tm_year == now.tm_year) { + if (format == NULL) { + if (y == ny) { /* Translators: "friendly time" string for a day in the current year, * strftime format. e.g. "Feb 12 12:34 am" */ @@ -316,7 +150,7 @@ rb_utf_friendly_time (time_t date) } if (format != NULL) { - str = eel_strdup_strftime (format, &then); + str = g_date_time_format (datetime, format); } if (str == NULL) { @@ -324,6 +158,9 @@ rb_utf_friendly_time (time_t date) str = g_strdup (_("Unknown")); } + g_date_time_unref (datetime); + g_date_time_unref (now); + return str; } diff --git a/lib/rb-cut-and-paste-code.h b/lib/rb-cut-and-paste-code.h index bf4581fab..feb43487f 100644 --- a/lib/rb-cut-and-paste-code.h +++ b/lib/rb-cut-and-paste-code.h @@ -25,9 +25,6 @@ G_BEGIN_DECLS -char *eel_strdup_strftime (const char *format, - struct tm *time_pieces); - GdkPixbuf *eel_create_colorized_pixbuf (GdkPixbuf *src, int red_value, int green_value,