summaryrefslogtreecommitdiff
path: root/src/e_date.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/e_date.c')
-rw-r--r--src/e_date.c214
1 files changed, 214 insertions, 0 deletions
diff --git a/src/e_date.c b/src/e_date.c
new file mode 100644
index 0000000..9b9a894
--- /dev/null
+++ b/src/e_date.c
@@ -0,0 +1,214 @@
+#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);
+ }
+ }
+#if 0
+#ifdef CTIME_R_THREE_ARGS
+ ctime_r (&date, buf, 26);
+#else
+ ctime_r (&date, buf);
+#endif
+#endif
+
+ return g_strdup (buf);
+}
+
+
+
+
+char *
+procman_format_date_for_display(time_t d)
+{
+ return filter_date(d);
+}