#include <config.h> #include <glib.h> #include <glib/gi18n.h> #include <string.h> #include "e_date.h" /* all this code comes from evolution - e-util.c - message-list.c */ static size_t e_strftime(char *s, size_t max, const char *fmt, const struct tm *tm) { #ifdef HAVE_LKSTRFTIME return strftime(s, max, fmt, tm); #else char *c, *ffmt, *ff; size_t ret; ffmt = g_strdup(fmt); ff = ffmt; while ((c = strstr(ff, "%l")) != NULL) { c[1] = 'I'; ff = c; } ff = ffmt; while ((c = strstr(ff, "%k")) != NULL) { c[1] = 'H'; ff = c; } ret = strftime(s, max, ffmt, tm); g_free(ffmt); return ret; #endif } /** * Function to do a last minute fixup of the AM/PM stuff if the locale * and gettext haven't done it right. Most English speaking countries * except the USA use the 24 hour clock (UK, Australia etc). However * since they are English nobody bothers to write a language * translation (gettext) file. So the locale turns off the AM/PM, but * gettext does not turn on the 24 hour clock. Leaving a mess. * * This routine checks if AM/PM are defined in the locale, if not it * forces the use of the 24 hour clock. * * The function itself is a front end on strftime and takes exactly * the same arguments. * * TODO: Actually remove the '%p' from the fixed up string so that * there isn't a stray space. **/ static size_t e_strftime_fix_am_pm(char *s, size_t max, const char *fmt, const struct tm *tm) { char buf[10]; char *sp; char *ffmt; size_t ret; if (strstr(fmt, "%p")==NULL && strstr(fmt, "%P")==NULL) { /* No AM/PM involved - can use the fmt string directly */ ret=e_strftime(s, max, fmt, tm); } else { /* Get the AM/PM symbol from the locale */ e_strftime (buf, 10, "%p", tm); if (buf[0]) { /** * AM/PM have been defined in the locale * so we can use the fmt string directly **/ ret=e_strftime(s, max, fmt, tm); } else { /** * No AM/PM defined by locale * must change to 24 hour clock **/ ffmt=g_strdup(fmt); for (sp=ffmt; (sp=strstr(sp, "%l")); sp++) { /** * Maybe this should be 'k', but I have never * seen a 24 clock actually use that format **/ sp[1]='H'; } for (sp=ffmt; (sp=strstr(sp, "%I")); sp++) { sp[1]='H'; } ret=e_strftime(s, max, ffmt, tm); g_free(ffmt); } } return(ret); } static size_t e_utf8_strftime_fix_am_pm(char *s, size_t max, const char *fmt, const struct tm *tm) { size_t sz, ret; char *locale_fmt, *buf; locale_fmt = g_locale_from_utf8(fmt, -1, NULL, &sz, NULL); if (!locale_fmt) return 0; ret = e_strftime_fix_am_pm(s, max, locale_fmt, tm); if (!ret) { g_free (locale_fmt); return 0; } buf = g_locale_to_utf8(s, ret, NULL, &sz, NULL); if (!buf) { g_free (locale_fmt); return 0; } if (sz >= max) { char *tmp = buf + max - 1; tmp = g_utf8_find_prev_char(buf, tmp); if (tmp) sz = tmp - buf; else sz = 0; } memcpy(s, buf, sz); s[sz] = '\0'; g_free(locale_fmt); g_free(buf); return sz; } static char * filter_date (time_t date) { time_t nowdate = time(NULL); time_t yesdate; struct tm then, now, yesterday; char buf[26]; gboolean done = FALSE; if (date == 0) // xgettext: ? stands for unknown return g_strdup (_("?")); localtime_r (&date, &then); localtime_r (&nowdate, &now); if (then.tm_mday == now.tm_mday && then.tm_mon == now.tm_mon && then.tm_year == now.tm_year) { e_utf8_strftime_fix_am_pm (buf, 26, _("Today %l:%M %p"), &then); 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) { e_utf8_strftime_fix_am_pm (buf, 26, _("Yesterday %l:%M %p"), &then); done = TRUE; } } if (!done) { 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) { e_utf8_strftime_fix_am_pm (buf, 26, _("%a %l:%M %p"), &then); done = TRUE; break; } } } if (!done) { if (then.tm_year == now.tm_year) { e_utf8_strftime_fix_am_pm (buf, 26, _("%b %d %l:%M %p"), &then); } else { e_utf8_strftime_fix_am_pm (buf, 26, _("%b %d %Y"), &then); } } return g_strdup (buf); } char * procman_format_date_for_display(time_t d) { return filter_date(d); }