-1

I want to display how long ago something happened. For example

  • 24 minutes ago //discard seconds
  • 3 hours ago //discard minutes
  • 5 days ago // discard hours
  • 3 weeks ago // discard days

All I have is a long timestamp and so I am free to use java.util.Date or jodatime or whatever other Time android uses. I am having such a hard time getting it right. I try to use jodatime with minus but I can't quite get the right answer yet.

One approach is for me to do the whole thing myself: first subtract my timestamp from now and then do some arithmetics. But I would rather avoid that route if possible.

learner
  • 11,490
  • 26
  • 97
  • 169

2 Answers2

2

Android provides the utility class DateUtils for all such requirements. If I've understood your requirement correctly, you need to use the DateUtils#getRelativeTimeSpanString() utility method.

From the docs for

CharSequence getRelativeTimeSpanString (long time, long now, long minResolution)

Returns a string describing 'time' as a time relative to 'now'. Time spans in the past are formatted like "42 minutes ago". Time spans in the future are formatted like "In 42 minutes".

You'll be passing your timestamp as time and System.currentTimeMillis() as now. The minResolution specifies the minimum timespan to report.

For example, a time 3 seconds in the past will be reported as "0 minutes ago" if this is set to MINUTE_IN_MILLIS. Pass one of 0, MINUTE_IN_MILLIS, HOUR_IN_MILLIS, DAY_IN_MILLIS, WEEK_IN_MILLIS

Ravi K Thapliyal
  • 51,095
  • 9
  • 76
  • 89
0

You can use the following code :

   public class TimeAgo {
    public static final List<Long> times = Arrays.asList(
            TimeUnit.DAYS.toMillis(365),
            TimeUnit.DAYS.toMillis(30),
            TimeUnit.DAYS.toMillis(1),
            TimeUnit.HOURS.toMillis(1),
            TimeUnit.MINUTES.toMillis(1),
            TimeUnit.SECONDS.toMillis(1) );
    public static final List<String> timesString = Arrays.asList("year","month","day","hour","minute","second");

    public static String toDuration(long duration) {

        StringBuffer res = new StringBuffer();
        for(int i=0;i< Lists.times.size(); i++) {
            Long current = Lists.times.get(i);
            long temp = duration/current;
            if(temp>0) {
                res.append(temp).append(" ").append( Lists.timesString.get(i) ).append(temp > 1 ? "s" : "").append(" ago");
                break;
            }
        }
        if("".equals(res.toString()))
            return "0 second ago";
        else
            return res.toString();
    }
}

Just call the toDuration() method with your long timestamp as parameter.

You can also use DateUtils.getRelativeTimeSpanString() . You can read the documentation here Date Utils

Akash Singh
  • 748
  • 1
  • 6
  • 14
  • There isn't exactly 365 days in a year or exactly 30 days in a month – MadProgrammer Oct 17 '15 at 20:39
  • that won't make any big difference. anyways the OP is showing approximate time "ago". So that won't make much a difference. Btw you can always use DateUtils#getRelativeTimeSpanString() – Akash Singh Oct 18 '15 at 03:24
  • It depends on how you're using the algorithm, the more time that pasts, the worst it will get, given that there are better mechanisms readily available, all it does is propagates a bad idea - I'm very particular about date/time calculations ;) – MadProgrammer Oct 18 '15 at 04:05