I need to calculate the time elapsed from one specific date till开发者_如何学运维 now and display it with the same format as StackOverflow questions, i.e.:
15s ago
2min ago
2hours ago
2days ago
25th Dec 08
Do you know how to achieve it with the Java Joda-Time library? Is there a helper method out there that already implements it, or should I write the algorithm myself?
To calculate the elapsed time with JodaTime, use Period
. To format the elapsed time in the desired human representation, use PeriodFormatter
which you can build by PeriodFormatterBuilder
.
Here's a kickoff example:
DateTime myBirthDate = new DateTime(1978, 3, 26, 12, 35, 0, 0);
DateTime now = new DateTime();
Period period = new Period(myBirthDate, now);
PeriodFormatter formatter = new PeriodFormatterBuilder()
.appendSeconds().appendSuffix(" seconds ago\n")
.appendMinutes().appendSuffix(" minutes ago\n")
.appendHours().appendSuffix(" hours ago\n")
.appendDays().appendSuffix(" days ago\n")
.appendWeeks().appendSuffix(" weeks ago\n")
.appendMonths().appendSuffix(" months ago\n")
.appendYears().appendSuffix(" years ago\n")
.printZeroNever()
.toFormatter();
String elapsed = formatter.print(period);
System.out.println(elapsed);
This prints by now
3 seconds ago 51 minutes ago 7 hours ago 6 days ago 10 months ago 31 years ago
(Cough, old, cough) You see that I've taken months and years into account as well and configured it to omit the values when those are zero.
Use PrettyTime for Simple Elapsed Time.
I tried HumanTime as @sfussenegger answered and using JodaTime's Period
but the easiest and cleanest method for human readable elapsed time that I found was the PrettyTime library.
Here's a couple of simple examples with input and output:
Five Minutes Ago
DateTime fiveMinutesAgo = DateTime.now().minusMinutes( 5 );
new PrettyTime().format( fiveMinutesAgo.toDate() );
// Outputs: "5 minutes ago"
Awhile Ago
DateTime birthday = new DateTime(1978, 3, 26, 12, 35, 0, 0);
new PrettyTime().format( birthday.toDate() );
// Outputs: "4 decades ago"
CAUTION: I've tried playing around with the library's more precise functionality, but it produces some odd results so use it with care and in non-life threatening projects.
JP
You can do this with a PeriodFormatter but you don't have to go to the effort of making your own PeriodFormatBuilder as in other answers. If it suits your case, you can just use the default formatter:
Period period = new Period(startDate, endDate);
System.out.println(PeriodFormat.getDefault().print(period))
(hat tip to this answer on a similar question, I'm cross-posting for discoverability)
There is a small helper class called HumanTime that I'm pretty happy with.
This is using mysql timestamp to get elapsed time to now. Singular and plular is managed. Only display the max time.
NOTE: set your own timezone.
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;
}
Here is my solution, using joda time
.
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)
{
if(time < 1000000000000L)
{
time *= 1000;
}
long now = System.currentTimeMillis();
if(time > now || time <= 0)
{
return null;
}
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";
}
}
How to use the method:
Just call the method and pass in time in milliseconds
.
For example:
long now = System.currentTimeMillis();
getTimeAgo(now);
精彩评论