How to convert time to " time ago " in android

Viewed 60006

My server. It return time :

"2016-01-24T16:00:00.000Z"

I want

1 : convert to String.

2 : I want it show " time ago " when load it from server.

Please. Help me!

19 Answers

using @Excelso_Widi code, i was able to overcome,

I modified his code and also translated to English.

public class TimeAgo2 {

    public String covertTimeToText(String dataDate) {

        String convTime = null;

        String prefix = "";
        String suffix = "Ago";

        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
            Date pasTime = dateFormat.parse(dataDate);

            Date nowTime = new Date();

            long dateDiff = nowTime.getTime() - pasTime.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) {
                convTime = second + " Seconds " + suffix;
            } else if (minute < 60) {
                convTime = minute + " Minutes "+suffix;
            } else if (hour < 24) {
                convTime = hour + " Hours "+suffix;
            } else if (day >= 7) {
                if (day > 360) {
                    convTime = (day / 360) + " Years " + suffix;
                } else if (day > 30) {
                    convTime = (day / 30) + " Months " + suffix;
                } else {
                    convTime = (day / 7) + " Week " + suffix;
                }
            } else if (day < 7) {
                convTime = day+" Days "+suffix;
            }

        } catch (ParseException e) {
            e.printStackTrace();
            Log.e("ConvTimeE", e.getMessage());
        }

        return convTime;
    }

}

and i used it like this

 String time = jsonObject.getString("date_gmt");
 TimeAgo2 timeAgo2 = new TimeAgo2();
String MyFinalValue = timeAgo2.covertTimeToText(time);

Happy coding and thanks @Excelso_Widi you the man wink

Kotlin version

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

private fun currentDate(): Date {
    val calendar = Calendar.getInstance()
    return calendar.time
}

fun getTimeAgo(date: Date): String {
    var time = date.time
    if (time < 1000000000000L) {
        time *= 1000
    }

    val now = currentDate().time
    if (time > now || time <= 0) {
        return "in the future"
    }

    val diff = now - time
    return when {
        diff < MINUTE_MILLIS -> "moments ago"
        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"
    }
}

For kotlin, you can use this extension function.

fun Date.getTimeAgo(): String {
    val calendar = Calendar.getInstance()
    calendar.time = this

    val year = calendar.get(Calendar.YEAR)
    val month = calendar.get(Calendar.MONTH)
    val day = calendar.get(Calendar.DAY_OF_MONTH)
    val hour = calendar.get(Calendar.HOUR_OF_DAY)
    val minute = calendar.get(Calendar.MINUTE)

    val currentCalendar = Calendar.getInstance()

    val currentYear = currentCalendar.get(Calendar.YEAR)
    val currentMonth = currentCalendar.get(Calendar.MONTH)
    val currentDay = currentCalendar.get(Calendar.DAY_OF_MONTH)
    val currentHour = currentCalendar.get(Calendar.HOUR_OF_DAY)
    val currentMinute = currentCalendar.get(Calendar.MINUTE)

    return if (year < currentYear ) {
        val interval = currentYear - year
        if (interval == 1) "$interval year ago" else "$interval years ago"
    } else if (month < currentMonth) {
        val interval = currentMonth - month
        if (interval == 1) "$interval month ago" else "$interval months ago"
    } else  if (day < currentDay) {
        val interval = currentDay - day
        if (interval == 1) "$interval day ago" else "$interval days ago"
    } else if (hour < currentHour) {
        val interval = currentHour - hour
        if (interval == 1) "$interval hour ago" else "$interval hours ago"
    } else if (minute < currentMinute) {
        val interval = currentMinute - minute
        if (interval == 1) "$interval minute ago" else "$interval minutes ago"
    } else {
        "a moment ago"
    }
}

// To use it
val timeAgo = someDate.getTimeAgo()

Easiest way

For Kotlin (time in millisecond)

private const val SECOND = 1
private const val MINUTE = 60 * SECOND
private const val HOUR = 60 * MINUTE
private const val DAY = 24 * HOUR
private const val MONTH = 30 * DAY
private const val YEAR = 12 * MONTH

private fun currentDate(): Long {
    val calendar = Calendar.getInstance()
    return calendar.timeInMillis
}

// Long: time in millisecond
fun Long.toTimeAgo(): String {
    val time = this
    val now = currentDate()

    // convert back to second
    val diff = (now - time) / 1000

    return when {
        diff < MINUTE -> "Just now"
        diff < 2 * MINUTE -> "a minute ago"
        diff < 60 * MINUTE -> "${diff / MINUTE} minutes ago"
        diff < 2 * HOUR -> "an hour ago"
        diff < 24 * HOUR -> "${diff / HOUR} hours ago"
        diff < 2 * DAY -> "yesterday"
        diff < 30 * DAY -> "${diff / DAY} days ago"
        diff < 2 * MONTH -> "a month ago"
        diff < 12 * MONTH -> "${diff / MONTH} months ago"
        diff < 2 * YEAR -> "a year ago"
        else -> "${diff / YEAR} years ago"
    }
}

You can select what type format you want both method are tested and working fine.

/*
* It's return date  before one week timestamp
*  like return
*  1 day ago
*  2 days ago
*  5 days ago
*  21 April 2019
*
* */
public static String getTimeAgoDate(long pastTimeStamp) {

    // for 2 min ago   use  DateUtils.MINUTE_IN_MILLIS
    // for 2 sec ago   use  DateUtils.SECOND_IN_MILLIS
    // for 1 hours ago use  DateUtils.HOUR_IN_MILLIS

    long now = System.currentTimeMillis();

    if (now - pastTimeStamp < 1000) {
        pastTimeStamp = pastTimeStamp + 1000;
    }
    CharSequence ago =
            DateUtils.getRelativeTimeSpanString(pastTimeStamp, now, DateUtils.SECOND_IN_MILLIS);
    return ago.toString();
}


/*
 *
 * It's return date  before one week timestamp
 *
 *  like return
 *
 *  1 day ago
 *  2 days ago
 *  5 days ago
 *  2 weeks ago
 *  2 months ago
 *  2 years ago
 *
 *
 * */

public static String getTimeAgo(long mReferenceTime) {

    long now = System.currentTimeMillis();
    final long diff = now - mReferenceTime;
    if (diff < android.text.format.DateUtils.WEEK_IN_MILLIS) {
        return (diff <= 1000) ?
                "just now" :
                android.text.format.DateUtils.getRelativeTimeSpanString(mReferenceTime, now, DateUtils.MINUTE_IN_MILLIS,
                        DateUtils.FORMAT_ABBREV_RELATIVE).toString();
    } else if (diff <= 4 * android.text.format.DateUtils.WEEK_IN_MILLIS) {
        int week = (int)(diff / (android.text.format.DateUtils.WEEK_IN_MILLIS));
        return  week>1?week+" weeks ago":week+" week ago";
    } else if (diff < android.text.format.DateUtils.YEAR_IN_MILLIS) {
        int month = (int)(diff / (4 * android.text.format.DateUtils.WEEK_IN_MILLIS));
        return  month>1?month+" months ago":month+" month ago";
    } else {
        int year = (int) (diff/DateUtils.YEAR_IN_MILLIS);
        return year>1?year+" years ago":year+" year ago";
    }
}

Thanks

Please check the code below to do this perfectly in a modular and reusable way which will also return you the future time as like 5 minutes later also. First, you need to create the UnixToHuman class in your project I mention below. Then you need to convert the server returned string into UNIX timestamp by

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
long time = sdf.parse("2016-01-24T16:00:00.000Z").getTime();

Then you need to just call the function UnixToHuman.getTimeAgo(long time) where time is your UNIX time which will return the desired string. The UnixToHuman.java is

public class UnixToHuman {
    private static final int SECOND_MILLIS = 1000;
    private static final int MINUTE_MILLIS = 60 * SECOND_MILLIS;
    private static final int HOUR_MILLIS = 60 * MINUTE_MILLIS;
    private static final int DAY_MILLIS = 24 * HOUR_MILLIS;
    private static final int WEEK_MILLIS = 7 * DAY_MILLIS ;

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

        long now =System.currentTimeMillis();;


        long diff = now - time;
        if(diff>0) {


            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 + " minutes 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 if (diff < 7 * DAY_MILLIS) {
                return diff / DAY_MILLIS + " days ago";
            } else if (diff < 2 * WEEK_MILLIS) {
                return "a week ago";
            } else if (diff < WEEK_MILLIS * 3) {
                return diff / WEEK_MILLIS + " weeks ago";
            } else {
                java.util.Date date = new java.util.Date((long) time);
                return date.toString();
            }

        }
        else {

            diff=time-now;
            if (diff < MINUTE_MILLIS) {
                return "this minute";
            } else if (diff < 2 * MINUTE_MILLIS) {
                return "a minute later";
            } else if (diff < 50 * MINUTE_MILLIS) {
                return diff / MINUTE_MILLIS + " minutes later";
            } else if (diff < 90 * MINUTE_MILLIS) {
                return "an hour later";
            } else if (diff < 24 * HOUR_MILLIS) {
                return diff / HOUR_MILLIS + " hours later";
            } else if (diff < 48 * HOUR_MILLIS) {
                return "tomorrow";
            } else if (diff < 7 * DAY_MILLIS) {
                return diff / DAY_MILLIS + " days later";
            } else if (diff < 2 * WEEK_MILLIS) {
                return "a week later";
            } else if (diff < WEEK_MILLIS * 3) {
                return diff / WEEK_MILLIS + " weeks later";
            } else {
                java.util.Date date = new java.util.Date((long) time);
                return date.toString();
            }
        }

    }
}

Modified Above Answer:

public class TimeAgo {



   public String covertTimeToText(String dataDate) {

        String convertTime = null;
    String suffix = "ago";

    try {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
        Date pasTime = dateFormat.parse(dataDate);

        Date nowTime = new Date();

        long dateDiff = nowTime.getTime() - pasTime.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) {
            if (second == 1) {
                convertTime = second + " second " + suffix;
            } else {
                convertTime = second + " seconds " + suffix;
            }
        } else if (minute < 60) {
            if (minute == 1) {
                convertTime = minute + " minute " + suffix;
            } else {
                convertTime = minute + " minutes " + suffix;
            }
        } else if (hour < 24) {
            if (hour == 1) {
                convertTime = hour + " hour " + suffix;
            } else {
                convertTime = hour + " hours " + suffix;
            }
        } else if (day >= 7) {
            if (day >= 365) {
                long tempYear = day / 365;
                if (tempYear == 1) {
                    convertTime = tempYear + " year " + suffix;
                } else {
                    convertTime = tempYear + " years " + suffix;
                }
            } else if (day >= 30) {
                long tempMonth = day / 30;
                if (tempMonth == 1) {
                    convertTime = (day / 30) + " month " + suffix;
                } else {
                    convertTime = (day / 30) + " months " + suffix;
                }
            } else {
                long tempWeek = day / 7;
                if (tempWeek == 1) {
                    convertTime = (day / 7) + " week " + suffix;
                } else {
                    convertTime = (day / 7) + " weeks " + suffix;
                }
            }
        } else {
            if (day == 1) {
                convertTime = day + " day " + suffix;
            } else {
                convertTime = day + " days " + suffix;
            }
        }

    } catch (ParseException e) {
        e.printStackTrace();
        Log.e("TimeAgo", e.getMessage() + "");
    }
    return convertTime;
   }

}

As I went through all the answers, there are a bunch of ways to get the solution for this query anyhow the below answer does not require any third-party modules or any native util classes, you can get the result from native Java using the below technique also it's a memory-optimized answer, it won't consume your memory much.

Usage:

HumanDateUtils.durationFromNow(startDate)

You can customize this method as your wish by adding ago or seen.

import java.util.Date;

public class HumanDateUtils {

    public static String durationFromNow(Date startDate) {

        long different = System.currentTimeMillis() - startDate.getTime();

        long secondsInMilli = 1000;
        long minutesInMilli = secondsInMilli * 60;
        long hoursInMilli = minutesInMilli * 60;
        long daysInMilli = hoursInMilli * 24;

        long elapsedDays = different / daysInMilli;
        different = different % daysInMilli;

        long elapsedHours = different / hoursInMilli;
        different = different % hoursInMilli;

        long elapsedMinutes = different / minutesInMilli;
        different = different % minutesInMilli;

        long elapsedSeconds = different / secondsInMilli;

        String output = "";
        if (elapsedDays > 0) output += elapsedDays + "days ";
        if (elapsedDays > 0 || elapsedHours > 0) output += elapsedHours + " hours ";
        if (elapsedHours > 0 || elapsedMinutes > 0) output += elapsedMinutes + " minutes ";
        if (elapsedMinutes > 0 || elapsedSeconds > 0) output += elapsedSeconds + " seconds";

        return output;
    }
}

Output:
12 days 12 hours 25 minutes 4 seconds

Reference: Human Readable Date - Java

java.time

The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.

Also, quoted below is a notice from the home page of Joda-Time:

Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.

Solution using java.time, the modern Date-Time API: You can use java.time.Duration which was introduced with Java-8 as part of JSR-310 implementation to model ISO_8601#Duration. With Java-9 some more convenience methods were introduced.

Demo:

import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.TimeUnit;

public class Main {
    public static void main(String args[]) {
        String strDateTime = "2016-01-24T16:00:00.000Z";
        Instant then = Instant.parse(strDateTime);
        Instant now = Instant.now();
        Duration duration = Duration.between(then, now);
        System.out.println(duration);

        // ####################################Java-8####################################
        String formatted = String.format("%d days %02d hours %02d minutes %02d seconds %02d milliseconds ago",
                duration.toDays(), duration.toHours() % 24, duration.toMinutes() % 60, duration.toSeconds() % 60,
                TimeUnit.MILLISECONDS.convert(duration.toNanos() % 1000_000_000, TimeUnit.NANOSECONDS));
        System.out.println(formatted);
        // ##############################################################################

        // ####################################Java-9####################################
        formatted = String.format("%d days %02d hours %02d minutes %02d seconds %02d milliseconds ago",
                duration.toDaysPart(), duration.toHoursPart(), duration.toMinutesPart(), duration.toSecondsPart(),
                TimeUnit.MILLISECONDS.convert(duration.toNanosPart(), TimeUnit.NANOSECONDS));
        System.out.println(formatted);
        // ####################################Java-9####################################
    }
}

Output:

PT50117H11M53.914442S
2088 days 05 hours 11 minutes 53 seconds 914 milliseconds ago
2088 days 05 hours 11 minutes 53 seconds 914 milliseconds ago

ONLINE DEMO

Learn more about the modern Date-Time API* from Trail: Date Time.


* If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring. Note that Android 8.0 Oreo already provides support for java.time.

too late but try this,

 public static String parseDate(String givenDateString) {
    if (givenDateString.equalsIgnoreCase("")) {
        return "";
    }

    long timeInMilliseconds=0;
    SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
    try {

        Date mDate = sdf.parse(givenDateString);
        timeInMilliseconds = mDate.getTime();
        System.out.println("Date in milli :: " + timeInMilliseconds);
    } catch (ParseException e) {
        e.printStackTrace();
    }


    String result = "now";
    SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");

    String todayDate = formatter.format(new Date());
    Calendar calendar = Calendar.getInstance();

    long dayagolong =  timeInMilliseconds;
    calendar.setTimeInMillis(dayagolong);
    String agoformater = formatter.format(calendar.getTime());

    Date CurrentDate = null;
    Date CreateDate = null;

    try {
        CurrentDate = formatter.parse(todayDate);
        CreateDate = formatter.parse(agoformater);

        long different = Math.abs(CurrentDate.getTime() - CreateDate.getTime());

        long secondsInMilli = 1000;
        long minutesInMilli = secondsInMilli * 60;
        long hoursInMilli = minutesInMilli * 60;
        long daysInMilli = hoursInMilli * 24;

        long elapsedDays = different / daysInMilli;
        different = different % daysInMilli;

        long elapsedHours = different / hoursInMilli;
        different = different % hoursInMilli;

        long elapsedMinutes = different / minutesInMilli;
        different = different % minutesInMilli;

        long elapsedSeconds = different / secondsInMilli;

        different = different % secondsInMilli;
        if (elapsedDays == 0) {
            if (elapsedHours == 0) {
                if (elapsedMinutes == 0) {
                    if (elapsedSeconds < 0) {
                        return "0" + " s";
                    } else {
                        if (elapsedDays > 0 && elapsedSeconds < 59) {
                            return "now";
                        }
                    }
                } else {
                    return String.valueOf(elapsedMinutes) + "mins ago";
                }
            } else {
                return String.valueOf(elapsedHours) + "hr ago";
            }

        } else {
            if (elapsedDays <= 29) {
                return String.valueOf(elapsedDays) + "d ago";

            }
            else if (elapsedDays > 29 && elapsedDays <= 58) {
                return "1Mth ago";
            }
            if (elapsedDays > 58 && elapsedDays <= 87) {
                return "2Mth ago";
            }
            if (elapsedDays > 87 && elapsedDays <= 116) {
                return "3Mth ago";
            }
            if (elapsedDays > 116 && elapsedDays <= 145) {
                return "4Mth ago";
            }
            if (elapsedDays > 145 && elapsedDays <= 174) {
                return "5Mth ago";
            }
            if (elapsedDays > 174 && elapsedDays <= 203) {
                return "6Mth ago";
            }
            if (elapsedDays > 203 && elapsedDays <= 232) {
                return "7Mth ago";
            }
            if (elapsedDays > 232 && elapsedDays <= 261) {
                return "8Mth ago";
            }
            if (elapsedDays > 261 && elapsedDays <= 290) {
                return "9Mth ago";
            }
            if (elapsedDays > 290 && elapsedDays <= 319) {
                return "10Mth ago";
            }
            if (elapsedDays > 319 && elapsedDays <= 348) {
                return "11Mth ago";
            }
            if (elapsedDays > 348 && elapsedDays <= 360) {
                return "12Mth ago";
            }

            if (elapsedDays > 360 && elapsedDays <= 720) {
                return "1 year ago";
            }
        }

    } catch (java.text.ParseException e) {
        e.printStackTrace();
    }
    return result;
}

As a Kotlin extension function (Replace App.context with your own context):

fun Long.msToTimeAgo(): String {
    val seconds = (System.currentTimeMillis() - this) / 1000f

    return when (true) {
        seconds < 60 -> App.context.resources.getQuantityString(R.plurals.seconds_ago, seconds.toInt(), seconds.toInt())
        seconds < 3600 -> {
            val minutes = seconds / 60f
            App.context.resources.getQuantityString(R.plurals.minutes_ago, minutes.toInt(), minutes.toInt())
        }
        seconds < 86400 -> {
            val hours = seconds / 3600f
            App.context.resources.getQuantityString(R.plurals.hours_ago, hours.toInt(), hours.toInt())
        }
        seconds < 604800 -> {
            val days = seconds / 86400f
            App.context.resources.getQuantityString(R.plurals.days_ago, days.toInt(), days.toInt())
        }
        seconds < 2_628_000 -> {
            val weeks = seconds / 604800f
            App.context.resources.getQuantityString(R.plurals.weeks_ago, weeks.toInt(), weeks.toInt())
        }
        seconds < 31_536_000 -> {
            val months = seconds / 2_628_000f
            App.context.resources.getQuantityString(R.plurals.months_ago, months.toInt(), months.toInt())
        }
        else -> {
            val years = seconds / 31_536_000f
            App.context.resources.getQuantityString(R.plurals.years_ago, years.toInt(), years.toInt())
        }
    }
}

Add the following to your string resources:

<plurals name="seconds_ago">
    <item quantity="one">%d second ago</item>
    <item quantity="other">%d seconds ago</item>
</plurals>

<plurals name="minutes_ago">
    <item quantity="one">%d minute ago</item>
    <item quantity="other">%d minutes ago</item>
</plurals>

<plurals name="hours_ago">
    <item quantity="one">%d hour ago</item>
    <item quantity="other">%d hours ago</item>
</plurals>

<plurals name="days_ago">
    <item quantity="one">%d day ago</item>
    <item quantity="other">%d days ago</item>
</plurals>

<plurals name="weeks_ago">
    <item quantity="one">%d week ago</item>
    <item quantity="other">%d weeks ago</item>
</plurals>

<plurals name="months_ago">
    <item quantity="one">%d month ago</item>
    <item quantity="other">%d months ago</item>
</plurals>

<plurals name="years_ago">
    <item quantity="one">%d year ago</item>
    <item quantity="other">%d years ago</item>
</plurals>
Related