问题
I create J2SE application and this application needs to format two times in milliseconds into a string that represents the interval between this two times.
long time1 = 1334331041677L; //Fri Apr 13 17:30:41 CEST 2012
long time2 = time1+1000*60*2; //Fri Apr 13 17:32:41 CEST 2012
and I would like to get something like "00:02:00". This would be simple, but I need to format interval which is long from few seconds up to several years - so the library should handle it. Ideally is if this library could format the interval according to the habbits of the country (if any).
I have searched throught the questions and answers and solution for me could be Jodatime or Lang library from Apache Commons. Could you provide me some recommendation which library from these solves my requirements in better way? Thank you in advance.
回答1:
PeriodFormat in Joda Time is probably what you want - but you'll need to think very carefully about how you want to format values of more than a day. Bear in mind that months and years are of variable lengths - if you're happy to have the largest unit as a day, that would probably keep things simple.
You should also be aware of the difference in Joda Time between a Period
(which can include things like "months") and a Duration
which is a fixed number of milliseconds. Normalization between the two touches on exactly the problems mentioned above :) Basically, you should work out whether you're interested in the difference in elapsed time between two instants in time, or the difference in "calendar" time between two local date/time values. For example, between midnight and 2am on a particular date in a particular time zone may be 1 hour, 2 hours or 3 hours of elapsed time...
回答2:
You can use standard Java Calendar
for intervals up to one day (24 hours). It is not possible to use this trick for longer periods (days, years), though...
long start = System.currentTimeMillis();
/*
* perform the measured activity here,
* let's say it will take 2 minutes 5 seconds => 125 seconds => 125000ms
*/
Thread.sleep(125 * 1000);
long stop = System.currentTimeMillis();
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
c.setTimeInMillis(c.getTimeInMillis() + (stop - start));
DateFormat df = new SimpleDateFormat("HH:mm:ss.SSS");
System.out.println(df.format(c.getTime()));
回答3:
If I understood you correctly, the following (using Joda Time) should help
import org.joda.time.DateTime;
import org.joda.time.Period;
private String formatDuration(DateTime dt1, DateTime dt2) {
Period period = new Period(dt1, dt2);
String str = String.format("%s:%02d:%02d:%02d:%02d:%02d",
period.getYears(), period.getMonths(), period.getDays(),
period.getHours(), period.getMinutes(), period.getSeconds());
// Ignoring milliseconds
String[] tokens = str.split(":");
boolean currNonZero = false, flag = false, isFirst = true;
int ctr = 0, pos = 0;
StringBuilder sb = new StringBuilder();
for (String token : tokens) {
pos++;
int val = Integer.parseInt(token);
currNonZero = (val > 0);
if ((ctr < 3 && (flag || currNonZero)) || (ctr == 0 && pos > 3)) {
if (isFirst) { isFirst = false; }
else { sb.append(":"); }
sb.append(token);
flag = (++ctr < 3);
}
}
return sb.toString();
}
A few tests,
DateTime dt1 = new DateTime(2012, 1, 1, 8, 3, 5, 0);
DateTime dt2 = new DateTime(2012, 1, 2, 9, 5, 6, 0);
DateTime dt3 = new DateTime(2012, 2, 3, 11, 3, 5, 0);
DateTime dt4 = new DateTime(2012, 2, 3, 11, 3, 10, 0);
DateTime dt5 = new DateTime(2012, 2, 3, 11, 3, 10, 5); //5 millis away from dt4
formatDuration(dt1, dt2); // Returns "01:01:01"
formatDuration(dt1, dt3); // Returns "01:02:03"
formatDuration(dt3, dt4); // Returns "00:00:05"
formatDuration(dt4, dt5); // Returns "00:00:00"
回答4:
According to this answer, this is the most efficient way of formatting elapsed time:
public static String combinationFormatter(final long millis) {
long seconds = TimeUnit.MILLISECONDS.toSeconds(millis)
- TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis));
long minutes = TimeUnit.MILLISECONDS.toMinutes(millis)
- TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis));
long hours = TimeUnit.MILLISECONDS.toHours(millis);
StringBuilder b = new StringBuilder();
b.append(hours == 0 ? "00" : hours < 10 ? String.valueOf("0" + hours) :
String.valueOf(hours));
b.append(":");
b.append(minutes == 0 ? "00" : minutes < 10 ? String.valueOf("0" + minutes) :
String.valueOf(minutes));
b.append(":");
b.append(seconds == 0 ? "00" : seconds < 10 ? String.valueOf("0" + seconds) :
String.valueOf(seconds));
return b.toString();
}
回答5:
Detailed Answer: https://stackoverflow.com/a/39600534/5330578
Simple formatting for elapsed time less than 24h. Over 24h the code will only display the hours within the next day and won't add the elapsed day to the hours.
public static String formatElapsedTime(long milliseconds) {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
return sdf.format(milliseconds);
}
来源:https://stackoverflow.com/questions/10144072/how-to-format-time-intervals-in-java