"Time Since/Ago" Library for Android/Java

Time Since/Ago Library for Android/Java

From the Google I/O 2012 App:

/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

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;

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

long now = getCurrentTime(ctx);
if (time > now || time <= 0) {
return null;
}

// TODO: localize
final long diff = now - time;
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 {
return diff / DAY_MILLIS + " days ago";
}
}

Time ago for Android/java

What you want to display is called as the Relative time display. Android provides methods
to display time relative to your current time. You don't have to use any third party library just for this purpose.

You can use

DateUtils.getRelativeTimeSpanString(long time, long now, long minResolution)

Refer docs Here

eg.

DateUtils.getRelativeTimeSpanString(your_time_in_milliseconds, current_ time_in_millisecinds,DateUtils.MINUTE_IN_MILLIS);

UPDATE1:

You can try following to pass your date and get the milliseconds for it.

public static long getDateInMillis(String srcDate) {
SimpleDateFormat desiredFormat = new SimpleDateFormat(
"d MMMM yyyy, hh:mm aa");

long dateInMillis = 0;
try {
Date date = desiredFormat.parse(srcDate);
dateInMillis = date.getTime();
return dateInMillis;
} catch (ParseException e) {
Log.d("Exception while parsing date. " + e.getMessage());
e.printStackTrace();
}

return 0;
}

Hope it helps you.

Android - Converting Date to Time ago but it is returning 48 years ago

I will look at your code but I should definitely say that, 48 years ago reminds me 1 Jan 1970. Probably you're sending null or 0 as date to humanizer function.

Edit After Review:

I think the problem is that, you're calculating duration of a date, not difference. If you want to calculate a real date ago, you should send time difference to toDuration function.

Current behavior is quite normal because you send a x-x-2018 date to toDuration function and it returns 48 years ago basically(since zero is 1970). You should send the difference.
For example;

long difference = System.currentTimeMillis() - dateInMillisecond;
String humanizedDate = toDuration(difference);

How to calculate time ago 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.

How to get exact TimeAgo in Android

You can not do that via existing methods of DateUtils. You can use this implementation for that, but keep in mind that it works correct only for past (weeks, month, years). If you want to handle future then you need care about that use case.

public static final long AVERAGE_MONTH_IN_MILLIS = DateUtils.DAY_IN_MILLIS * 30;

private String getRelationTime(long time) {
final long now = new Date().getTime();
final long delta = now - time;
long resolution;
if (delta <= DateUtils.MINUTE_IN_MILLIS) {
resolution = DateUtils.SECOND_IN_MILLIS;
} else if (delta <= DateUtils.HOUR_IN_MILLIS) {
resolution = DateUtils.MINUTE_IN_MILLIS;
} else if (delta <= DateUtils.DAY_IN_MILLIS) {
resolution = DateUtils.HOUR_IN_MILLIS;
} else if (delta <= DateUtils.WEEK_IN_MILLIS) {
resolution = DateUtils.DAY_IN_MILLIS;
} else if (delta <= AVERAGE_MONTH_IN_MILLIS) {
return Integer.toString((int) (delta / DateUtils.WEEK_IN_MILLIS)) + " weeks(s) ago";
} else if (delta <= DateUtils.YEAR_IN_MILLIS) {
return Integer.toString((int) (delta / AVERAGE_MONTH_IN_MILLIS)) + " month(s) ago";
} else {
return Integer.toString((int) (delta / DateUtils.YEAR_IN_MILLIS)) + " year(s) ago";
}
return DateUtils.getRelativeTimeSpanString(time, now, resolution).toString();
}

Displaying time ago like Twitter

You can use JodaTime to achieve this:

Add the dependency to your app level Build.Gradle file like so:

compile 'net.danlew:android.joda:2.9.4.1'

and then you can just simply implement this functionality.

private String time = "Just Now";

private String how_long_ago(String created_at) {
DateTime sinceGraduation = new DateTime(created_at, GregorianChronology.getInstance());
DateTime currentDate = new DateTime(); //current date

Months diffInMonths = Months.monthsBetween(sinceGraduation, currentDate);
Days diffInDays = Days.daysBetween(sinceGraduation, currentDate);
Hours diffInHours = Hours.hoursBetween(sinceGraduation, currentDate);
Minutes diffInMinutes = Minutes.minutesBetween(sinceGraduation, currentDate);
Seconds seconds = Seconds.secondsBetween(sinceGraduation, currentDate);

Log.d("since grad", "before if " + sinceGraduation);
if (diffInDays.isGreaterThan(Days.days(31))) {
time = diffInMonths.getMonths() + " months ago";
if (diffInMonths.getMonths() == 1) {
time = diffInMonths.getMonths() + " month ago";
} else {
time = diffInMonths.getMonths() + " months ago";
}
return time;
} else if (diffInHours.isGreaterThan(Hours.hours(24))) {
if (diffInDays.getDays() == 1) {
time = diffInDays.getDays() + " day ago";
} else {
time = diffInDays.getDays() + " days ago";
}
return time;
} else if (diffInMinutes.isGreaterThan(Minutes.minutes(60))) {
if (diffInHours.getHours() == 1) {
time = diffInHours.getHours() + " hour ago";
} else {
time = diffInHours.getHours() + " hours ago";
}
return time;
} else if (seconds.isGreaterThan(Seconds.seconds(60))) {
if (diffInMinutes.getMinutes() == 1) {
time = diffInMinutes.getMinutes() + " minute ago";
} else {
time = diffInMinutes.getMinutes() + " minutes ago";
}
return time;
} else if (seconds.isLessThan(Seconds.seconds(60))) {
return time;
}
Log.d("since grad", "" + sinceGraduation);
return time;
}

Just change the String output for time to achieve the desired '1m'

Note: you can use localization to change the string through your resources.

see Android Localization Tutorial for more details.

Android: How to build since date from server date

OK. It turns out that DateUtils.getRelativeTimeSpanString(date.getTime()) returns a RELATIVE duration (e.g."yesterday" or "30 minutes ago") EXCEPT if that duration is greater than a week, in which case it returns an ABSOLUTE (look at the code) date...


Nothing in the documentation says so... But that's a fact. Another drawback to most of the Android solutions is that the messages are not localized ("3 minutes ago" does not work in French nor Spanish nor any other language for that matter). So I will probably end up writing my own library for this.


Bottom line is that if you use English and want to display the date as an absolute date if it is more than a week ago, the above code works.



Related Topics



Leave a reply



Submit