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?
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?
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.
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();
}
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) {
StringBuffer res = new StringBuffer();
long temp = 0;
if (duration >= ONE_SECOND) {
temp = duration / ONE_DAY;
if (temp > 0) {
duration -= temp * ONE_DAY;
res.append(temp).append(\" day\").append(temp > 1 ? \"s\" : \"\")
.append(duration >= ONE_MINUTE ? \", \" : \"\");
}
temp = duration / ONE_HOUR;
if (temp > 0) {
duration -= temp * ONE_HOUR;
res.append(temp).append(\" hour\").append(temp > 1 ? \"s\" : \"\")
.append(duration >= ONE_MINUTE ? \", \" : \"\");
}
temp = duration / ONE_MINUTE;
if (temp > 0) {
duration -= temp * ONE_MINUTE;
res.append(temp).append(\" 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
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
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.
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..
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\");
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\";
}
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 are 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.
(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 unfortunatly 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.
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\"
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();
}
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.
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
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?
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\";
}
}
}
}
}
}
}
}
}
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;
}
}
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
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 be 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 this steps until you have the correct formula.
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();
}
}
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();
}
}
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;
} }
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>
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;
}
You can use Java\'s Library [RelativeDateTimeFormatter][1], it does exactly that:
[1]: https://developer.android.com/reference/android/icu/text/RelativeDateTimeFormatter
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\"