X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Ffmt_date.c;h=2c7c9f6fd237b82981375bf8b9d8a50d7dc235d0;hb=694a3ea878536e2deda1c0168e51837a31b81af7;hp=55b9897c8262aaf0625c2bc3a83c799d97c5d50c;hpb=fc6832083dc3c224c955853a827a9151b19c2d12;p=citadel.git diff --git a/webcit/fmt_date.c b/webcit/fmt_date.c index 55b9897c8..2c7c9f6fd 100644 --- a/webcit/fmt_date.c +++ b/webcit/fmt_date.c @@ -1,48 +1,48 @@ /* * $Id$ - * - * Miscellaneous routines */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +/** + * \defgroup FormatDates Miscellaneous routines formating dates + * \ingroup Calendaring + */ +/*@{*/ #include "webcit.h" #include "webserver.h" -typedef unsigned char byte; +typedef unsigned char byte; /**< a byte. */ -#define FALSE 0 -#define TRUE 1 +#define FALSE 0 /**< no. */ +#define TRUE 1 /**< yes. */ -char *ascmonths[] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; +/** + * \brief Wrapper around strftime() or strftime_l() + * depending upon how our build is configured. + * + * \param s String target buffer + * \param max Maximum size of string target buffer + * \param format strftime() format + * \param tm Input date/time + */ +size_t wc_strftime(char *s, size_t max, const char *format, const struct tm *tm) +{ +#ifdef ENABLE_NLS + if (wc_locales[WC->selected_language] == NULL) { + return strftime(s, max, format, tm); + } + else { + return strftime_l(s, max, format, tm, wc_locales[WC->selected_language]); + } +#else + return strftime(s, max, format, tm); +#endif +} -char *ascdays[] = { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" -}; -/* - * Format a date/time stamp for output +/** + * \brief Format a date/time stamp for output + * \param buf the output buffer + * \param thetime time to convert to string + * \param brief do we want compact view????? */ void fmt_date(char *buf, time_t thetime, int brief) { @@ -68,53 +68,32 @@ void fmt_date(char *buf, time_t thetime, int brief) if (brief) { + /** If date == today, show only the time */ if ((tm.tm_year == today_tm.tm_year) &&(tm.tm_mon == today_tm.tm_mon) &&(tm.tm_mday == today_tm.tm_mday)) { - if (!strcasecmp(calhourformat, "24")) { - sprintf(buf, "%2d:%02d", - tm.tm_hour, tm.tm_min - ); - } - else { - sprintf(buf, "%2d:%02d%s", - hour, tm.tm_min, - ((tm.tm_hour >= 12) ? "pm" : "am") - ); - } + wc_strftime(buf, 32, "%l:%M%p", &tm); + } + /** Otherwise, for messages up to 6 months old, show the + * month and day, and the time */ + else if (today_timet - thetime < 15552000) { + wc_strftime(buf, 32, "%b %d %l:%M%p", &tm); } + /** older than 6 months, show only the date */ else { - sprintf(buf, "%s %d %d", - ascmonths[tm.tm_mon], - tm.tm_mday, - tm.tm_year + 1900 - ); + wc_strftime(buf, 32, "%b %d %Y", &tm); } } else { - if (!strcasecmp(calhourformat, "24")) { - sprintf(buf, "%s %d %d %2d:%02d", - ascmonths[tm.tm_mon], - tm.tm_mday, - tm.tm_year + 1900, - tm.tm_hour, tm.tm_min - ); - } - else { - sprintf(buf, "%s %d %d %2d:%02d%s", - ascmonths[tm.tm_mon], - tm.tm_mday, - tm.tm_year + 1900, - hour, tm.tm_min, ((tm.tm_hour >= 12) ? "pm" : "am") - ); - } + wc_strftime(buf, 32, "%c", &tm); } } - -/* - * Format TIME ONLY for output +/** + * \brief Format TIME ONLY for output + * \param buf the output buffer + * \param thetime time to format into buf */ void fmt_time(char *buf, time_t thetime) { @@ -147,24 +126,100 @@ void fmt_time(char *buf, time_t thetime) -/* - * Format a date/time stamp to the format used in HTTP headers +/** + * \brief Break down the timestamp used in HTTP headers + * Should read rfc1123 and rfc850 dates OK + * \todo FIXME won't read asctime + * Doesn't understand timezone, but we only should be using GMT/UTC anyway + * \param buf time to parse + * \return the time found in buf */ -void httpdate(char *buf, time_t thetime) +time_t httpdate_to_timestamp(char *buf) { - struct tm *tm; - - buf[0] = 0; - tm = localtime(&thetime); - - sprintf(buf, "%s, %02d %s %4d %02d:%02d:%02d", - ascdays[tm->tm_wday], - tm->tm_mday, - ascmonths[tm->tm_mon], - tm->tm_year + 1900, tm->tm_hour, tm->tm_min, tm->tm_sec); + time_t t = 0; + struct tm tt; + char *c; + char tz[256]; + + /** Skip day of week, to number */ + for (c = buf; *c != ' '; c++) + ; + c++; + + /* Get day of month */ + tt.tm_mday = atoi(c); + for (; *c != ' ' && *c != '-'; c++); + c++; + + /** Get month */ + switch (*c) { + case 'A': /** April, August */ + tt.tm_mon = (c[1] == 'p') ? 3 : 7; + break; + case 'D': /** December */ + tt.tm_mon = 11; + break; + case 'F': /** February */ + tt.tm_mon = 1; + break; + case 'M': /** March, May */ + tt.tm_mon = (c[2] == 'r') ? 2 : 4; + break; + case 'J': /** January, June, July */ + tt.tm_mon = (c[2] == 'n') ? ((c[1] == 'a') ? 0 : 5) : 6; + break; + case 'N': /** November */ + tt.tm_mon = 10; + break; + case 'O': /** October */ + tt.tm_mon = 9; + break; + case 'S': /** September */ + tt.tm_mon = 8; + break; + default: + return 42; + break; /** NOTREACHED */ + } + c += 4; + + tt.tm_year = 0; + /** Get year */ + tt.tm_year = atoi(c); + for (; *c != ' '; c++); + c++; + if (tt.tm_year >= 1900) + tt.tm_year -= 1900; + + /** Get hour */ + tt.tm_hour = atoi(c); + for (; *c != ':'; c++); + c++; + + /** Get minute */ + tt.tm_min = atoi(c); + for (; *c != ':'; c++); + c++; + + /** Get second */ + tt.tm_sec = atoi(c); + for (; *c && *c != ' '; c++); + + /** Got everything; let's go */ + /** First, change to UTC */ + if (getenv("TZ")) + sprintf(tz, "TZ=%s", getenv("TZ")); + else + strcpy(tz, "TZ="); + putenv("TZ=UTC"); + tzset(); + t = mktime(&tt); + putenv(tz); + tzset(); + return t; } - +/*@}*/