Documentation: refactor common operations into variables
[gitweb.git] / date.c
diff --git a/date.c b/date.c
index f64bbeb8237acceaca565c010fdf50b3385ead8f..59dfe579c6a0c65abe0a34052cdbf16643afbfb8 100644 (file)
--- a/date.c
+++ b/date.c
@@ -144,8 +144,8 @@ void show_date_relative(unsigned long time, int tz,
                if (months) {
                        struct strbuf sb = STRBUF_INIT;
                        strbuf_addf(&sb, Q_("%lu year", "%lu years", years), years);
-                       /* TRANSLATORS: "%s" is "<n> years" */
                        strbuf_addf(timebuf,
+                                /* TRANSLATORS: "%s" is "<n> years" */
                                 Q_("%s, %lu month ago", "%s, %lu months ago", months),
                                 sb.buf, months);
                        strbuf_release(&sb);
@@ -200,7 +200,16 @@ const char *show_date(unsigned long time, int tz, enum date_mode mode)
                                tm->tm_mday,
                                tm->tm_hour, tm->tm_min, tm->tm_sec,
                                tz);
-       else if (mode == DATE_RFC2822)
+       else if (mode == DATE_ISO8601_STRICT) {
+               char sign = (tz >= 0) ? '+' : '-';
+               tz = abs(tz);
+               strbuf_addf(&timebuf, "%04d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d",
+                               tm->tm_year + 1900,
+                               tm->tm_mon + 1,
+                               tm->tm_mday,
+                               tm->tm_hour, tm->tm_min, tm->tm_sec,
+                               sign, tz / 100, tz % 100);
+       } else if (mode == DATE_RFC2822)
                strbuf_addf(&timebuf, "%.3s, %d %.3s %d %02d:%02d:%02d %+05d",
                        weekday_names[tm->tm_wday], tm->tm_mday,
                        month_names[tm->tm_mon], tm->tm_year + 1900,
@@ -385,7 +394,7 @@ static int is_date(int year, int month, int day, struct tm *now_tm, time_t now,
                 * sense to specify timestamp way into the future.  Make
                 * sure it is not later than ten days from now...
                 */
-               if (now + 10*24*3600 < specified)
+               if ((specified != -1) && (now + 10*24*3600 < specified))
                        return 0;
                tm->tm_mon = r->tm_mon;
                tm->tm_mday = r->tm_mday;
@@ -605,7 +614,7 @@ static int match_tz(const char *date, int *offp)
        return end - date;
 }
 
-static int date_string(unsigned long date, int offset, char *buf, int len)
+static void date_string(unsigned long date, int offset, struct strbuf *buf)
 {
        int sign = '+';
 
@@ -613,7 +622,7 @@ static int date_string(unsigned long date, int offset, char *buf, int len)
                offset = -offset;
                sign = '-';
        }
-       return snprintf(buf, len, "%lu %c%02d%02d", date, sign, offset / 60, offset % 60);
+       strbuf_addf(buf, "%lu %c%02d%02d", date, sign, offset / 60, offset % 60);
 }
 
 /*
@@ -696,8 +705,14 @@ int parse_date_basic(const char *date, unsigned long *timestamp, int *offset)
 
        /* mktime uses local timezone */
        *timestamp = tm_to_time_t(&tm);
-       if (*offset == -1)
-               *offset = ((time_t)*timestamp - mktime(&tm)) / 60;
+       if (*offset == -1) {
+               time_t temp_time = mktime(&tm);
+               if ((time_t)*timestamp > temp_time) {
+                       *offset = ((time_t)*timestamp - temp_time) / 60;
+               } else {
+                       *offset = -(int)((temp_time - (time_t)*timestamp) / 60);
+               }
+       }
 
        if (*timestamp == -1)
                return -1;
@@ -707,13 +722,36 @@ int parse_date_basic(const char *date, unsigned long *timestamp, int *offset)
        return 0; /* success */
 }
 
-int parse_date(const char *date, char *result, int maxlen)
+int parse_expiry_date(const char *date, unsigned long *timestamp)
+{
+       int errors = 0;
+
+       if (!strcmp(date, "never") || !strcmp(date, "false"))
+               *timestamp = 0;
+       else if (!strcmp(date, "all") || !strcmp(date, "now"))
+               /*
+                * We take over "now" here, which usually translates
+                * to the current timestamp.  This is because the user
+                * really means to expire everything she has done in
+                * the past, and by definition reflogs are the record
+                * of the past, and there is nothing from the future
+                * to be kept.
+                */
+               *timestamp = ULONG_MAX;
+       else
+               *timestamp = approxidate_careful(date, &errors);
+
+       return errors;
+}
+
+int parse_date(const char *date, struct strbuf *result)
 {
        unsigned long timestamp;
        int offset;
        if (parse_date_basic(date, &timestamp, &offset))
                return -1;
-       return date_string(timestamp, offset, result, maxlen);
+       date_string(timestamp, offset, result);
+       return 0;
 }
 
 enum date_mode parse_date_format(const char *format)
@@ -723,6 +761,9 @@ enum date_mode parse_date_format(const char *format)
        else if (!strcmp(format, "iso8601") ||
                 !strcmp(format, "iso"))
                return DATE_ISO8601;
+       else if (!strcmp(format, "iso8601-strict") ||
+                !strcmp(format, "iso-strict"))
+               return DATE_ISO8601_STRICT;
        else if (!strcmp(format, "rfc2822") ||
                 !strcmp(format, "rfc"))
                return DATE_RFC2822;
@@ -738,7 +779,7 @@ enum date_mode parse_date_format(const char *format)
                die("unknown date format %s", format);
 }
 
-void datestamp(char *buf, int bufsize)
+void datestamp(struct strbuf *out)
 {
        time_t now;
        int offset;
@@ -748,7 +789,7 @@ void datestamp(char *buf, int bufsize)
        offset = tm_to_time_t(localtime(&now)) - now;
        offset /= 60;
 
-       date_string(now, offset, buf, bufsize);
+       date_string(now, offset, out);
 }
 
 /*
@@ -881,7 +922,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
        const char *end = date;
        int i;
 
-       while (isalpha(*++end));
+       while (isalpha(*++end))
                ;
 
        for (i = 0; i < 12; i++) {