From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Cc: "Tom Xue" <tomxue0126@gmail.com>,
"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>,
"Thomas Rast" <trast@student.ethz.ch>,
"Jiang Xin" <worldhello.net@gmail.com>
Subject: [PATCH 1/2] date: refactor the relative date logic from presentation
Date: Thu, 16 Aug 2012 16:02:02 -0700 [thread overview]
Message-ID: <1345158123-22189-2-git-send-email-gitster@pobox.com> (raw)
In-Reply-To: <1345158123-22189-1-git-send-email-gitster@pobox.com>
Separate the logic to decide which presentation (e.g. "N months") to
use based on the length of the time from the present and actual
presentation (i.e. "strbuf_addf()"). This is not strictly needed
but will make the next step easier to read.
The format strings lost N_() markings along the way; help from the
i18n folks to come up with the best and sane way to mark them up is
very much appreciated.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
date.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 127 insertions(+), 43 deletions(-)
diff --git a/date.c b/date.c
index 57331ed..b6ff04e 100644
--- a/date.c
+++ b/date.c
@@ -86,78 +86,162 @@ static int local_tzoffset(unsigned long time)
return offset * eastwest;
}
-void show_date_relative(unsigned long time, int tz,
- const struct timeval *now,
- struct strbuf *timebuf)
+enum relative_style {
+ rd_seconds = 0, rd_minutes, rd_hours, rd_days, rd_weeks, rd_months, rd_years
+};
+
+struct relative_date {
+ int seconds;
+ int minutes;
+ int hours;
+ int days;
+ int weeks;
+ int months;
+ int years;
+};
+
+static enum relative_style format_relative_date(unsigned long diff,
+ struct relative_date *rd)
{
- unsigned long diff;
- if (now->tv_sec < time) {
- strbuf_addstr(timebuf, _("in the future"));
- return;
- }
- diff = now->tv_sec - time;
+ memset(rd, 0, sizeof(*rd));
if (diff < 90) {
- strbuf_addf(timebuf,
- Q_("%lu second ago", "%lu seconds ago", diff), diff);
- return;
+ rd->seconds = diff;
+ return rd_seconds;
}
/* Turn it into minutes */
diff = (diff + 30) / 60;
if (diff < 90) {
- strbuf_addf(timebuf,
- Q_("%lu minute ago", "%lu minutes ago", diff), diff);
- return;
+ rd->minutes = diff;
+ return rd_minutes;
}
/* Turn it into hours */
diff = (diff + 30) / 60;
if (diff < 36) {
- strbuf_addf(timebuf,
- Q_("%lu hour ago", "%lu hours ago", diff), diff);
- return;
+ rd->hours = diff;
+ return rd_hours;
}
/* We deal with number of days from here on */
diff = (diff + 12) / 24;
if (diff < 14) {
- strbuf_addf(timebuf,
- Q_("%lu day ago", "%lu days ago", diff), diff);
- return;
+ rd->days = diff;
+ return rd_days;
}
/* Say weeks for the past 10 weeks or so */
if (diff < 70) {
- strbuf_addf(timebuf,
- Q_("%lu week ago", "%lu weeks ago", (diff + 3) / 7),
- (diff + 3) / 7);
- return;
+ rd->weeks = (diff + 3) / 7;
+ return rd_weeks;
}
/* Say months for the past 12 months or so */
if (diff < 365) {
- strbuf_addf(timebuf,
- Q_("%lu month ago", "%lu months ago", (diff + 15) / 30),
- (diff + 15) / 30);
- return;
+ rd->months = (diff + 15) / 30;
+ return rd_months;
}
/* Give years and months for 5 years or so */
if (diff < 1825) {
unsigned long totalmonths = (diff * 12 * 2 + 365) / (365 * 2);
- unsigned long years = totalmonths / 12;
- unsigned long months = totalmonths % 12;
- if (months) {
+ rd->years = totalmonths / 12;
+ rd->months = totalmonths % 12;
+ return rd_years;
+ }
+ /* Otherwise, just years. Centuries is probably overkill. */
+ rd->years = (diff + 183) / 365;
+ return rd_years;
+}
+
+void show_date_relative(unsigned long time, int tz,
+ const struct timeval *now,
+ struct strbuf *timebuf)
+{
+ unsigned long diff;
+ struct relative_date rd;
+ int pf = 0; /* past or future */
+
+ struct {
+ struct { const char *s, *p; } msg_seconds;
+ struct { const char *s, *p; } msg_minutes;
+ struct { const char *s, *p; } msg_hours;
+ struct { const char *s, *p; } msg_days;
+ struct { const char *s, *p; } msg_weeks;
+ struct { const char *s, *p; } msg_months;
+ struct { const char *s, *p; } msg_years_only;
+ struct { const char *s, *p; } msg_years_months;
+ struct { const char *s, *p; } msg_years;
+ } msg[1] = {
+ {
+ { "%lu second ago", "%lu seconds ago" },
+ { "%lu minute ago", "%lu minutes ago" },
+ { "%lu hour ago", "%lu hours ago" },
+ { "%lu day ago", "%lu days ago" },
+ { "%lu week ago", "%lu weeks ago" },
+ { "%lu month ago", "%lu months ago" },
+ { "%lu year", "%lu years" },
+ {
+ /* TRANSLATORS: "%s" is "<n> years" */
+ "%s, %lu month ago",
+ /* TRANSLATORS: "%s" is "<n> years" */
+ "%s, %lu months ago"
+ },
+ { "%lu year ago", "%lu years ago" },
+ }
+ };
+
+ if (now->tv_sec < time) {
+ strbuf_addstr(timebuf, _("in the future"));
+ return;
+ }
+ diff = now->tv_sec - time;
+
+ switch (format_relative_date(diff, &rd)) {
+ case rd_seconds:
+ strbuf_addf(timebuf,
+ Q_(msg[pf].msg_seconds.s, msg[pf].msg_seconds.p,
+ rd.seconds), rd.seconds);
+ break;
+ case rd_minutes:
+ strbuf_addf(timebuf,
+ Q_(msg[pf].msg_minutes.s, msg[pf].msg_minutes.p,
+ rd.minutes), rd.minutes);
+ break;
+ case rd_hours:
+ strbuf_addf(timebuf,
+ Q_(msg[pf].msg_hours.s, msg[pf].msg_hours.p,
+ rd.hours), rd.hours);
+ break;
+ case rd_days:
+ strbuf_addf(timebuf,
+ Q_(msg[pf].msg_days.s, msg[pf].msg_days.p,
+ rd.days), rd.days);
+ break;
+ case rd_weeks:
+ strbuf_addf(timebuf,
+ Q_(msg[pf].msg_weeks.s, msg[pf].msg_weeks.p,
+ rd.weeks), rd.weeks);
+ break;
+ case rd_months:
+ strbuf_addf(timebuf,
+ Q_(msg[pf].msg_months.s, msg[pf].msg_months.p,
+ rd.months), rd.months);
+ break;
+
+ case rd_years:
+ if (rd.months) {
struct strbuf sb = STRBUF_INIT;
- strbuf_addf(&sb, Q_("%lu year", "%lu years", years), years);
- /* TRANSLATORS: "%s" is "<n> years" */
+ strbuf_addf(&sb, Q_(msg[pf].msg_years_only.s,
+ msg[pf].msg_years_only.p,
+ rd.years), rd.years);
strbuf_addf(timebuf,
- Q_("%s, %lu month ago", "%s, %lu months ago", months),
- sb.buf, months);
+ Q_(msg[pf].msg_years_months.s,
+ msg[pf].msg_years_months.p,
+ rd.months),
+ sb.buf, rd.months);
strbuf_release(&sb);
- } else
+ } else {
strbuf_addf(timebuf,
- Q_("%lu year ago", "%lu years ago", years), years);
- return;
+ Q_(msg[pf].msg_years.s, msg[pf].msg_years.p,
+ rd.years), rd.years);
+ }
+ break;
}
- /* Otherwise, just years. Centuries is probably overkill. */
- strbuf_addf(timebuf,
- Q_("%lu year ago", "%lu years ago", (diff + 183) / 365),
- (diff + 183) / 365);
}
const char *show_date(unsigned long time, int tz, enum date_mode mode)
--
1.7.12.rc3.69.gaf0166d
next prev parent reply other threads:[~2012-08-16 23:02 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-05 16:18 [PATCH] Can show relative date of the commit with future timestamp Tom Xue
2012-07-05 17:26 ` Junio C Hamano
[not found] ` <CA+P7oHuCbeJ5shfL5OVhSypgygzmQwn-RGPD8UvFUFuqnoV9fA@mail.gmail.com>
2012-07-06 8:15 ` Jundong Xue
2012-08-20 22:51 ` Junio C Hamano
2012-08-21 9:17 ` Jundong Xue
2012-08-16 23:02 ` [PATCH 0/2] relative future date Junio C Hamano
2012-08-16 23:02 ` Junio C Hamano [this message]
2012-08-16 23:02 ` [PATCH 2/2] date: show relative dates in the future Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1345158123-22189-2-git-send-email-gitster@pobox.com \
--to=gitster@pobox.com \
--cc=avarab@gmail.com \
--cc=git@vger.kernel.org \
--cc=tomxue0126@gmail.com \
--cc=trast@student.ethz.ch \
--cc=worldhello.net@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).