很久以前像 youtube 一样实现

Implements time ago like youtube

如何区分4周前和1个月前?我在 android 上为它编写测试代码时遇到了问题。

我认为这取决于我测试的日期。我觉得对吗?如果我的意见是对的,那我怎么才能做好或通过测试代码呢?

我通过测试代码的一个想法是现在保留测试日期。我有什么想法吗?


抱歉,我觉得我的问题不清楚。我的部分代码在这里。

assertEquals("a month ago", timeAgoWithAddedValue(Calendar.MONTH, -1));

private String timeAgoWithAddedValue(int field, int value) {
    Calendar cal = Calendar.getInstance();
    cal.add(field, value);
    return timeAgo(cal.getTime());
}

public static final long WEEK_UNIT = DAY_UNIT * 7;
public static final long MONTH_UNIT = 2629746000L; // I found this value online, 1 Gregorian month -> ms
public static final long YEAR_UNIT = 31556952000L; // I found this value online, 1 Gregorian year -> ms

public String timeAgo(Date date) {
        long now = Calendar.getInstance().getTimeInMillis();
        long sinceNowInMillis = now - date.getTime();

        ...
        if (sinceNowInMillis < MONTH_UNIT) {
            long weeks = sinceNowInMillis / WEEK_UNIT;
            // return proper ago string with weeks
        }

        if (sinceNowInMillis < YEAR_UNIT) {
            long months = sinceNowInMillis / MONTH_UNIT;
            // return proper ago string with months
        }
        ...
}

我几个月前写的代码,当时就成功了。但是今天测试代码失败了。因为代码期望 4 weeks ago 而不是。我想知道我的代码是错误的还是问题取决于一周的长度所以这是自然问题?

获取以下函数:

  public static String millisToLongDHMS(long duration) {
  if (duration > 0) {
     duration = new Date().getTime() - duration;
  }
  if (duration < 0) {
     duration = 0;
  }

  StringBuffer res = new StringBuffer();
  long temp = 0;
  if (duration >= ONE_SECOND) {
     temp = duration / ONE_DAY;
     if (temp > 0) {
        duration -= temp * ONE_DAY;
        res.append(temp).append(" day").append(temp > 1 ? "s" : "")
                .append(duration >= ONE_MINUTE ? ", " : "");
     }

     temp = duration / ONE_HOUR;
     if (temp > 0) {
        duration -= temp * ONE_HOUR;
        res.append(temp).append(" hour").append(temp > 1 ? "s" : "")
                .append(duration >= ONE_MINUTE ? ", " : "");
     }

     temp = duration / ONE_MINUTE;
     if (temp > 0) {
        duration -= temp * ONE_MINUTE;
        res.append(temp).append(" min").append(temp > 1 ? "s" : "");
     }

     if (!res.toString().equals("") && duration >= ONE_SECOND) {
        res.append(" and ");
     }

     temp = duration / ONE_SECOND;
     if (temp > 0) {
        res.append(temp).append(" sec").append(temp > 1 ? "s" : "");
     }
     res.append(" ago");
     return res.toString();
  } else {
     return "Just Now";
  }
 }

更新

你可以使用我的另一个功能:

  public static String getTimeAgo(long time) {
     if (time < 1000000000000L) {
     // if timestamp given in seconds, convert to millis
     time *= 1000;
  }

  long now = System.currentTimeMillis();
  if (time > now || time <= 0) {
     return null;
  }

  // TODO: localize
  final long diff = now - time;
  if (diff < MINUTE_MILLIS) {
     return "just now";
  } else if (diff < 2 * MINUTE_MILLIS) {
     return "a minute ago";
  } else if (diff < 50 * MINUTE_MILLIS) {
     return diff / MINUTE_MILLIS + " min ago";
  } else if (diff < 90 * MINUTE_MILLIS) {
     return "an hour ago";
  } else if (diff < 24 * HOUR_MILLIS) {
     return diff / HOUR_MILLIS + " hours ago";
  } else if (diff < 48 * HOUR_MILLIS) {
     return "yesterday";
  } else {
     return diff / DAY_MILLIS + " days ago";
  }
 }

您可以使用这行代码来实现您的目标,而无需在您的项目中使用任何库

 DateUtils.getRelativeTimeSpanString(timestamp, new Date().getTime(), DateUtils.MINUTE_IN_MILLIS)

这里timestamp是很长的时间毫秒

在此处阅读更多文档 DateUtils

例如 如果您将时间戳作为 1482739673913 传递,您将得到 6 minutes ago

如果时间戳是 1482582128877 你会得到 2 days ago

我弄清楚是什么问题了。这取决于一个月中的几天。

一个月中的天数不一样(Oct:31, Nov:30, Dec:31..)但是我在代码中计算它时使用的是常量。

我的意思是,如果月份有 31 天,那么我代码中的 sinceNowInMillis 小于 MONTH_UNIT。所以按照我的代码,结果是“4 周前”。因为我使用 Calendar.add(Calender.MONTH, -1).

计算了目标日期

另一方面,如果月份有 30 天或更少,我代码中的 sinceNowInMillis 大于 MONTH_UNIT。所以按照我的代码,结果是“1 个月前”。