/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
#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);
}