如何将毫秒转换为Java中的“X mins,x秒”?
我想用System.currentTimeMillis()
当用户在我的程序中开始一些东西时logging时间。 当他完成时,我将从start
variables中减去当前的System.currentTimeMillis()
,并且我想通过人类可读的格式(例如“XX小时,XX分钟,XX秒”或者“XX分钟” ,XX秒“,因为它不可能需要一个小时。
什么是最好的方法来做到这一点?
使用java.util.concurrent.TimeUnit
类:
String.format("%d min, %d sec", TimeUnit.MILLISECONDS.toMinutes(millis), TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)) );
注意: TimeUnit
是Java 1.5规范的一部分,但从Java 1.6开始添加了toMinutes
。
要为值0-9添加前导零,请执行以下操作:
String.format("%02d min, %02d sec", TimeUnit.MILLISECONDS.toMinutes(millis), TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)) );
如果TimeUnit
或toMinutes
不受支持(例如在API版本9之前的Android上),请使用以下公式:
int seconds = (int) (milliseconds / 1000) % 60 ; int minutes = (int) ((milliseconds / (1000*60)) % 60); int hours = (int) ((milliseconds / (1000*60*60)) % 24); //etc...
基于@ siddhadev的回答,我写了一个函数来最近这样做。 只是以为我会分享,以防有人发现它有用:
/** * Convert a millisecond duration to a string format * * @param millis A duration to convert to a string form * @return A string of the form "X Days Y Hours Z Minutes A Seconds". */ public static String getDurationBreakdown(long millis) { if(millis < 0) { throw new IllegalArgumentException("Duration must be greater than zero!"); } long days = TimeUnit.MILLISECONDS.toDays(millis); millis -= TimeUnit.DAYS.toMillis(days); long hours = TimeUnit.MILLISECONDS.toHours(millis); millis -= TimeUnit.HOURS.toMillis(hours); long minutes = TimeUnit.MILLISECONDS.toMinutes(millis); millis -= TimeUnit.MINUTES.toMillis(minutes); long seconds = TimeUnit.MILLISECONDS.toSeconds(millis); StringBuilder sb = new StringBuilder(64); sb.append(days); sb.append(" Days "); sb.append(hours); sb.append(" Hours "); sb.append(minutes); sb.append(" Minutes "); sb.append(seconds); sb.append(" Seconds"); return(sb.toString()); }
请享用!
long time = 1536259; return (new SimpleDateFormat("mm:ss:SSS")).format(new Date(time));
打印:
25:36:259
呃…一秒钟有多less毫秒? 在一分钟之内? 司并不那么辛苦。
int seconds = (int) ((milliseconds / 1000) % 60); int minutes = (int) ((milliseconds / 1000) / 60);
继续这样的几个小时,几天,几周,几个月,一年,几十年,不pipe。
我不会为了这个额外的依赖(毕竟分区并不那么辛苦),但是如果你使用的是Commons Lang,那么就有DurationFormatUtils 。
无论是手部,还是使用SimpleDateFormat API 。
long start = System.currentTimeMillis(); // do your work... long elapsed = System.currentTimeMillis() - start; DateFormat df = new SimpleDateFormat("HH 'hours', mm 'mins,' ss 'seconds'"); df.setTimeZone(TimeZone.getTimeZone("GMT+0")); System.out.println(df.format(new Date(elapsed)));
Bombe编辑 :在评论中显示,这种方法只适用于较短的时间(即不到一天)。
在Java 8中使用java.time包 :
Instant start = Instant.now(); Thread.sleep(63553); Instant end = Instant.now(); System.out.println(Duration.between(start, end));
输出采用ISO 8601持续时间格式 : PT1M3.553S
(1分钟和3.553秒)。
只要添加更多的信息,如果你想格式如:HH:mm:ss
0 <= HH <=无限
0 <= mm <60
0 <= ss <60
用这个:
int h = (int) ((startTimeInMillis / 1000) / 3600); int m = (int) (((startTimeInMillis / 1000) / 60) % 60); int s = (int) ((startTimeInMillis / 1000) % 60);
我现在刚刚遇到了这个问题,并且明白了这一点
我认为最好的办法是:
String.format("%d min, %d sec", TimeUnit.MILLISECONDS.toSeconds(length)/60, TimeUnit.MILLISECONDS.toSeconds(length) % 60 );
最短的解决scheme:
这可能是最短的也是时区的问题。
System.out.printf("%tT", millis-TimeZone.getDefault().getRawOffset());
例如:
00:18:32
说明:
%tT
是24小时制格式化为%tH:%tM:%tS
。
%tT
也接受longs作为input,所以不需要创build一个Date
。 printf()
将只显示以毫秒为单位的时间,但在当前时区中,因此我们必须减去当前时区的原始偏移量,因此0毫秒将是0小时,而不是当前时区的时间偏移量值。
注意#1:如果你需要结果作为一个String
,你可以这样得到它:
String t = String.format("%tT", millis-TimeZone.getDefault().getRawOffset());
注#2:如果millis
less于一天,这只会给出正确的结果,因为date部分不包含在输出中。
乔达时间
使用乔达时间 :
DateTime startTime = new DateTime(); // do something DateTime endTime = new DateTime(); Duration duration = new Duration(startTime, endTime); Period period = duration.toPeriod().normalizedStandard(PeriodType.time()); System.out.println(PeriodFormat.getDefault().print(period));
适用于Android 9以下的Android
(String.format("%d hr %d min, %d sec", millis/(1000*60*60), (millis%(1000*60*60))/(1000*60), ((millis%(1000*60*60))%(1000*60))/1000))
不到一个小时,我更喜欢:
long millis = ... System.out.printf("%1$TM:%1$TS", millis); // or String str = String.format("%1$TM:%1$TS", millis);
为更长的intervalls:
private static final long HOUR = TimeUnit.HOURS.toMillis(1); ... if (millis < HOUR) { System.out.printf("%1$TM:%1$TS%n", millis); } else { System.out.printf("%d:%2$TM:%2$TS%n", millis / HOUR, millis % HOUR); }
long startTime = System.currentTimeMillis(); // do your work... long endTime=System.currentTimeMillis(); long diff=endTime-startTime; long hours=TimeUnit.MILLISECONDS.toHours(diff); diff=diff-(hours*60*60*1000); long min=TimeUnit.MILLISECONDS.toMinutes(diff); diff=diff-(min*60*1000); long seconds=TimeUnit.MILLISECONDS.toSeconds(diff); //hour, min and seconds variables contains the time elapsed on your work
回顾上面的@ brent-nash贡献,我们可以使用模函数而不是减法,并对结果string使用String.format方法:
/** * Convert a millisecond duration to a string format * * @param millis A duration to convert to a string form * @return A string of the form "X Days Y Hours Z Minutes A Seconds B Milliseconds". */ public static String getDurationBreakdown(long millis) { if (millis < 0) { throw new IllegalArgumentException("Duration must be greater than zero!"); } long days = TimeUnit.MILLISECONDS.toDays(millis); long hours = TimeUnit.MILLISECONDS.toHours(millis) % 24; long minutes = TimeUnit.MILLISECONDS.toMinutes(millis) % 60; long seconds = TimeUnit.MILLISECONDS.toSeconds(millis) % 60; long milliseconds = millis % 1000; return String.format("%d Days %d Hours %d Minutes %d Seconds %d Milliseconds", days, hours, minutes, seconds, milliseconds); }
我简单的计算:
String millisecToTime(int millisec) { int sec = millisec/1000; int second = sec % 60; int minute = sec / 60; if (minute >= 60) { int hour = minute / 60; minute %= 60; return hour + ":" + (minute < 10 ? "0" + minute : minute) + ":" + (second < 10 ? "0" + second : second); } return minute + ":" + (second < 10 ? "0" + second : second); }
快乐编码:)
这是一个基于布伦特纳什答案的答案,希望有帮助!
public static String getDurationBreakdown(long millis) { String[] units = {" Days ", " Hours ", " Minutes ", " Seconds "}; Long[] values = new Long[units.length]; if(millis < 0) { throw new IllegalArgumentException("Duration must be greater than zero!"); } values[0] = TimeUnit.MILLISECONDS.toDays(millis); millis -= TimeUnit.DAYS.toMillis(values[0]); values[1] = TimeUnit.MILLISECONDS.toHours(millis); millis -= TimeUnit.HOURS.toMillis(values[1]); values[2] = TimeUnit.MILLISECONDS.toMinutes(millis); millis -= TimeUnit.MINUTES.toMillis(values[2]); values[3] = TimeUnit.MILLISECONDS.toSeconds(millis); StringBuilder sb = new StringBuilder(64); boolean startPrinting = false; for(int i = 0; i < units.length; i++){ if( !startPrinting && values[i] != 0) startPrinting = true; if(startPrinting){ sb.append(values[i]); sb.append(units[i]); } } return(sb.toString()); }
如果你知道时间差不到一个小时,那么你可以使用下面的代码:
Calendar c1 = Calendar.getInstance(); Calendar c2 = Calendar.getInstance(); c2.add(Calendar.MINUTE, 51); long diff = c2.getTimeInMillis() - c1.getTimeInMillis(); c2.set(Calendar.MINUTE, 0); c2.set(Calendar.HOUR, 0); c2.set(Calendar.SECOND, 0); DateFormat df = new SimpleDateFormat("mm:ss"); long diff1 = c2.getTimeInMillis() + diff; System.out.println(df.format(new Date(diff1)));
这将导致:51:00
这个答案类似于上面的一些答案。 不过,我觉得这样做会有好处,因为与其他答案不同的是,这将删除任何额外的逗号或空格,并处理缩写。
/** * Converts milliseconds to "x days, x hours, x mins, x secs" * * @param millis * The milliseconds * @param longFormat * {@code true} to use "seconds" and "minutes" instead of "secs" and "mins" * @return A string representing how long in days/hours/minutes/seconds millis is. */ public static String millisToString(long millis, boolean longFormat) { if (millis < 1000) { return String.format("0 %s", longFormat ? "seconds" : "secs"); } String[] units = { "day", "hour", longFormat ? "minute" : "min", longFormat ? "second" : "sec" }; long[] times = new long[4]; times[0] = TimeUnit.DAYS.convert(millis, TimeUnit.MILLISECONDS); millis -= TimeUnit.MILLISECONDS.convert(times[0], TimeUnit.DAYS); times[1] = TimeUnit.HOURS.convert(millis, TimeUnit.MILLISECONDS); millis -= TimeUnit.MILLISECONDS.convert(times[1], TimeUnit.HOURS); times[2] = TimeUnit.MINUTES.convert(millis, TimeUnit.MILLISECONDS); millis -= TimeUnit.MILLISECONDS.convert(times[2], TimeUnit.MINUTES); times[3] = TimeUnit.SECONDS.convert(millis, TimeUnit.MILLISECONDS); StringBuilder s = new StringBuilder(); for (int i = 0; i < 4; i++) { if (times[i] > 0) { s.append(String.format("%d %s%s, ", times[i], units[i], times[i] == 1 ? "" : "s")); } } return s.toString().substring(0, s.length() - 2); } /** * Converts milliseconds to "x days, x hours, x mins, x secs" * * @param millis * The milliseconds * @return A string representing how long in days/hours/mins/secs millis is. */ public static String millisToString(long millis) { return millisToString(millis, false); }
我已经在另一个答案中涵盖了这一点,但你可以做到:
public static Map<TimeUnit,Long> computeDiff(Date date1, Date date2) { long diffInMillies = date2.getTime() - date1.getTime(); List<TimeUnit> units = new ArrayList<TimeUnit>(EnumSet.allOf(TimeUnit.class)); Collections.reverse(units); Map<TimeUnit,Long> result = new LinkedHashMap<TimeUnit,Long>(); long milliesRest = diffInMillies; for ( TimeUnit unit : units ) { long diff = unit.convert(milliesRest,TimeUnit.MILLISECONDS); long diffInMilliesForUnit = unit.toMillis(diff); milliesRest = milliesRest - diffInMilliesForUnit; result.put(unit,diff); } return result; }
输出类似于Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0}
。
根据目标语言环境,了解如何国际化这些数据取决于您。
对于正确的string(“1小时,3秒”,“3分钟”,但不是“0小时,0分钟,3秒”)我写这个代码:
int seconds = (int)(millis / 1000) % 60 ; int minutes = (int)((millis / (1000*60)) % 60); int hours = (int)((millis / (1000*60*60)) % 24); int days = (int)((millis / (1000*60*60*24)) % 365); int years = (int)(millis / 1000*60*60*24*365); ArrayList<String> timeArray = new ArrayList<String>(); if(years > 0) timeArray.add(String.valueOf(years) + "y"); if(days > 0) timeArray.add(String.valueOf(days) + "d"); if(hours>0) timeArray.add(String.valueOf(hours) + "h"); if(minutes>0) timeArray.add(String.valueOf(minutes) + "min"); if(seconds>0) timeArray.add(String.valueOf(seconds) + "sec"); String time = ""; for (int i = 0; i < timeArray.size(); i++) { time = time + timeArray.get(i); if (i != timeArray.size() - 1) time = time + ", "; } if (time == "") time = "0 sec";
我修改了@MyKuLLSKI的答案并增加了plurlization的支持。 我花了几秒钟,因为我不需要他们,尽pipe如果你需要它可以重新添加它。
public static String intervalToHumanReadableTime(int intervalMins) { if(intervalMins <= 0) { return "0"; } else { long intervalMs = intervalMins * 60 * 1000; long days = TimeUnit.MILLISECONDS.toDays(intervalMs); intervalMs -= TimeUnit.DAYS.toMillis(days); long hours = TimeUnit.MILLISECONDS.toHours(intervalMs); intervalMs -= TimeUnit.HOURS.toMillis(hours); long minutes = TimeUnit.MILLISECONDS.toMinutes(intervalMs); StringBuilder sb = new StringBuilder(12); if (days >= 1) { sb.append(days).append(" day").append(pluralize(days)).append(", "); } if (hours >= 1) { sb.append(hours).append(" hour").append(pluralize(hours)).append(", "); } if (minutes >= 1) { sb.append(minutes).append(" minute").append(pluralize(minutes)); } else { sb.delete(sb.length()-2, sb.length()-1); } return(sb.toString()); } } public static String pluralize(long val) { return (Math.round(val) > 1 ? "s" : ""); }
Java 9的答案(尚未testing):
Duration elapsedTime = Duration.ofMillis(millisDiff); String humanReadableElapsedTime = String.format( "%d hours, %d mins, %d seconds", elapsedTime.toHours(), elapsedTime.toMinutesPart(), elapsedTime.toSecondsPart());
如果您想在格式化之前四舍五入整秒:
elapsedTime = elapsedTime.plusMillis(500).truncatedTo(ChronoUnit.SECONDS);
如果它们是0,我将把它留给读者如何排除小时数。如何使用前导零来打印分钟和秒数,如果您愿意的话,它们总是两位数字(提示: String.format()
很容易) 。