I want to take two times (in seconds since epoch) and show the difference between the two in formats like:
- 2 minutes
- 1 hour, 15 minutes
- 3 hours, 9 minutes
- 1 minute ago
- 1 hour, 2 minutes ago
How can I accomplish this??
I want to take two times (in seconds since epoch) and show the difference between the two in formats like:
How can I accomplish this??
I'm not an expert in Java, but you can do t1-t2=t3(in seconds) then divide that by 60, would give you minutes, by another 60 would give you seconds. Then it's just a matter of figuring out how many divisions you need.
Hope it helps.
You can also try JODA if the simple solution is unacceptable. It deals with Durations nicely.
I always start with Joda Time. Working with dates and times in Java is always "fun" but Joda Time takes the strain off.
They have Interval and Duration classes which do half of what you are looking for. Not sure if they have a function for outputing in readable format though. I'll keep looking.
HTH
long time1, time2;
time1 = System.currentMillis();
.. drink coffee
time2 = System.currentMillis();
long difference = time2 - time1 // millies between time1 and time2
java.util.Date differneceDate = new Date(difference);
To create a string like "2 Minutes" you should use DateFormatter/DateFormat. You can find more details on this in the the Java API spec (java.sun.com).
OK, after a brief peruse of the API it seems that you could do the following: -
HTH
Date start = new Date(1167627600000L); // JANUARY_1_2007
Date end = new Date(1175400000000L); // APRIL_1_2007
long diffInSeconds = (end.getTime() - start.getTime()) / 1000;
long diff[] = new long[] { 0, 0, 0, 0 };
/* sec */diff[3] = (diffInSeconds >= 60 ? diffInSeconds % 60 : diffInSeconds);
/* min */diff[2] = (diffInSeconds = (diffInSeconds / 60)) >= 60 ? diffInSeconds % 60 : diffInSeconds;
/* hours */diff[1] = (diffInSeconds = (diffInSeconds / 60)) >= 24 ? diffInSeconds % 24 : diffInSeconds;
/* days */diff[0] = (diffInSeconds = (diffInSeconds / 24));
System.out.println(String.format(
"%d day%s, %d hour%s, %d minute%s, %d second%s ago",
diff[0],
diff[0] > 1 ? "s" : "",
diff[1],
diff[1] > 1 ? "s" : "",
diff[2],
diff[2] > 1 ? "s" : "",
diff[3],
diff[3] > 1 ? "s" : ""));
If your time-spans cross daylight-saving (summer-time) boundaries, do you want to report the number of days?
For example, 23:00 to 23:00 the next day is always a day but may be 23, 24 or 25 hours depending on whether the you cross a daylight-savings transition.
If you care about that, make sure you factor it into your choice.
Yup awakened the dead I have, but here's my improved implementation based on @mtim posted code, as this thread comes almost on top of the searches so I am messing with the sleepy hollow,
public static String getFriendlyTime(Date dateTime) {
StringBuffer sb = new StringBuffer();
Date current = Calendar.getInstance().getTime();
long diffInSeconds = (current.getTime() - dateTime.getTime()) / 1000;
/*long diff[] = new long[]{0, 0, 0, 0};
/* sec * diff[3] = (diffInSeconds >= 60 ? diffInSeconds % 60 : diffInSeconds);
/* min * diff[2] = (diffInSeconds = (diffInSeconds / 60)) >= 60 ? diffInSeconds % 60 : diffInSeconds;
/* hours * diff[1] = (diffInSeconds = (diffInSeconds / 60)) >= 24 ? diffInSeconds % 24 : diffInSeconds;
/* days * diff[0] = (diffInSeconds = (diffInSeconds / 24));
*/
long sec = (diffInSeconds >= 60 ? diffInSeconds % 60 : diffInSeconds);
long min = (diffInSeconds = (diffInSeconds / 60)) >= 60 ? diffInSeconds % 60 : diffInSeconds;
long hrs = (diffInSeconds = (diffInSeconds / 60)) >= 24 ? diffInSeconds % 24 : diffInSeconds;
long days = (diffInSeconds = (diffInSeconds / 24)) >= 30 ? diffInSeconds % 30 : diffInSeconds;
long months = (diffInSeconds = (diffInSeconds / 30)) >= 12 ? diffInSeconds % 12 : diffInSeconds;
long years = (diffInSeconds = (diffInSeconds / 12));
if (years > 0) {
if (years == 1) {
sb.append("a year");
} else {
sb.append(years + " years");
}
if (years <= 6 && months > 0) {
if (months == 1) {
sb.append(" and a month");
} else {
sb.append(" and " + months + " months");
}
}
} else if (months > 0) {
if (months == 1) {
sb.append("a month");
} else {
sb.append(months + " months");
}
if (months <= 6 && days > 0) {
if (days == 1) {
sb.append(" and a day");
} else {
sb.append(" and " + days + " days");
}
}
} else if (days > 0) {
if (days == 1) {
sb.append("a day");
} else {
sb.append(days + " days");
}
if (days <= 3 && hrs > 0) {
if (hrs == 1) {
sb.append(" and an hour");
} else {
sb.append(" and " + hrs + " hours");
}
}
} else if (hrs > 0) {
if (hrs == 1) {
sb.append("an hour");
} else {
sb.append(hrs + " hours");
}
if (min > 1) {
sb.append(" and " + min + " minutes");
}
} else if (min > 0) {
if (min == 1) {
sb.append("a minute");
} else {
sb.append(min + " minutes");
}
if (sec > 1) {
sb.append(" and " + sec + " seconds");
}
} else {
if (sec <= 1) {
sb.append("about a second");
} else {
sb.append("about " + sec + " seconds");
}
}
sb.append(" ago");
/*String result = new String(String.format(
"%d day%s, %d hour%s, %d minute%s, %d second%s ago",
diff[0],
diff[0] > 1 ? "s" : "",
diff[1],
diff[1] > 1 ? "s" : "",
diff[2],
diff[2] > 1 ? "s" : "",
diff[3],
diff[3] > 1 ? "s" : ""));*/
return sb.toString();
}
It obviously can be improved. basically it tries to get the time span more friendly, there are a few limitation though i.e. it would behave strangely if the time passed (parameter) is in future, and its limited up to the days, hours and seconds only (months and years not handled, so that someone else can ;-).
sample outputs are:
, cheers :D
EDIT: now supports months and years :P
Since everyone shouts "YOODAA!!!" but noone posts a concrete example, here's my contribution.
You could also do this with JodaTime. Use Period
to represent a period. To format the period 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()
.appendYears().appendSuffix(" years, ")
.appendMonths().appendSuffix(" months, ")
.appendDays().appendSuffix(" days, ")
.appendHours().appendSuffix(" hours, ")
.appendMinutes().appendSuffix(" minutes, ")
.appendSeconds().appendSuffix(" seconds")
.printZeroNever()
.toFormatter();
String elapsed = formatter.print(period);
System.out.println(elapsed + " ago");
Much more clear and concise, isn't it?
This prints by now
32 years, 1 months, 5 days, 6 hours, 56 minutes, 24 seconds ago
(Cough, old, cough)