How to calculate "time ago" in Java?

JavaDateTimeDatediffRelative Time-Span

Java Problem Overview


In Ruby on Rails, there is a feature that allows you to take any Date and print out how "long ago" it was.

For example:

8 minutes ago
8 hours ago
8 days ago
8 months ago
8 years ago

Is there an easy way to do this in Java?

Java Solutions


Solution 1 - Java

Take a look at the PrettyTime library.

It's quite simple to use:

import org.ocpsoft.prettytime.PrettyTime;

PrettyTime p = new PrettyTime();
System.out.println(p.format(new Date()));
// prints "moments ago"

You can also pass in a locale for internationalized messages:

PrettyTime p = new PrettyTime(new Locale("fr"));
System.out.println(p.format(new Date()));
// prints "à l'instant"

As noted in the comments, Android has this functionality built into the android.text.format.DateUtils class.

Solution 2 - Java

Have you considered the TimeUnit enum? It can be pretty useful for this kind of thing

	try {
        SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
        Date past = format.parse("01/10/2010");
        Date now = new Date();

        System.out.println(TimeUnit.MILLISECONDS.toMillis(now.getTime() - past.getTime()) + " milliseconds ago");
        System.out.println(TimeUnit.MILLISECONDS.toMinutes(now.getTime() - past.getTime()) + " minutes ago");
        System.out.println(TimeUnit.MILLISECONDS.toHours(now.getTime() - past.getTime()) + " hours ago");
        System.out.println(TimeUnit.MILLISECONDS.toDays(now.getTime() - past.getTime()) + " days ago");
    }
    catch (Exception j){
        j.printStackTrace();
    }

Solution 3 - Java

I take RealHowTo and Ben J answers and make my own version:

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< TimeAgo.times.size(); i++) {
		Long current = TimeAgo.times.get(i);
		long temp = duration/current;
		if(temp>0) {
			res.append(temp).append(" ").append( TimeAgo.timesString.get(i) ).append(temp != 1 ? "s" : "").append(" ago");
			break;
		}
	}
	if("".equals(res.toString()))
		return "0 seconds ago";
	else
		return res.toString();
}
public static void main(String args[]) {
	System.out.println(toDuration(123));
	System.out.println(toDuration(1230));
	System.out.println(toDuration(12300));
	System.out.println(toDuration(123000));
	System.out.println(toDuration(1230000));
	System.out.println(toDuration(12300000));
	System.out.println(toDuration(123000000));
	System.out.println(toDuration(1230000000));
	System.out.println(toDuration(12300000000L));
	System.out.println(toDuration(123000000000L));
}}

which will print the following

0 second ago
1 second ago
12 seconds ago
2 minutes ago
20 minutes ago
3 hours ago
1 day ago
14 days ago
4 months ago
3 years ago

Solution 4 - Java

  public class TimeUtils {
    
      public final static long ONE_SECOND = 1000;
      public final static long SECONDS = 60;
    
      public final static long ONE_MINUTE = ONE_SECOND * 60;
      public final static long MINUTES = 60;
      
      public final static long ONE_HOUR = ONE_MINUTE * 60;
      public final static long HOURS = 24;
      
      public final static long ONE_DAY = ONE_HOUR * 24;
    
      private TimeUtils() {
      }
    
      /**
       * converts time (in milliseconds) to human-readable format
       *  "<w> days, <x> hours, <y> minutes and (z) seconds"
       */
      public static String millisToLongDHMS(long duration) {
        StringBuilder res = new StringBuilder();
        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(" minute").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(" second").append(temp > 1 ? "s" : "");
          }
          return res.toString();
        } else {
          return "0 second";
        }
      }
    
   
      public static void main(String args[]) {
        System.out.println(millisToLongDHMS(123));
        System.out.println(millisToLongDHMS((5 * ONE_SECOND) + 123));
        System.out.println(millisToLongDHMS(ONE_DAY + ONE_HOUR));
        System.out.println(millisToLongDHMS(ONE_DAY + 2 * ONE_SECOND));
        System.out.println(millisToLongDHMS(ONE_DAY + ONE_HOUR + (2 * ONE_MINUTE)));
        System.out.println(millisToLongDHMS((4 * ONE_DAY) + (3 * ONE_HOUR)
            + (2 * ONE_MINUTE) + ONE_SECOND));
        System.out.println(millisToLongDHMS((5 * ONE_DAY) + (4 * ONE_HOUR)
            + ONE_MINUTE + (23 * ONE_SECOND) + 123));
        System.out.println(millisToLongDHMS(42 * ONE_DAY));
        /*
          output :
                0 second
                5 seconds
                1 day, 1 hour
                1 day and 2 seconds
                1 day, 1 hour, 2 minutes
                4 days, 3 hours, 2 minutes and 1 second
                5 days, 4 hours, 1 minute and 23 seconds
                42 days
         */
    }
}

more @Format a duration in milliseconds into a human-readable format

Solution 5 - Java

This is based on RealHowTo's answer so if you like it, give him/her some love too.

This cleaned up version allows you to specify the range of time you might be interested in.

It also handles the " and " part a little differently. I often find when joining strings with a delimiter it's ofter easier to skip the complicated logic and just delete the last delimiter when you're done.

import java.util.concurrent.TimeUnit;
import static java.util.concurrent.TimeUnit.MILLISECONDS;

public class TimeUtils {

    /**
     * Converts time to a human readable format within the specified range
     *
     * @param duration the time in milliseconds to be converted
     * @param max      the highest time unit of interest
     * @param min      the lowest time unit of interest
     */
    public static String formatMillis(long duration, TimeUnit max, TimeUnit min) {
        StringBuilder res = new StringBuilder();

        TimeUnit current = max;

        while (duration > 0) {
            long temp = current.convert(duration, MILLISECONDS);

            if (temp > 0) {
                duration -= current.toMillis(temp);
                res.append(temp).append(" ").append(current.name().toLowerCase());
                if (temp < 2) res.deleteCharAt(res.length() - 1);
                res.append(", ");
            }

            if (current == min) break;

            current = TimeUnit.values()[current.ordinal() - 1];
        }

        // clean up our formatting....

        // we never got a hit, the time is lower than we care about
        if (res.lastIndexOf(", ") < 0) return "0 " + min.name().toLowerCase();

        // yank trailing  ", "
        res.deleteCharAt(res.length() - 2);

        //  convert last ", " to " and"
        int i = res.lastIndexOf(", ");
        if (i > 0) {
            res.deleteCharAt(i);
            res.insert(i, " and");
        }

        return res.toString();
    }
}

Little code to give it a whirl:

import static java.util.concurrent.TimeUnit.*;

public class Main {

    public static void main(String args[]) {
        long[] durations = new long[]{
            123,
            SECONDS.toMillis(5) + 123,
            DAYS.toMillis(1) + HOURS.toMillis(1),
            DAYS.toMillis(1) + SECONDS.toMillis(2),
            DAYS.toMillis(1) + HOURS.toMillis(1) + MINUTES.toMillis(2),
            DAYS.toMillis(4) + HOURS.toMillis(3) + MINUTES.toMillis(2) + SECONDS.toMillis(1),
            DAYS.toMillis(5) + HOURS.toMillis(4) + MINUTES.toMillis(1) + SECONDS.toMillis(23) + 123,
            DAYS.toMillis(42)
        };

        for (long duration : durations) {
            System.out.println(TimeUtils.formatMillis(duration, DAYS, SECONDS));
        }

        System.out.println("\nAgain in only hours and minutes\n");

        for (long duration : durations) {
            System.out.println(TimeUtils.formatMillis(duration, HOURS, MINUTES));
        }
    }

}

Which will output the following:

0 seconds
5 seconds 
1 day and 1 hour 
1 day and 2 seconds 
1 day, 1 hour and 2 minutes 
4 days, 3 hours, 2 minutes and 1 second 
5 days, 4 hours, 1 minute and 23 seconds 
42 days 

Again in only hours and minutes

0 minutes
0 minutes
25 hours 
24 hours 
25 hours and 2 minutes 
99 hours and 2 minutes 
124 hours and 1 minute 
1008 hours 

And in case anyone ever needs it, here's a class that will convert any string like the above back into milliseconds. It's pretty useful for allowing people to specify timeouts of various things in readable text.

Solution 6 - Java

there's a simple way to do this:

let's say you want the time 20 minutes ago:

Long minutesAgo = new Long(20);
Date date = new Date();
Date dateIn_X_MinAgo = new Date (date.getTime() - minutesAgo*60*1000);

that's it..

Solution 7 - Java

About built-in solutions:

Java does not have any built-in support for formatting relative times, also not Java-8 and its new package java.time. If you only need English and nothing else then and only then a hand-made solution might be acceptable - see the answer of @RealHowTo (although it has the strong disadvantage to not take into account the timezone for the translation of instant deltas to local time units!). Anyway, if you want to avoid home-grown complex workarounds especially for other locales then you need an external library.

In latter case, I recommend to use my library Time4J (or Time4A on Android). It offers greatest flexibility and most i18n-power. The class net.time4j.PrettyTime has seven methods printRelativeTime...(...) for this purpose. Example using a test clock as time source:

TimeSource<?> clock = () -> PlainTimestamp.of(2015, 8, 1, 10, 24, 5).atUTC();
Moment moment = PlainTimestamp.of(2015, 8, 1, 17, 0).atUTC(); // our input
String durationInDays =
  PrettyTime.of(Locale.GERMAN).withReferenceClock(clock).printRelative(
    moment,
    Timezone.of(EUROPE.BERLIN),
    TimeUnit.DAYS); // controlling the precision
System.out.println(durationInDays); // heute (german word for today)

Another example using java.time.Instant as input:

String relativeTime = 
  PrettyTime.of(Locale.ENGLISH)
    .printRelativeInStdTimezone(Moment.from(Instant.EPOCH));
System.out.println(relativeTime); // 45 years ago

This library supports via its latest version (v4.17) 80 languages and also some country-specific locales (especially for Spanish, English, Arabic, French). The i18n-data is mainly based on the newest CLDR-version v29. Other important reasons why to use this library are good support for plural rules (which are often different from English in other locales), abbreviated format style (for example: "1 sec ago") and expressive ways for taking into account timezones. Time4J is even aware of such exotic details like leap seconds in calculations of relative times (not really important but it forms a message related to the expectation horizon). The compatibility with Java-8 exists due to easily available conversion methods for types like java.time.Instant or java.time.Period.

Are there any drawbacks? Only two.

  • The library is not small (also because of its big i18n-data repository).
  • The API is not well known so community knowledge and support are not available yet otherwise the supplied documentation is pretty detailed and comprehensive.

(Compact) alternatives:

If you look for a smaller solution and don't need so many features and are willing to tolerate possible quality issues related to i18n-data then:

  • I would recommend ocpsoft/PrettyTime (support for actually 32 languages (soon 34?) suitable for work with java.util.Date only - see the answer of @ataylor). The industry standard CLDR (from Unicode consortium) with its big community background is unfortunately not a base of the i18n-data so further enhancements or improvements of data can take a while...

  • If you are on Android then the helper class android.text.format.DateUtils is a slim built-in alternative (see other comments and answers here, with the disadvantage that it has no support for years and months. And I am sure that only very few people like the API-style of this helper class.

  • If you are a fan of Joda-Time then you can look at its class PeriodFormat (support for 14 languages in release v2.9.4, on the other side: Joda-Time is surely not compact, too, so I mention it here just for completeness). This library is not a real answer because relative times are not supported at all. You will need to append the literal " ago" at least (and manually stripping off all lower units from generated list formats - awkward). Unlike Time4J or Android-DateUtils, it has no special support for abbreviations or automatic switching from relative times to absolute time representations. Like PrettyTime, it is totally dependent on the unconfirmed contributions of private members of the Java-community to its i18n-data.

Solution 8 - Java

Based on a bunch of answers here, I created the following for my use case.

Example usage:

String relativeDate = String.valueOf(
                TimeUtils.getRelativeTime( 1000L * myTimeInMillis() ));

import java.util.Arrays;
import java.util.List;

import static java.util.concurrent.TimeUnit.DAYS;
import static java.util.concurrent.TimeUnit.HOURS;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.SECONDS;

/**
 * Utilities for dealing with dates and times
 */
public class TimeUtils {

    public static final List<Long> times = Arrays.asList(
        DAYS.toMillis(365),
        DAYS.toMillis(30),
        DAYS.toMillis(7),
        DAYS.toMillis(1),
        HOURS.toMillis(1),
        MINUTES.toMillis(1),
        SECONDS.toMillis(1)
    );

    public static final List<String> timesString = Arrays.asList(
        "yr", "mo", "wk", "day", "hr", "min", "sec"
    );

    /**
     * Get relative time ago for date
     *
     * NOTE:
     *  if (duration > WEEK_IN_MILLIS) getRelativeTimeSpanString prints the date.
     *
     * ALT:
     *  return getRelativeTimeSpanString(date, now, SECOND_IN_MILLIS, FORMAT_ABBREV_RELATIVE);
     *
     * @param date String.valueOf(TimeUtils.getRelativeTime(1000L * Date/Time in Millis)
     * @return relative time
     */
    public static CharSequence getRelativeTime(final long date) {
        return toDuration( Math.abs(System.currentTimeMillis() - date) );
    }

    private static String toDuration(long duration) {
        StringBuilder sb = new StringBuilder();
        for(int i=0;i< times.size(); i++) {
            Long current = times.get(i);
            long temp = duration / current;
            if (temp > 0) {
                sb.append(temp)
                  .append(" ")
                  .append(timesString.get(i))
                  .append(temp > 1 ? "s" : "")
                  .append(" ago");
                break;
            }
        }
        return sb.toString().isEmpty() ? "now" : sb.toString();
    }
}

Solution 9 - Java

If you looking for a simple "Today", "Yesterday" or "x days ago".

private String getDaysAgo(Date date){
	long days = (new Date().getTime() - date.getTime()) / 86400000;
	
	if(days == 0) return "Today";
	else if(days == 1) return "Yesterday";
	else return days + " days ago";
}

Solution 10 - Java

java.time

Using the java.time framework built into Java 8 and later.

LocalDateTime t1 = LocalDateTime.of(2015, 1, 1, 0, 0, 0);
LocalDateTime t2 = LocalDateTime.now();
Period period = Period.between(t1.toLocalDate(), t2.toLocalDate());
Duration duration = Duration.between(t1, t2);

System.out.println("First January 2015 is " + period.getYears() + " years ago");
System.out.println("First January 2015 is " + period.getMonths() + " months ago");
System.out.println("First January 2015 is " + period.getDays() + " days ago");
System.out.println("First January 2015 is " + duration.toHours() + " hours ago");
System.out.println("First January 2015 is " + duration.toMinutes() + " minutes ago");

Solution 11 - Java

java.time

The Answer by Habsq has the right idea but the wrong methods.

For a span-of-time unattached to the timeline on the scale of years-months-days, use Period. For days meaning 24-hour chunks of time unrelated to calendar and hours-minutes-seconds, use Duration. Mixing the two scales rarely makes any sense.

Duration

Start by fetching the current moment as seen in UTC, using the Instant class.

Instant now = Instant.now();  // Capture the current moment as seen in UTC.
Instant then = now.minus( 8L , ChronoUnit.HOURS ).minus( 8L , ChronoUnit.MINUTES ).minus( 8L , ChronoUnit.SECONDS );
Duration d = Duration.between( then , now );

Generate text for hours, minutes, and seconds.

// Generate text by calling `to…Part` methods.
String output = d.toHoursPart() + " hours ago\n" + d.toMinutesPart() + " minutes ago\n" + d.toSecondsPart() + " seconds ago";

Dump to console.

System.out.println( "From: " + then + " to: " + now );
System.out.println( output );

>From: 2019-06-04T11:53:55.714965Z to: 2019-06-04T20:02:03.714965Z

>8 hours ago

>8 minutes ago

>8 seconds ago

Period

Start by getting the current date.

A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.

If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your desired/expected time zone explicitly as an argument. If critical, confirm the zone with your user.

Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true-time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

Recreate a date eight days, months, and years ago.

LocalDate then = today.minusYears( 8 ).minusMonths( 8 ).minusDays( 7 ); // Notice the 7 days, not 8, because of granularity of months. 

Calculate elapsed time.

Period p = Period.between( then , today );

Build the string of "time ago" pieces.

String output = p.getDays() + " days ago\n" + p.getMonths() + " months ago\n" + p.getYears() + " years ago";

Dump to console.

System.out.println( "From: " + then + " to: " + today );
System.out.println( output );

>From: 2010-09-27 to: 2019-06-04

>8 days ago

>8 months ago

>8 years ago


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Solution 12 - Java

I created a simple Java timeago port of the jquery-timeago plug-in that does what you are asking for.

TimeAgo time = new TimeAgo();
String minutes = time.timeAgo(System.currentTimeMillis() - (15*60*1000)); // returns "15 minutes ago"

Solution 13 - Java

In case you're developing an app for Android, it provides the utility class DateUtils for all such requirements. Take a look at 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 lets you specify 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 etc.

Solution 14 - Java

For Android:

Just use this:

public static String getTimeAgoFormat(long timestamp) {
    return android.text.format.DateUtils.getRelativeTimeSpanString(timestamp).toString();
}

(From a comment)

Solution 15 - Java

The joda-time package, has the notion of Periods. You can do arithmetic with Periods and DateTimes.

From the docs:

public boolean isRentalOverdue(DateTime datetimeRented) {
  Period rentalPeriod = new  Period().withDays(2).withHours(12);
  return datetimeRented.plus(rentalPeriod).isBeforeNow();
}

Solution 16 - Java

You Can use this function to calculate time ago

 private String timeAgo(long time_ago) {
        long cur_time = (Calendar.getInstance().getTimeInMillis()) / 1000;
        long time_elapsed = cur_time - time_ago;
        long seconds = time_elapsed;
        int minutes = Math.round(time_elapsed / 60);
        int hours = Math.round(time_elapsed / 3600);
        int days = Math.round(time_elapsed / 86400);
        int weeks = Math.round(time_elapsed / 604800);
        int months = Math.round(time_elapsed / 2600640);
        int years = Math.round(time_elapsed / 31207680);

        // Seconds
        if (seconds <= 60) {
            return "just now";
        }
        //Minutes
        else if (minutes <= 60) {
            if (minutes == 1) {
                return "one minute ago";
            } else {
                return minutes + " minutes ago";
            }
        }
        //Hours
        else if (hours <= 24) {
            if (hours == 1) {
                return "an hour ago";
            } else {
                return hours + " hrs ago";
            }
        }
        //Days
        else if (days <= 7) {
            if (days == 1) {
                return "yesterday";
            } else {
                return days + " days ago";
            }
        }
        //Weeks
        else if (weeks <= 4.3) {
            if (weeks == 1) {
                return "a week ago";
            } else {
                return weeks + " weeks ago";
            }
        }
        //Months
        else if (months <= 12) {
            if (months == 1) {
                return "a month ago";
            } else {
                return months + " months ago";
            }
        }
        //Years
        else {
            if (years == 1) {
                return "one year ago";
            } else {
                return years + " years ago";
            }
        }
    }
  1. Here time_ago is in microsecond

Solution 17 - Java

private const val SECOND_MILLIS = 1
private const val MINUTE_MILLIS = 60 * SECOND_MILLIS
private const val HOUR_MILLIS = 60 * MINUTE_MILLIS
private const val DAY_MILLIS = 24 * HOUR_MILLIS

object TimeAgo {

fun timeAgo(time: Int): String {

    val now = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())
    if (time > now || time <= 0) {
        return "in the future"
    }

    val diff = now - time
    return when {
        diff < MINUTE_MILLIS -> "Just now"
        diff < 2 * MINUTE_MILLIS -> "a minute ago"
        diff < 60 * MINUTE_MILLIS -> "${diff / MINUTE_MILLIS} minutes ago"
        diff < 2 * HOUR_MILLIS -> "an hour ago"
        diff < 24 * HOUR_MILLIS -> "${diff / HOUR_MILLIS} hours ago"
        diff < 48 * HOUR_MILLIS -> "yesterday"
        else -> "${diff / DAY_MILLIS} days ago"
    }
}

}

Call

val String = timeAgo(unixTimeStamp)

to get the time ago in Kotlin

Solution 18 - Java

It's not pretty...but the closest I can think of is using Joda-Time (as described in this post: How to calculate elapsed time from now with Joda Time?

Solution 19 - Java

This is a better code if we consider performance.It reduces the number of calculations. Reason Minutes are calculated only if the number of seconds is greater than 60 and Hours are calculated only if the number of minutes is greater than 60 and so on...

class timeAgo {

static String getTimeAgo(long time_ago) {
    time_ago=time_ago/1000;
    long cur_time = (Calendar.getInstance().getTimeInMillis())/1000 ;
    long time_elapsed = cur_time - time_ago;
    long seconds = time_elapsed;
   // Seconds
    if (seconds <= 60) {
        return "Just now";
    }
    //Minutes
    else{
        int minutes = Math.round(time_elapsed / 60);

        if (minutes <= 60) {
            if (minutes == 1) {
                return "a minute ago";
            } else {
                return minutes + " minutes ago";
            }
        }
        //Hours
        else {
            int hours = Math.round(time_elapsed / 3600);
            if (hours <= 24) {
                if (hours == 1) {
                    return "An hour ago";
                } else {
                    return hours + " hrs ago";
                }
            }
            //Days
            else {
                int days = Math.round(time_elapsed / 86400);
                if (days <= 7) {
                    if (days == 1) {
                        return "Yesterday";
                    } else {
                        return days + " days ago";
                    }
                }
                //Weeks
                else {
                    int weeks = Math.round(time_elapsed / 604800);
                    if (weeks <= 4.3) {
                        if (weeks == 1) {
                            return "A week ago";
                        } else {
                            return weeks + " weeks ago";
                        }
                    }
                    //Months
                    else {
                        int months = Math.round(time_elapsed / 2600640);
                        if (months <= 12) {
                            if (months == 1) {
                                return "A month ago";
                            } else {
                                return months + " months ago";
                            }
                        }
                        //Years
                        else {
                            int years = Math.round(time_elapsed / 31207680);
                            if (years == 1) {
                                return "One year ago";
                            } else {
                                return years + " years ago";
                            }
                        }
                    }
                }
            }
        }
    }

}

}

Solution 20 - Java

java.time

You can use java.time.Duration and java.time.Period which are modelled on ISO-8601 standards and were introduced with Java-8 as part of JSR-310 implementation. With Java-9 some more convenience methods were introduced.

  1. Use Duration to calculate a time-based quantity or amount of time. It can be accessed using duration-based units, such as nanoseconds, seconds, minutes and hours. In addition, the DAYS unit can be used and is treated as exactly equal to 24 hours, thus ignoring daylight savings effects.
  2. Use Period to calculate a date-based amount of time. It can be accessed using period-based units, such as days, months and years.

Demo:

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.Month;

public class Main {
	public static void main(String[] args) {
		// An arbitrary local date and time
		LocalDateTime startDateTime = LocalDateTime.of(2020, Month.DECEMBER, 10, 15, 20, 25);

		// Current local date and time
		LocalDateTime endDateTime = LocalDateTime.now();

		Duration duration = Duration.between(startDateTime, endDateTime);
		// Default format
		System.out.println(duration);

		// Custom format
		// ####################################Java-8####################################
		String formattedElapsedTime = String.format("%d days, %d hours, %d minutes, %d seconds, %d nanoseconds ago",
				duration.toDays(), duration.toHours() % 24, duration.toMinutes() % 60, duration.toSeconds() % 60,
				duration.toNanos() % 1000000000);
		System.out.println(formattedElapsedTime);
		// ##############################################################################

		// ####################################Java-9####################################
		formattedElapsedTime = String.format("%d days, %d hours, %d minutes, %d seconds, %d nanoseconds ago",
				duration.toDaysPart(), duration.toHoursPart(), duration.toMinutesPart(), duration.toSecondsPart(),
				duration.toNanosPart());
		System.out.println(formattedElapsedTime);
		// ##############################################################################
	}
}

Output:

PT1395H35M7.355288S
58 days, 3 hours, 35 minutes, 7 seconds, 355288000 nanoseconds ago
58 days, 3 hours, 35 minutes, 7 seconds, 355288000 nanoseconds ago

If you have two moments at UTC, you can use Instant instead of LocalDateTime e.g.

import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;

public class Main {
	public static void main(String[] args) {
		// Current moment at UTC
		Instant now = Instant.now();

		// An instant in the past
		Instant startDateTime = now.minus(58, ChronoUnit.DAYS)
								.minus(2, ChronoUnit.HOURS)
								.minus(54, ChronoUnit.MINUTES)
								.minus(24, ChronoUnit.SECONDS)
								.minus(808624000, ChronoUnit.NANOS);

		Duration duration = Duration.between(startDateTime, now);
		// Default format
		System.out.println(duration);

		// Custom format
		// ####################################Java-8####################################
		String formattedElapsedTime = String.format("%d days, %d hours, %d minutes, %d seconds, %d nanoseconds ago",
				duration.toDays(), duration.toHours() % 24, duration.toMinutes() % 60, duration.toSeconds() % 60,
				duration.toNanos() % 1000000000);
		System.out.println(formattedElapsedTime);
		// ##############################################################################

		// ####################################Java-9####################################
		formattedElapsedTime = String.format("%d days, %d hours, %d minutes, %d seconds, %d nanoseconds ago",
				duration.toDaysPart(), duration.toHoursPart(), duration.toMinutesPart(), duration.toSecondsPart(),
				duration.toNanosPart());
		System.out.println(formattedElapsedTime);
		// ##############################################################################
	}
}

Output:

PT1394H54M24.808624S
58 days, 2 hours, 54 minutes, 24 seconds, 808624000 nanoseconds ago
58 days, 2 hours, 54 minutes, 24 seconds, 808624000 nanoseconds ago

Demo on Period:

import java.time.LocalDate;
import java.time.Period;
import java.time.ZoneId;

public class Main {
	public static void main(String[] args) {
		// Replace ZoneId.systemDefault() with the applicable timezone ID e.g.
		// ZoneId.of("Europe/London"). For LocalDate in the JVM's timezone, simply use
		// LocalDate.now()
		LocalDate endDate = LocalDate.now(ZoneId.systemDefault());

		// Let's assume the start date is 1 year, 2 months, and 3 days ago
		LocalDate startDate = endDate.minusYears(1).minusMonths(2).minusDays(3);

		Period period = Period.between(startDate, endDate);
		// Default format
		System.out.println(period);

		// Custom format
		String formattedElapsedPeriod = String.format("%d years, %d months, %d days ago", period.getYears(),
				period.getMonths(), period.getDays());
		System.out.println(formattedElapsedPeriod);
	}
}

Output:

P1Y2M3D
1 years, 2 months, 3 days ago

Learn about the modern date-time API from Trail: Date Time.

Solution 21 - Java

After long research i found this.

    public class GetTimeLapse {
    public static String getlongtoago(long createdAt) {
        DateFormat userDateFormat = new SimpleDateFormat("E MMM dd HH:mm:ss Z yyyy");
        DateFormat dateFormatNeeded = new SimpleDateFormat("MM/dd/yyyy HH:MM:SS");
        Date date = null;
        date = new Date(createdAt);
        String crdate1 = dateFormatNeeded.format(date);

        // Date Calculation
        DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
        crdate1 = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(date);

        // get current date time with Calendar()
        Calendar cal = Calendar.getInstance();
        String currenttime = dateFormat.format(cal.getTime());

        Date CreatedAt = null;
        Date current = null;
        try {
            CreatedAt = dateFormat.parse(crdate1);
            current = dateFormat.parse(currenttime);
        } catch (java.text.ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        // Get msec from each, and subtract.
        long diff = current.getTime() - CreatedAt.getTime();
        long diffSeconds = diff / 1000;
        long diffMinutes = diff / (60 * 1000) % 60;
        long diffHours = diff / (60 * 60 * 1000) % 24;
        long diffDays = diff / (24 * 60 * 60 * 1000);

        String time = null;
        if (diffDays > 0) {
            if (diffDays == 1) {
                time = diffDays + "day ago ";
            } else {
                time = diffDays + "days ago ";
            }
        } else {
            if (diffHours > 0) {
                if (diffHours == 1) {
                    time = diffHours + "hr ago";
                } else {
                    time = diffHours + "hrs ago";
                }
            } else {
                if (diffMinutes > 0) {
                    if (diffMinutes == 1) {
                        time = diffMinutes + "min ago";
                    } else {
                        time = diffMinutes + "mins ago";
                    }
                } else {
                    if (diffSeconds > 0) {
                        time = diffSeconds + "secs ago";
                    }
                }

            }

        }
        return time;
    }
}

Solution 22 - Java

For Android Exactly like Ravi said, but since lots of people want to just copy-paste the thing here it is.

  try {
      SimpleDateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z");
      Date dt = formatter.parse(date_from_server);
      CharSequence output = DateUtils.getRelativeTimeSpanString (dt.getTime());
      your_textview.setText(output.toString());
    } catch (Exception ex) {
      ex.printStackTrace();
      your_textview.setText("");
    }

Explanation for people that have more time

  1. You get the data from somewhere. First, you have to figure out its format.

Ex. I get the data from a server in the format Wed, 27 Jan 2016 09:32:35 GMT [this is probably NOT your case]

this is translated into

SimpleDateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z");

how do I know it? Read the documentation here.

Then after I parse it I get a date. that date I put in the getRelativeTimeSpanString (without any additional parameters is fine by me, to default to minutes)

You WILL get an exception if you didn't figure out the correct parsing String, Something like exception at character 5. Look at character 5, and correct your initial parsing string.. You might get another exception, repeat these steps until you have the correct formula.

Solution 23 - Java

You can use Java's Library RelativeDateTimeFormatter, it does exactly that:

RelativeDateTimeFormatter fmt = RelativeDateTimeFormatter.getInstance();
 fmt.format(1, Direction.NEXT, RelativeUnit.DAYS); // "in 1 day"
 fmt.format(3, Direction.NEXT, RelativeUnit.DAYS); // "in 3 days"
 fmt.format(3.2, Direction.LAST, RelativeUnit.YEARS); // "3.2 years ago"

 fmt.format(Direction.LAST, AbsoluteUnit.SUNDAY); // "last Sunday"
 fmt.format(Direction.THIS, AbsoluteUnit.SUNDAY); // "this Sunday"
 fmt.format(Direction.NEXT, AbsoluteUnit.SUNDAY); // "next Sunday"
 fmt.format(Direction.PLAIN, AbsoluteUnit.SUNDAY); // "Sunday"

 fmt.format(Direction.LAST, AbsoluteUnit.DAY); // "yesterday"
 fmt.format(Direction.THIS, AbsoluteUnit.DAY); // "today"
 fmt.format(Direction.NEXT, AbsoluteUnit.DAY); // "tomorrow"

 fmt.format(Direction.PLAIN, AbsoluteUnit.NOW); // "now"

Solution 24 - Java

SQL timestamp to now elapsed time. Set your own timezone.

NOTE1: This will handle singular/plural.

NOTE2: This is using Joda time

String getElapsedTime(String strMysqlTimestamp) {
    
    DateTimeFormatter formatter = DateTimeFormat.forPattern("YYYY-MM-dd HH:mm:ss.S");
    DateTime mysqlDate = formatter.parseDateTime(strMysqlTimestamp).
                         withZone(DateTimeZone.forID("Asia/Kuala_Lumpur"));
    
    DateTime now = new DateTime();
    Period period = new Period(mysqlDate, now);
    
    int seconds = period.getSeconds();
    int minutes = period.getMinutes();
    int hours = period.getHours();
    int days = period.getDays();
    int weeks = period.getWeeks();
    int months = period.getMonths();
    int years = period.getYears();
    
    String elapsedTime = "";
    if (years != 0)
        if (years == 1)
            elapsedTime = years + " year ago";
        else
            elapsedTime = years + " years ago";
    else if (months != 0)
        if (months == 1)
            elapsedTime = months + " month ago";
        else
            elapsedTime = months + " months ago";
    else if (weeks != 0)
        if (weeks == 1)
            elapsedTime = weeks + " week ago";
        else
            elapsedTime = weeks + " weeks ago";
    else if (days != 0)
        if (days == 1)
            elapsedTime = days + " day ago";
        else
            elapsedTime = days + " days ago";
    else if (hours != 0)
        if (hours == 1)
            elapsedTime = hours + " hour ago";
        else
            elapsedTime = hours + " hours ago";
    else if (minutes != 0)
        if (minutes == 1)
            elapsedTime = minutes + " minute ago";
        else
            elapsedTime = minutes + " minutes ago";
    else if (seconds != 0)
        if (seconds == 1)
            elapsedTime = seconds + " second ago";
        else
            elapsedTime = seconds + " seconds ago";   
    
    return elapsedTime;
}

Solution 25 - Java

Here is my Java Implementation of this

    public static String relativeDate(Date date){
	Date now=new Date();
	if(date.before(now)){
	int days_passed=(int) TimeUnit.MILLISECONDS.toDays(now.getTime() - date.getTime());
	if(days_passed>1)return days_passed+" days ago";
	else{
		int hours_passed=(int) TimeUnit.MILLISECONDS.toHours(now.getTime() - date.getTime());
		if(hours_passed>1)return days_passed+" hours ago";
		else{
			int minutes_passed=(int) TimeUnit.MILLISECONDS.toMinutes(now.getTime() - date.getTime());
			if(minutes_passed>1)return minutes_passed+" minutes ago";
			else{
				int seconds_passed=(int) TimeUnit.MILLISECONDS.toSeconds(now.getTime() - date.getTime());
				return seconds_passed +" seconds ago";
			}
		}
	}
	 
	}
	else
	{
		return new SimpleDateFormat("HH:mm:ss MM/dd/yyyy").format(date).toString();
	}
  }

Solution 26 - Java

it works for me

public class TimeDifference {
    int years;
    int months;
    int days;
    int hours;
    int minutes;
    int seconds;
    String differenceString;

    public TimeDifference(@NonNull Date curdate, @NonNull Date olddate) {

        float diff = curdate.getTime() - olddate.getTime();
        if (diff >= 0) {
            int yearDiff = Math.round((diff / (AppConstant.aLong * AppConstant.aFloat)) >= 1 ? (diff / (AppConstant.aLong * AppConstant.aFloat)) : 0);
            if (yearDiff > 0) {
                years = yearDiff;
                setDifferenceString(years + (years == 1 ? " year" : " years") + " ago");
            } else {
                int monthDiff = Math.round((diff / AppConstant.aFloat) >= 1 ? (diff / AppConstant.aFloat) : 0);
                if (monthDiff > 0) {
                    if (monthDiff > AppConstant.ELEVEN) {
                        monthDiff = AppConstant.ELEVEN;
                    }
                    months = monthDiff;
                    setDifferenceString(months + (months == 1 ? " month" : " months") + " ago");
                } else {
                    int dayDiff = Math.round((diff / (AppConstant.bFloat)) >= 1 ? (diff / (AppConstant.bFloat)) : 0);
                    if (dayDiff > 0) {
                        days = dayDiff;
                        if (days == AppConstant.THIRTY) {
                            days = AppConstant.TWENTYNINE;
                        }
                        setDifferenceString(days + (days == 1 ? " day" : " days") + " ago");
                    } else {
                        int hourDiff = Math.round((diff / (AppConstant.cFloat)) >= 1 ? (diff / (AppConstant.cFloat)) : 0);
                        if (hourDiff > 0) {
                            hours = hourDiff;
                            setDifferenceString(hours + (hours == 1 ? " hour" : " hours") + " ago");
                        } else {
                            int minuteDiff = Math.round((diff / (AppConstant.dFloat)) >= 1 ? (diff / (AppConstant.dFloat)) : 0);
                            if (minuteDiff > 0) {
                                minutes = minuteDiff;
                                setDifferenceString(minutes + (minutes == 1 ? " minute" : " minutes") + " ago");
                            } else {
                                int secondDiff = Math.round((diff / (AppConstant.eFloat)) >= 1 ? (diff / (AppConstant.eFloat)) : 0);
                                if (secondDiff > 0) {
                                    seconds = secondDiff;
                                } else {
                                    seconds = 1;
                                }
                                setDifferenceString(seconds + (seconds == 1 ? " second" : " seconds") + " ago");
                            }
                        }
                    }

                }
            }

        } else {
            setDifferenceString("Just now");
        }

    }

    public String getDifferenceString() {
        return differenceString;
    }

    public void setDifferenceString(String differenceString) {
        this.differenceString = differenceString;
    }

    public int getYears() {
        return years;
    }

    public void setYears(int years) {
        this.years = years;
    }

    public int getMonths() {
        return months;
    }

    public void setMonths(int months) {
        this.months = months;
    }

    public int getDays() {
        return days;
    }

    public void setDays(int days) {
        this.days = days;
    }

    public int getHours() {
        return hours;
    }

    public void setHours(int hours) {
        this.hours = hours;
    }

    public int getMinutes() {
        return minutes;
    }

    public void setMinutes(int minutes) {
        this.minutes = minutes;
    }

    public int getSeconds() {
        return seconds;
    }

    public void setSeconds(int seconds) {
        this.seconds = seconds;
    } }

Solution 27 - Java

This is the very basic script. its easy to improvized.
Result : (XXX Hours Ago), or (XX Days Ago/Yesterday/Today)

<span id='hourpost'></span>
,or
<span id='daypost'></span>

<script>
var postTime = new Date('2017/6/9 00:01'); 
var now = new Date();
var difference = now.getTime() - postTime.getTime();
var minutes = Math.round(difference/60000);
var hours = Math.round(minutes/60);
var days = Math.round(hours/24);

var result;
if (days < 1) {
result = "Today";
} else if (days < 2) {
result = "Yesterday";
} else {
result = days + " Days ago";
}

document.getElementById("hourpost").innerHTML = hours + "Hours Ago" ;
document.getElementById("daypost").innerHTML = result ;
</script>

Solution 28 - Java

for this I've done Just Now, seconds ago, min ago, hrs ago, days ago, weeks ago, months ago, years ago in this example you can parse date like 2018-09-05T06:40:46.183Z this or any other like below

add below value in string.xml

  <string name="lbl_justnow">Just Now</string>
    <string name="lbl_seconds_ago">seconds ago</string>
    <string name="lbl_min_ago">min ago</string>
    <string name="lbl_mins_ago">mins ago</string>
    <string name="lbl_hr_ago">hr ago</string>
    <string name="lbl_hrs_ago">hrs ago</string>
    <string name="lbl_day_ago">day ago</string>
    <string name="lbl_days_ago">days ago</string>
    <string name="lbl_lstweek_ago">last week</string>
    <string name="lbl_week_ago">weeks ago</string>
    <string name="lbl_onemonth_ago">1 month ago</string>
    <string name="lbl_month_ago">months ago</string>
    <string name="lbl_oneyear_ago" >last year</string>
    <string name="lbl_year_ago" >years ago</string>

java code try below

  public String getFormatDate(String postTime1) {
        Calendar cal=Calendar.getInstance();
        Date now=cal.getTime();
        String disTime="";
        try {
            Date postTime;
            //2018-09-05T06:40:46.183Z
            postTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse(postTime1);

            long diff=(now.getTime()-postTime.getTime()+18000)/1000;

            //for months
            Calendar calObj = Calendar.getInstance();
            calObj.setTime(postTime);
            int m=calObj.get(Calendar.MONTH);
            calObj.setTime(now);

            SimpleDateFormat monthFormatter = new SimpleDateFormat("MM"); // output month

            int mNow = Integer.parseInt(monthFormatter.format(postTime));

            diff = diff-19800;

            if(diff<15) { //below 15 sec

                disTime = getResources().getString(R.string.lbl_justnow);
            } else if(diff<60) {

                //below 1 min
                disTime= diff+" "+getResources().getString(R.string.lbl_seconds_ago);
            } else if(diff<3600) {//below 1 hr

                // convert min
                long temp=diff/60;

                if(temp==1) {
                    disTime= temp + " " +getResources().getString(R.string.lbl_min_ago);
                } else {
                    disTime = temp  + " " +getResources().getString(R.string.lbl_mins_ago);
                }
            } else if(diff<(24*3600)) {// below 1 day

                // convert hr
                long temp= diff/3600;
                System.out.println("hey temp3:"+temp);
                if(temp==1) {
                    disTime = temp  + " " +getResources().getString(R.string.lbl_hr_ago);
                } else {
                    disTime = temp + " " +getResources().getString(R.string.lbl_hrs_ago);
                }
            } else if(diff<(24*3600*7)) {// below week

                // convert days
                long temp=diff/(3600*24);
                if (temp==1) {
                    //  disTime = "\nyesterday";
                    disTime = temp + " " +getResources().getString(R.string.lbl_day_ago);
                } else {
                    disTime = temp + " " +getResources().getString(R.string.lbl_days_ago);
                }
            } else if(diff<((24*3600*28))) {// below month

                // convert week
                long temp=diff/(3600*24*7);
                if (temp <= 4) {

                    if (temp < 1) {
                        disTime = getResources().getString(R.string.lbl_lstweek_ago);
                    }else{
                        disTime = temp + " " + getResources().getString(R.string.lbl_week_ago);
                    }

                } else {
                    int diffMonth = mNow - m;
                    Log.e("count : ", String.valueOf(diffMonth));
                    disTime = diffMonth + " " + getResources().getString(R.string.lbl_month_ago);
                }
            }else if(diff<((24*3600*365))) {// below year

                // convert month
                long temp=diff/(3600*24*30);

                System.out.println("hey temp2:"+temp);
                if (temp <= 12) {

                    if (temp == 1) {
                        disTime = getResources().getString(R.string.lbl_onemonth_ago);
                    }else{
                        disTime = temp + " " + getResources().getString(R.string.lbl_month_ago);
                    }
                }

            }else if(diff>((24*3600*365))) { // above year

                // convert year
                long temp=diff/(3600*24*30*12);

                System.out.println("hey temp8:"+temp);

                if (temp == 1) {
                    disTime = getResources().getString(R.string.lbl_oneyear_ago);
                }else{
                    disTime = temp + " " + getResources().getString(R.string.lbl_year_ago);
                }
            }

        } catch(Exception e) {
            e.printStackTrace();
        }

        return disTime;
    }

Solution 29 - Java

I'm using the Instant, Date and DateTimeUtils. The data (date) which is stored in the database in type of String and then convert to become Instant.

    /*
    This method is to display ago.
    Example: 3 minutes ago.
    I already implement the latest which is including the Instant.
    Convert from String to Instant and then parse to Date.
     */
    public String convertTimeToAgo(String dataDate) {
    //Initialize
    String conversionTime = null;
    String suffix = "Yang Lalu";
    Date pastTime;
    //Parse from String (which is stored as Instant.now().toString()
    //And then convert to become Date
    Instant instant = Instant.parse(dataDate);
    pastTime = DateTimeUtils.toDate(instant);

    //Today date
    Date nowTime = new Date();

    long dateDiff = nowTime.getTime() - pastTime.getTime();
    long second = TimeUnit.MILLISECONDS.toSeconds(dateDiff);
    long minute = TimeUnit.MILLISECONDS.toMinutes(dateDiff);
    long hour = TimeUnit.MILLISECONDS.toHours(dateDiff);
    long day = TimeUnit.MILLISECONDS.toDays(dateDiff);

    if (second < 60) {
        conversionTime = second + " Saat " + suffix;
    } else if (minute < 60) {
        conversionTime = minute + " Minit " + suffix;
    } else if (hour < 24) {
        conversionTime = hour + " Jam " + suffix;
    } else if (day >= 7) {
        if (day > 30) {
            conversionTime = (day / 30) + " Bulan " + suffix;
        } else if (day > 360) {
            conversionTime = (day / 360) + " Tahun " + suffix;
        } else {
            conversionTime = (day / 7) + " Minggu " + suffix;
        }
    } else if (day < 7) {
        conversionTime = day + " Hari " + suffix;
    }
    return conversionTime;
    }

Solution 30 - Java

The following solutions are all in pure Java:

Option 1: No rounding and only largest time container

The following function will only display the largest time container, for example, if the true elapsed time is "1 month 14 days ago", this function will only display "1 month ago". This function will also always round down, so a time equivalent to "50 days ago" will display as "1 month"

public String formatTimeAgo(long millis) {
        String[] ids = new String[]{"second","minute","hour","day","month","year"};

        long seconds = millis / 1000;
        long minutes = seconds / 60;
        long hours = minutes / 60;
        long days = hours / 24;
        long months = days / 30;
        long years = months / 12;

        ArrayList<Long> times = new ArrayList<>(Arrays.asList(years, months, days, hours, minutes, seconds));

        for(int i = 0; i < times.size(); i++) {
            if(times.get(i) != 0) {
                long value = times.get(i).intValue();

                return value + " " + ids[ids.length - 1 - i] + (value == 1 ? "" : "s") + " ago";
            }
        }

        return "0 seconds ago";
    }

Option 2: With rounding

Simply wrap the time container you'd like to round with a Math.round(...) statement, so if you wanted to round 50 days to 2 months, modify long months = days / 30 to long months = Math.round(days / 30.0)

Solution 31 - Java

Here is my test case, hope it helps:

    val currentCalendar = Calendar.getInstance()
    currentCalendar.set(2019, 6, 2, 5, 31, 0)

    val targetCalendar = Calendar.getInstance()
    targetCalendar.set(2019, 6, 2, 5, 30, 0)

    val diffTs = currentCalendar.timeInMillis - targetCalendar.timeInMillis
    val diffMins = TimeUnit.MILLISECONDS.toMinutes(diffTs)
    val diffHours = TimeUnit.MILLISECONDS.toHours(diffTs)
    val diffDays = TimeUnit.MILLISECONDS.toDays(diffTs)
    val diffWeeks = TimeUnit.MILLISECONDS.toDays(diffTs) / 7
    val diffMonths = TimeUnit.MILLISECONDS.toDays(diffTs) / 30
    val diffYears = TimeUnit.MILLISECONDS.toDays(diffTs) / 365

    val newTs = when {
        diffYears >= 1 -> "Years $diffYears"
        diffMonths >= 1 -> "Months $diffMonths"
        diffWeeks >= 1 -> "Weeks $diffWeeks"
        diffDays >= 1 -> "Days $diffDays"
        diffHours >= 1 -> "Hours $diffHours"
        diffMins >= 1 -> "Mins $diffMins"
        else -> "now"
    }

Solution 32 - Java

The getrelativeDateTime function will give you date time as you see in Whatsapp notification.
To get future relative Date Time add conditions for it. This is created specifically for getting Date Time like Whatsapp notification.

private static String getRelativeDateTime(long date) {
    SimpleDateFormat DateFormat = new SimpleDateFormat("MMM dd, yyyy", Locale.getDefault());
    SimpleDateFormat TimeFormat = new SimpleDateFormat(" hh:mm a", Locale.getDefault());
    long now = Calendar.getInstance().getTimeInMillis();
    long startOfDay = StartOfDay(Calendar.getInstance().getTime());
    String Day = "";
    String Time = "";
    long millSecInADay = 86400000;
    long oneHour = millSecInADay / 24;
    long differenceFromNow = now - date;

    if (date > startOfDay) {
        if (differenceFromNow < (oneHour)) {
            int minute = (int) (differenceFromNow / (60000));
            if (minute == 0) {
                int sec = (int) differenceFromNow / 1000;
                if (sec == 0) {
                    Time = "Just Now";
                } else if (sec == 1) {
                    Time = sec + " second ago";
                } else {
                    Time = sec + " seconds ago";
                }
            } else if (minute == 1) {
                Time = minute + " minute ago";
            } else if (minute < 60) {
                Time = minute + " minutes ago";
            }
        } else {
            Day = "Today, ";
        }
    } else if (date > (startOfDay - millSecInADay)) {
        Day = "Yesterday, ";
    } else if (date > (startOfDay - millSecInADay * 7)) {
        int days = (int) (differenceFromNow / millSecInADay);
        Day = days + " Days ago, ";
    } else {
        Day = DateFormat.format(date);
    }
    if (Time.isEmpty()) {
        Time = TimeFormat.format(date);
    }
    return Day + Time;
}

public static long StartOfDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    return calendar.getTimeInMillis();
}

Solution 33 - Java

For the lack of simplicity and updated response, follows the more recent Java 8 and beyond version

import java.time.*;
import java.time.temporal.*;

public class Time {
    public static void main(String[] args) {

        System.out.println(LocalTime.now().minus(8, ChronoUnit.MINUTES));
        System.out.println(LocalTime.now().minus(8, ChronoUnit.HOURS));
        System.out.println(LocalDateTime.now().minus(8, ChronoUnit.DAYS));
        System.out.println(LocalDateTime.now().minus(8, ChronoUnit.MONTHS));
    }
}

This is the version that uses the Java Time API that tries to solve issues from the past for dealing with Date and Time.

Javadoc

version 8 https://docs.oracle.com/javase/8/docs/api/index.html?java/time/package-summary.html

version 11 https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html

W3Schools Tutorial - https://www.w3schools.com/java/java_date.asp

DZone Article - https://dzone.com/articles/java-8-date-and-time

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjtsView Question on Stackoverflow
Solution 1 - JavaataylorView Answer on Stackoverflow
Solution 2 - JavaBen JView Answer on Stackoverflow
Solution 3 - JavaRiccardo CasattaView Answer on Stackoverflow
Solution 4 - JavaRealHowToView Answer on Stackoverflow
Solution 5 - JavaDavid BlevinsView Answer on Stackoverflow
Solution 6 - JavaMoriaView Answer on Stackoverflow
Solution 7 - JavaMeno HochschildView Answer on Stackoverflow
Solution 8 - JavaCodeversedView Answer on Stackoverflow
Solution 9 - JavaDumi JayView Answer on Stackoverflow
Solution 10 - JavahabsqView Answer on Stackoverflow
Solution 11 - JavaBasil BourqueView Answer on Stackoverflow
Solution 12 - JavaKevin SawickiView Answer on Stackoverflow
Solution 13 - JavaRavi K ThapliyalView Answer on Stackoverflow
Solution 14 - JavaLukas NiessenView Answer on Stackoverflow
Solution 15 - JavaPaul RubelView Answer on Stackoverflow
Solution 16 - JavaRajesh TiwariView Answer on Stackoverflow
Solution 17 - JavaDino SunnyView Answer on Stackoverflow
Solution 18 - JavaJustin NiessnerView Answer on Stackoverflow
Solution 19 - JavaMirza Asad BaigView Answer on Stackoverflow
Solution 20 - JavaArvind Kumar AvinashView Answer on Stackoverflow
Solution 21 - JavaHari krishna Andhra PradeshView Answer on Stackoverflow
Solution 22 - JavaOWADVLView Answer on Stackoverflow
Solution 23 - JavamavesonziniView Answer on Stackoverflow
Solution 24 - Javajumper rbkView Answer on Stackoverflow
Solution 25 - JavaJoey PintoView Answer on Stackoverflow
Solution 26 - JavaRahulView Answer on Stackoverflow
Solution 27 - JavaDwipa AranthaView Answer on Stackoverflow
Solution 28 - JavaOmkarView Answer on Stackoverflow
Solution 29 - JavaTicherhaz FreePalestineView Answer on Stackoverflow
Solution 30 - JavawidaviesView Answer on Stackoverflow
Solution 31 - JavaDavid_WangView Answer on Stackoverflow
Solution 32 - JavaSumit SinghView Answer on Stackoverflow
Solution 33 - JavabrunocrtView Answer on Stackoverflow