Calculate Relative Time also known as “Time Ago” In Java

Time Ago Generation Days, Hours, Seconds

Here is an example of how you can calculate relative time also know as “time ago” in java. This will return the time difference between two dates in years, months, weeks, days, hours, minutes or seconds depending on the time interval between the two times.

  • X seconds will be printed if the time interval is between 0 and 60 seconds
  • X minutes will be printed if the time interval is between 60 seconds and 60 minutes
  • X hours will be printed if the time interval is between 60 minutes and 24 hours
  • X days will be printed if the time interval is between 24 hours and 1 week
  • X weeks will be printed if the time interval is between 1 week and 30 days
  • X months will be printed if the time interval is between 30 days and 365 days
  • X years will be printed if the time interval is between 365 year and …
Be warned that we use 30 days for a month and that results may vary depending on what month you are currently in.

Time Ago Class

We created a class that will convert a long which is the time difference of two date times to be formatted as the time ago format. As a convenience we also added a method that will take two dates and calculate the difference by themselves. The maxLevel parameter takes an int indicating how many levels your output prints. e.g.: when you specify level 1 then only the biggest value will be printed.

package com.memorynotfound.time;

import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class TimeAgo {

    public static final Map<String, Long> times = new LinkedHashMap<>();

    static {
        times.put("year", TimeUnit.DAYS.toMillis(365));
        times.put("month", TimeUnit.DAYS.toMillis(30));
        times.put("week", TimeUnit.DAYS.toMillis(7));
        times.put("day", TimeUnit.DAYS.toMillis(1));
        times.put("hour", TimeUnit.HOURS.toMillis(1));
        times.put("minute", TimeUnit.MINUTES.toMillis(1));
        times.put("second", TimeUnit.SECONDS.toMillis(1));
    }

    public static String toRelative(long duration, int maxLevel) {
        StringBuilder res = new StringBuilder();
        int level = 0;
        for (Map.Entry<String, Long> time : times.entrySet()){
            long timeDelta = duration / time.getValue();
            if (timeDelta > 0){
                res.append(timeDelta)
                        .append(" ")
                        .append(time.getKey())
                        .append(timeDelta > 1 ? "s" : "")
                        .append(", ");
                duration -= time.getValue() * timeDelta;
                level++;
            }
            if (level == maxLevel){
                break;
            }
        }
        if ("".equals(res.toString())) {
            return "0 seconds ago";
        } else {
            res.setLength(res.length() - 2);
            res.append(" ago");
            return res.toString();
        }
    }

    public static String toRelative(long duration) {
        return toRelative(duration, times.size());
    }

    public static String toRelative(Date start, Date end){
        assert start.after(end);
        return toRelative(end.getTime() - start.getTime());
    }

    public static String toRelative(Date start, Date end, int level){
        assert start.after(end);
        return toRelative(end.getTime() - start.getTime(), level);
    }
}

Testing

For testing purposes we will print out every possible situation how you can use the TimeAgo class.

package com.memorynotfound.time;

import java.util.Date;
import java.util.concurrent.TimeUnit;

public class TimeAgoProgram {

    private static final long ONE_SECOND = TimeUnit.SECONDS.toMillis(1);
    private static final long ONE_MINUTE = TimeUnit.MINUTES.toMillis(1);
    private static final long ONE_HOUR = TimeUnit.HOURS.toMillis(1);
    private static final long ONE_DAY = TimeUnit.DAYS.toMillis(1);
    private static final long ONE_WEEK = TimeUnit.DAYS.toMillis(7);
    private static final long ONE_MONTH = TimeUnit.DAYS.toMillis(30);
    private static final long ONE_YEAR = TimeUnit.DAYS.toMillis(365);

    private static final int RANDOM = 3521;

    public static void main(String... args){
        System.out.println("Generate time ago from long");
        System.out.println(TimeAgo.toRelative(ONE_SECOND));
        System.out.println(TimeAgo.toRelative(ONE_MINUTE));
        System.out.println(TimeAgo.toRelative(ONE_HOUR));
        System.out.println(TimeAgo.toRelative(ONE_DAY));
        System.out.println(TimeAgo.toRelative(ONE_WEEK));
        System.out.println(TimeAgo.toRelative(ONE_MONTH));
        System.out.println(TimeAgo.toRelative(ONE_YEAR));

        System.out.println("\nGenerate time ago from long with random number");

        System.out.println(TimeAgo.toRelative(ONE_SECOND * RANDOM));
        System.out.println(TimeAgo.toRelative(ONE_MINUTE  * RANDOM));
        System.out.println(TimeAgo.toRelative(ONE_HOUR  * RANDOM));
        System.out.println(TimeAgo.toRelative(ONE_DAY  * RANDOM));
        System.out.println(TimeAgo.toRelative(ONE_WEEK  * RANDOM));
        System.out.println(TimeAgo.toRelative(ONE_MONTH  * RANDOM));
        System.out.println(TimeAgo.toRelative(ONE_YEAR  * RANDOM));

        System.out.println("\nGenerate time ago from long with random number and 2 levels");

        System.out.println(TimeAgo.toRelative(ONE_SECOND * RANDOM, 2));
        System.out.println(TimeAgo.toRelative(ONE_MINUTE  * RANDOM, 2));
        System.out.println(TimeAgo.toRelative(ONE_HOUR  * RANDOM, 2));
        System.out.println(TimeAgo.toRelative(ONE_DAY  * RANDOM, 2));
        System.out.println(TimeAgo.toRelative(ONE_WEEK  * RANDOM, 2));
        System.out.println(TimeAgo.toRelative(ONE_MONTH  * RANDOM, 2));
        System.out.println(TimeAgo.toRelative(ONE_YEAR  * RANDOM, 2));

        System.out.println("\nGenerate time ago from date");

        System.out.println(TimeAgo.toRelative(new Date(), new Date(new Date().getTime() + ONE_SECOND)));
        System.out.println(TimeAgo.toRelative(new Date(), new Date(new Date().getTime() + ONE_MINUTE)));
        System.out.println(TimeAgo.toRelative(new Date(), new Date(new Date().getTime() + ONE_HOUR)));
        System.out.println(TimeAgo.toRelative(new Date(), new Date(new Date().getTime() + ONE_DAY)));
        System.out.println(TimeAgo.toRelative(new Date(), new Date(new Date().getTime() + ONE_WEEK)));
        System.out.println(TimeAgo.toRelative(new Date(), new Date(new Date().getTime() + ONE_MONTH)));
        System.out.println(TimeAgo.toRelative(new Date(), new Date(new Date().getTime() + ONE_YEAR)));

        System.out.println("\nGenerate time ago from date with random number");

        System.out.println(TimeAgo.toRelative(new Date(), new Date(new Date().getTime() + ONE_SECOND * RANDOM)));
        System.out.println(TimeAgo.toRelative(new Date(), new Date(new Date().getTime() + ONE_MINUTE * RANDOM)));
        System.out.println(TimeAgo.toRelative(new Date(), new Date(new Date().getTime() + ONE_HOUR * RANDOM)));
        System.out.println(TimeAgo.toRelative(new Date(), new Date(new Date().getTime() + ONE_DAY * RANDOM)));
        System.out.println(TimeAgo.toRelative(new Date(), new Date(new Date().getTime() + ONE_WEEK * RANDOM)));
        System.out.println(TimeAgo.toRelative(new Date(), new Date(new Date().getTime() + ONE_MONTH * RANDOM)));
        System.out.println(TimeAgo.toRelative(new Date(), new Date(new Date().getTime() + ONE_YEAR * RANDOM)));

        System.out.println("\nGenerate time ago from with random number and 2 levels");

        System.out.println(TimeAgo.toRelative(new Date(), new Date(new Date().getTime() + ONE_SECOND * RANDOM), 2));
        System.out.println(TimeAgo.toRelative(new Date(), new Date(new Date().getTime() + ONE_MINUTE * RANDOM), 2));
        System.out.println(TimeAgo.toRelative(new Date(), new Date(new Date().getTime() + ONE_HOUR * RANDOM), 2));
        System.out.println(TimeAgo.toRelative(new Date(), new Date(new Date().getTime() + ONE_DAY * RANDOM), 2));
        System.out.println(TimeAgo.toRelative(new Date(), new Date(new Date().getTime() + ONE_WEEK * RANDOM), 2));
        System.out.println(TimeAgo.toRelative(new Date(), new Date(new Date().getTime() + ONE_MONTH * RANDOM), 2));
        System.out.println(TimeAgo.toRelative(new Date(), new Date(new Date().getTime() + ONE_YEAR * RANDOM), 2));

    }
}

Here are the test results.

Generate time ago from long
1 second ago
1 minute ago
1 hour ago
1 day ago
1 week ago
1 month ago
1 year ago

Generate time ago from long with random number
58 minutes, 41 seconds ago
2 days, 10 hours, 41 minutes ago
4 months, 3 weeks, 5 days, 17 hours ago
9 years, 7 months, 3 weeks, 5 days ago
67 years, 6 months, 1 week, 5 days ago
289 years, 4 months, 3 weeks, 4 days ago
3521 years ago

Generate time ago from long with random number and 2 levels
58 minutes, 41 seconds ago
2 days, 10 hours ago
4 months, 3 weeks ago
9 years, 7 months ago
67 years, 6 months ago
289 years, 4 months ago
3521 years ago

Generate time ago from date
1 second ago
1 minute ago
1 hour ago
1 day ago
1 week ago
1 month ago
1 year ago

Generate time ago from date with random number
58 minutes, 41 seconds ago
2 days, 10 hours, 41 minutes ago
4 months, 3 weeks, 5 days, 17 hours ago
9 years, 7 months, 3 weeks, 5 days ago
67 years, 6 months, 1 week, 5 days ago
289 years, 4 months, 3 weeks, 4 days ago
3521 years ago

Generate time ago from with random number and 2 levels
58 minutes, 41 seconds ago
2 days, 10 hours ago
4 months, 3 weeks ago
9 years, 7 months ago
67 years, 6 months ago
289 years, 4 months ago
3521 years ago

References

You may also like...