summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin-cat-file.c2
-rw-r--r--cache.h2
-rw-r--r--commit.c4
-rw-r--r--date.c63
4 files changed, 59 insertions, 12 deletions
diff --git a/builtin-cat-file.c b/builtin-cat-file.c
index 7a6fa56e93..6c16bfa1ae 100644
--- a/builtin-cat-file.c
+++ b/builtin-cat-file.c
@@ -54,7 +54,7 @@ static void pprint_tag(const unsigned char *sha1, const char *buf, unsigned long
write_or_die(1, tagger, sp - tagger);
date = strtoul(sp, &ep, 10);
tz = strtol(ep, NULL, 10);
- sp = show_date(date, tz);
+ sp = show_date(date, tz, 0);
write_or_die(1, sp, strlen(sp));
xwrite(1, "\n", 1);
break;
diff --git a/cache.h b/cache.h
index 1f212d77a4..ccb83a1fd5 100644
--- a/cache.h
+++ b/cache.h
@@ -286,7 +286,7 @@ extern void *read_object_with_reference(const unsigned char *sha1,
unsigned long *size,
unsigned char *sha1_ret);
-const char *show_date(unsigned long time, int timezone);
+const char *show_date(unsigned long time, int timezone, int relative);
const char *show_rfc2822_date(unsigned long time, int timezone);
int parse_date(const char *date, char *buf, int bufsize);
void datestamp(char *buf, int bufsize);
diff --git a/commit.c b/commit.c
index 00bc3de22e..c3ff9b4175 100644
--- a/commit.c
+++ b/commit.c
@@ -507,14 +507,14 @@ static int add_user_info(const char *what, enum cmit_fmt fmt, char *buf, const c
}
switch (fmt) {
case CMIT_FMT_MEDIUM:
- ret += sprintf(buf + ret, "Date: %s\n", show_date(time, tz));
+ ret += sprintf(buf + ret, "Date: %s\n", show_date(time, tz, 0));
break;
case CMIT_FMT_EMAIL:
ret += sprintf(buf + ret, "Date: %s\n",
show_rfc2822_date(time, tz));
break;
case CMIT_FMT_FULLER:
- ret += sprintf(buf + ret, "%sDate: %s\n", what, show_date(time, tz));
+ ret += sprintf(buf + ret, "%sDate: %s\n", what, show_date(time, tz, 0));
break;
default:
/* notin' */
diff --git a/date.c b/date.c
index d780846b66..e387dcd397 100644
--- a/date.c
+++ b/date.c
@@ -37,6 +37,16 @@ static const char *weekday_names[] = {
"Sundays", "Mondays", "Tuesdays", "Wednesdays", "Thursdays", "Fridays", "Saturdays"
};
+static time_t gm_time_t(unsigned long time, int tz)
+{
+ int minutes;
+
+ minutes = tz < 0 ? -tz : tz;
+ minutes = (minutes / 100)*60 + (minutes % 100);
+ minutes = tz < 0 ? -minutes : minutes;
+ return time + minutes * 60;
+}
+
/*
* The "tz" thing is passed in as this strange "decimal parse of tz"
* thing, which means that tz -0100 is passed in as the integer -100,
@@ -44,21 +54,58 @@ static const char *weekday_names[] = {
*/
static struct tm *time_to_tm(unsigned long time, int tz)
{
- time_t t;
- int minutes;
-
- minutes = tz < 0 ? -tz : tz;
- minutes = (minutes / 100)*60 + (minutes % 100);
- minutes = tz < 0 ? -minutes : minutes;
- t = time + minutes * 60;
+ time_t t = gm_time_t(time, tz);
return gmtime(&t);
}
-const char *show_date(unsigned long time, int tz)
+const char *show_date(unsigned long time, int tz, int relative)
{
struct tm *tm;
static char timebuf[200];
+ if (relative) {
+ unsigned long diff;
+ time_t t = gm_time_t(time, tz);
+ struct timeval now;
+ gettimeofday(&now, NULL);
+ if (now.tv_sec < t)
+ return "in the future";
+ diff = now.tv_sec - t;
+ if (diff < 90) {
+ snprintf(timebuf, sizeof(timebuf), "%lu seconds ago", diff);
+ return timebuf;
+ }
+ /* Turn it into minutes */
+ diff = (diff + 30) / 60;
+ if (diff < 90) {
+ snprintf(timebuf, sizeof(timebuf), "%lu minutes ago", diff);
+ return timebuf;
+ }
+ /* Turn it into hours */
+ diff = (diff + 30) / 60;
+ if (diff < 36) {
+ snprintf(timebuf, sizeof(timebuf), "%lu hours ago", diff);
+ return timebuf;
+ }
+ /* We deal with number of days from here on */
+ diff = (diff + 12) / 24;
+ if (diff < 14) {
+ snprintf(timebuf, sizeof(timebuf), "%lu days ago", diff);
+ return timebuf;
+ }
+ /* Say weeks for the past 10 weeks or so */
+ if (diff < 70) {
+ snprintf(timebuf, sizeof(timebuf), "%lu weeks ago", (diff + 3) / 7);
+ return timebuf;
+ }
+ /* Say months for the past 12 months or so */
+ if (diff < 360) {
+ snprintf(timebuf, sizeof(timebuf), "%lu months ago", (diff + 15) / 30);
+ return timebuf;
+ }
+ /* Else fall back on absolute format.. */
+ }
+
tm = time_to_tm(time, tz);
if (!tm)
return NULL;