提交 f1e9c548 编写于 作者: M Michael J Gruber 提交者: Junio C Hamano

date: avoid "X years, 12 months" in relative dates

When relative dates are more than about a year ago, we start
writing them as "Y years, M months".  At the point where we
calculate Y and M, we have the time delta specified as a
number of days. We calculate these integers as:

  Y = days / 365
  M = (days % 365 + 15) / 30

This rounds days in the latter half of a month up to the
nearest month, so that day 16 is "1 month" (or day 381 is "1
year, 1 month").

We don't round the year at all, though, meaning we can end
up with "1 year, 12 months", which is silly; it should just
be "2 years".

Implement this differently with months of size

  onemonth = 365/12

so that

  totalmonths = (long)( (days + onemonth/2)/onemonth )
  years = totalmonths / 12
  months = totalmonths % 12

In order to do this without floats, we write the first formula as

  totalmonths = (days*12*2 + 365) / (365*2)

Tests and inspiration by Jeff King.
Helped-by: NJeff King <peff@peff.net>
Signed-off-by: NMichael J Gruber <git@drmicha.warpmail.net>
Signed-off-by: NJunio C Hamano <gitster@pobox.com>
上级 87b50542
...@@ -129,8 +129,9 @@ const char *show_date_relative(unsigned long time, int tz, ...@@ -129,8 +129,9 @@ const char *show_date_relative(unsigned long time, int tz,
} }
/* Give years and months for 5 years or so */ /* Give years and months for 5 years or so */
if (diff < 1825) { if (diff < 1825) {
unsigned long years = diff / 365; unsigned long totalmonths = (diff * 12 * 2 + 365) / (365 * 2);
unsigned long months = (diff % 365 + 15) / 30; unsigned long years = totalmonths / 12;
unsigned long months = totalmonths % 12;
int n; int n;
n = snprintf(timebuf, timebuf_size, "%lu year%s", n = snprintf(timebuf, timebuf_size, "%lu year%s",
years, (years > 1 ? "s" : "")); years, (years > 1 ? "s" : ""));
......
...@@ -25,6 +25,7 @@ check_show 37500000 '1 year, 2 months ago' ...@@ -25,6 +25,7 @@ check_show 37500000 '1 year, 2 months ago'
check_show 55188000 '1 year, 9 months ago' check_show 55188000 '1 year, 9 months ago'
check_show 630000000 '20 years ago' check_show 630000000 '20 years ago'
check_show 31449600 '12 months ago' check_show 31449600 '12 months ago'
check_show 62985600 '2 years ago'
check_parse() { check_parse() {
echo "$1 -> $2" >expect echo "$1 -> $2" >expect
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册