如何将毫秒转换为“hh:mm:ss”格式?
Posted
技术标签:
【中文标题】如何将毫秒转换为“hh:mm:ss”格式?【英文标题】:How to convert milliseconds to "hh:mm:ss" format? 【发布时间】:2012-02-20 02:08:45 【问题描述】:我很困惑。在偶然发现this 线程后,我试图弄清楚如何格式化具有hh:mm:ss
格式的倒数计时器。
这是我的尝试 -
//hh:mm:ss
String.format("%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis) -
TimeUnit.MINUTES.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
TimeUnit.MILLISECONDS.toSeconds(millis) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
所以,当我尝试像3600000ms
这样的值时,我得到01:59:00
,这是错误的,因为它应该是01:00:00
。显然我的逻辑有问题,但目前我看不到它是什么!
谁能帮忙?
编辑 -
修复它。这是将毫秒格式化为hh:mm:ss
格式的正确方法-
//hh:mm:ss
String.format("%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis) -
TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
TimeUnit.MILLISECONDS.toSeconds(millis) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))));
问题是这个TimeUnit.MINUTES.toMinutes(TimeUnit.MILLISECONDS.toHours(millis))
。应该是这个TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis))
。
【问题讨论】:
3,600,000 毫秒是 3,600 秒、60 分钟或 1 小时。不应该是00:59:59
,应该是01:00:00
。
【参考方案1】:
你真的很亲密:
String.format("%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis) -
TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)), // The change is in this line
TimeUnit.MILLISECONDS.toSeconds(millis) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
您使用 minutes 而不是 hours 将小时转换为毫秒。
顺便说一句,我喜欢你使用 TimeUnit
API :)
这是一些测试代码:
public static void main(String[] args) throws ParseException
long millis = 3600000;
String hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
System.out.println(hms);
输出:
01:00:00
我意识到我上面的代码可以通过使用模除法而不是减法来大大简化:
String hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis) % TimeUnit.HOURS.toMinutes(1),
TimeUnit.MILLISECONDS.toSeconds(millis) % TimeUnit.MINUTES.toSeconds(1));
仍然对所有魔法值使用TimeUnit
API,并提供完全相同的输出。
【讨论】:
阿门,就像你使用 TimeUnit API 的方式一样 :) 重新发明***不是个好主意! Triton Man 的答案是更好的解决方案。 @محمدباقر 但另一个答案使用外部库,而我的代码仅使用核心 JDK。这取决于您的需求 - 例如,您可能无法使用外部库。不过,另一个答案很好。 @Ozuf 添加.replaceAll("^00:", "")
或 .replaceAll("^00:(00:)?", "")
以删除分钟和小时(如果两者都为零)。
@Ozuf 你分别得到"15:00"
和"10:00:23"
;由于匹配被^
锚定到输入的开头,因此只删除了前导零。【参考方案2】:
通用方法相当简单:
public static String convertSecondsToHMmSs(long seconds)
long s = seconds % 60;
long m = (seconds / 60) % 60;
long h = (seconds / (60 * 60)) % 24;
return String.format("%d:%02d:%02d", h,m,s);
【讨论】:
@Javaman59,你的意思是String.format("%
02 d:%02d:%02d", h,m,s)
?
@KarenAnne。这取决于您是否想要,例如“03:59:59”或“3:59:59”。
时间单位为毫秒,需要用秒乘以1000
作者问的是毫秒,而不是秒!【参考方案3】:
如果你使用的是 apache commons:
DurationFormatUtils.formatDuration(timeInMS, "HH:mm:ss,SSS");
【讨论】:
快捷方式:DurationFormatUtils.formatDurationHMS(timeInMS);
@Jorgesys 为什么它们已经过时了?
它们并没有过时。【参考方案4】:
我用过这个:
String.format("%1$tH:%1$tM:%1$tS.%1$tL", millis);
查看类Formatter的描述。
使用 2400 毫秒的输入查看 runnable example。
【讨论】:
它似乎不起作用,我只是通过 100、1000、1200 测试它,它的响应为 05:30:00 , 05:30:01,05:30:01. @CoDe,它适用于您的时区。您必须位于与 UTC 不同的时区。String.format()
是时区依赖。然而,理想的正确答案应该是时区独立。
@CoDe,它显示的时间与您的时区相对应,必须不同于 UTC。 String.format()
是时区依赖。然而,理想的正确答案应该是时区独立。【参考方案5】:
// New date object from millis
Date date = new Date(millis);
// formattter
SimpleDateFormat formatter= new SimpleDateFormat("HH:mm:ss.SSS");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
// Pass date object
String formatted = formatter.format(date );
您也可以使用新的 DateTime API
var formatted = DateTimeFormatter.ofPattern("HH:mm:ss.SSS")
.withZone(ZoneId.of("UTC"))
.format(Instant.ofEpochMilli(millis));
【讨论】:
这会在超过一天的时间内产生不正确的结果。它将小时数从 23 换回 0,这在这里可能是不可取的。 没有朋友...我认为它仍然可以正常工作。试试今天的日期 SimpleDateFormat sdf = new SimpleDateFormat("hh:mm aa");以防有人想要上午/下午的 12 小时格式【参考方案6】:DateFormat df = new SimpleDateFormat("HH:mm:ss");
String formatted = df.format(aDateObject);
【讨论】:
与***.com/questions/9027317/… 相同的答案,持续时间超过 1 天 它还取决于时区,这意味着在不同时区运行时结果会有所不同。【参考方案7】:这对我有用,使用 kotlin
fun formatToDigitalClock(miliSeconds: Long): String
val hours = TimeUnit.MILLISECONDS.toHours(miliSeconds).toInt() % 24
val minutes = TimeUnit.MILLISECONDS.toMinutes(miliSeconds).toInt() % 60
val seconds = TimeUnit.MILLISECONDS.toSeconds(miliSeconds).toInt() % 60
return when
hours > 0 -> String.format("%d:%02d:%02d", hours, minutes, seconds)
minutes > 0 -> String.format("%02d:%02d", minutes, seconds)
seconds > 0 -> String.format("00:%02d", seconds)
else ->
"00:00"
【讨论】:
非常适合我。这应该是最好的答案,因为它处理零小时【参考方案8】:4 种实现的测试结果
必须对大量数据进行大量格式化,需要最佳性能,因此以下是(令人惊讶的)结果:
for (int i = 0; i
持续时间:
combinationFormatter:196毫秒 格式持续时间:272毫秒 apacheFormat: 754 毫秒格式时间单位:2216 毫秒
public static String apacheFormat(long millis) throws ParseException
return DurationFormatUtils.formatDuration(millis, "HH:mm:ss");
public static String formatTimeUnit(long millis) throws ParseException
String formatted = String.format(
"%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis)
- TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
TimeUnit.MILLISECONDS.toSeconds(millis)
- TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
return formatted;
public static String formatDuration(final long millis)
long seconds = (millis / 1000) % 60;
long minutes = (millis / (1000 * 60)) % 60;
long hours = millis / (1000 * 60 * 60);
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();
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();
【讨论】:
这样的指标有多可靠?我从来没有真正理解过这个过程。 在我连续创建了数千个对象的情况下,我认为这个测试非常有用。好的,不只是设置一些字符串,而是创建一个具有格式化字符串的字段的对象。 @marius 你很麻烦地使用StringBuilder
然后错误地使用“0”+数字类型的“破坏”它。 @mre JVM 的 GC 非常擅长分配和收集大量短期对象,不用担心。我选择了String.format
没有要处理的前导零逻辑。【参考方案9】:
Java 9
Duration timeLeft = Duration.ofMillis(3600000);
String hhmmss = String.format("%02d:%02d:%02d",
timeLeft.toHours(), timeLeft.toMinutesPart(), timeLeft.toSecondsPart());
System.out.println(hhmmss);
打印出来:
01:00:00
您在让库方法为您进行相关转换方面做得很好。 java.time
,现代 Java 日期和时间 API,或者更准确地说,它的 Duration
类比 TimeUnit
更优雅且不易出错。
我使用的 toMinutesPart
和 toSecondsPart
方法是在 Java 9 中引入的。
Java 6、7 和 8
long hours = timeLeft.toHours();
timeLeft = timeLeft.minusHours(hours);
long minutes = timeLeft.toMinutes();
timeLeft = timeLeft.minusMinutes(minutes);
long seconds = timeLeft.toSeconds();
String hhmmss = String.format("%02d:%02d:%02d", hours, minutes, seconds);
System.out.println(hhmmss);
输出同上。
问题:这在 Java 6 和 7 中如何工作?
在 Java 8 及更高版本以及更新的 android 设备上(据我所知,从 API 级别 26 开始)java.time
是内置的。
在 Java 6 和 7 中获得 ThreeTen Backport,这是现代类的后向端口(JSR 310 的 ThreeTen;请参阅底部的链接)。
在(较旧的)Android 上使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。并确保从 org.threeten.bp
导入日期和时间类以及子包。
链接
Oracle tutorial: Date Time 解释如何使用java.time
。
Java Specification Request (JSR) 310,其中首次描述了 java.time
。
ThreeTen Backport project,java.time
到 Java 6 和 7(JSR-310 的 ThreeTen)的反向移植。
ThreeTenABP,Android 版 ThreeTen Backport
Question: How to use ThreeTenABP in Android Project,解释得很透彻。
【讨论】:
【参考方案10】:标记为正确的答案有一点错误,
String myTime = String.format("%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis) -
TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)), // The change is in this line
TimeUnit.MILLISECONDS.toSeconds(millis) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
例如,这是我得到的值的一个例子:
417474:44:19
这是获得正确格式的解决方案是:
String myTime = String.format("%02d:%02d:%02d",
//Hours
TimeUnit.MILLISECONDS.toHours(millis) -
TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(millis)),
//Minutes
TimeUnit.MILLISECONDS.toMinutes(millis) -
TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
//Seconds
TimeUnit.MILLISECONDS.toSeconds(millis) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
得到正确的格式:
18:44:19
获取格式hh:mm:ss
的其他选项只是:
Date myDate = new Date(timeinMillis);
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
String myTime = formatter.format(myDate);
【讨论】:
【参考方案11】:按照 Bohemian 的回答,我们不需要使用 TimeUnit 来查找已知值。 更优化的代码将是
String hms = String.format("%02d:%02d:%02d", millisLeft/(3600*1000),
millisLeft/(60*1000) % 60,
millisLeft/1000 % 60);
希望对你有帮助
【讨论】:
最喜欢你的回答!只是简单的数学。顺便说一句,在我的情况下,我将毫秒添加到末尾millisLeft%1000/10
所以我们得到格式 hour:minutes:seconds:milliseconds
@LêQuangDuy 我需要 3 位数的毫秒数,例如 01:24:51,123,但你最后要砍 3 怎么办?
@naanu 只需使用millisLeft%1000
【参考方案12】:
String string = String.format("%02d:%02d:%02d.%03d",
TimeUnit.MILLISECONDS.toHours(millisecend), TimeUnit.MILLISECONDS.toMinutes(millisecend) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millisecend)),
TimeUnit.MILLISECONDS.toSeconds(millisecend) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisecend)), millisecend - TimeUnit.SECONDS.toMillis(TimeUnit.MILLISECONDS.toSeconds(millisecend)));
格式:00:00:00.000
示例:615605 毫秒
00:10:15.605
【讨论】:
【参考方案13】: public String millsToDateFormat(long mills)
Date date = new Date(mills);
DateFormat formatter = new SimpleDateFormat("HH:mm:ss");
String dateFormatted = formatter.format(date);
return dateFormatted; //note that it will give you the time in GMT+0
【讨论】:
答案取决于时区,这意味着在不同时区运行时结果会有所不同。【参考方案14】:下面的代码以两种方式进行转换
23:59:58:999 转 86398999
比
86398999 至 23:59:58:999
import java.util.concurrent.TimeUnit;
public class TimeUtility
public static void main(String[] args)
long currentDateTime = System.currentTimeMillis();
String strTest = "23:59:58:999";
System.out.println(strTest);
long l = strToMilli(strTest);
System.out.println(l);
l += 1;
String str = milliToString(l);
System.out.println(str);
/**
* convert a time string into the equivalent long milliseconds
*
* @param strTime string fomratted as HH:MM:SS:MSMS i.e. "23:59:59:999"
* @return long integer like 86399999
*/
public static long strToMilli(String strTime)
long retVal = 0;
String hour = strTime.substring(0, 2);
String min = strTime.substring(3, 5);
String sec = strTime.substring(6, 8);
String milli = strTime.substring(9, 12);
int h = Integer.parseInt(hour);
int m = Integer.parseInt(min);
int s = Integer.parseInt(sec);
int ms = Integer.parseInt(milli);
String strDebug = String.format("%02d:%02d:%02d:%03d", h, m, s, ms);
//System.out.println(strDebug);
long lH = h * 60 * 60 * 1000;
long lM = m * 60 * 1000;
long lS = s * 1000;
retVal = lH + lM + lS + ms;
return retVal;
/**
* convert time in milliseconds to the corresponding string, in case of day
* rollover start from scratch 23:59:59:999 + 1 = 00:00:00:000
*
* @param millis the number of milliseconds corresponding to tim i.e.
* 34137999 that can be obtained as follows;
* <p>
* long lH = h * 60 * 60 * 1000; //hour to milli
* <p>
* long lM = m * 60 * 1000; // minute to milli
* <p>
* long lS = s * 1000; //seconds to milli
* <p>
* millis = lH + lM + lS + ms;
* @return a string formatted as HH:MM:SS:MSMS i.e. "23:59:59:999"
*/
private static String milliToString(long millis)
long hrs = TimeUnit.MILLISECONDS.toHours(millis) % 24;
long min = TimeUnit.MILLISECONDS.toMinutes(millis) % 60;
long sec = TimeUnit.MILLISECONDS.toSeconds(millis) % 60;
//millis = millis - (hrs * 60 * 60 * 1000); //alternative way
//millis = millis - (min * 60 * 1000);
//millis = millis - (sec * 1000);
//long mls = millis ;
long mls = millis % 1000;
String toRet = String.format("%02d:%02d:%02d:%03d", hrs, min, sec, mls);
//System.out.println(toRet);
return toRet;
【讨论】:
我赞成这个解决方案。只需在 sec 和 mls 之间添加一个点。而且我不知道为什么在 Java 中时间和日期处理如此困难。最常用的函数应该已经可用并且是类的一部分。【参考方案15】:我尝试如第一个答案所示。它有效,但减号让我感到困惑。我的 Groovy 回答:
import static java.util.concurrent.TimeUnit.*
...
private static String formatElapsedTime(long millis)
int hrs = MILLISECONDS.toHours(millis) % 24
int min = MILLISECONDS.toMinutes(millis) % 60
int sec = MILLISECONDS.toSeconds(millis) % 60
int mls = millis % 1000
sprintf( '%02d:%02d:%02d (%03d)', [hrs, min, sec, mls])
【讨论】:
【参考方案16】:对于科特林
val hours = String.format("%02d", TimeUnit.MILLISECONDS.toHours(milSecs))
val minutes = String.format("%02d",
TimeUnit.MILLISECONDS.toMinutes(milSecs) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(milSecs)))
val seconds = String.format("%02d",
TimeUnit.MILLISECONDS.toSeconds(milSecs) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(milSecs)))
其中,milSecs
是毫秒
【讨论】:
【参考方案17】:嗯,你可以试试这样的:
public String getElapsedTimeHoursMinutesSecondsString()
long elapsedTime = getElapsedTime();
String format = String.format("%%0%dd", 2);
elapsedTime = elapsedTime / 1000;
String seconds = String.format(format, elapsedTime % 60);
String minutes = String.format(format, (elapsedTime % 3600) / 60);
String hours = String.format(format, elapsedTime / 3600);
String time = hours + ":" + minutes + ":" + seconds;
return time;
将毫秒转换为时间值
【讨论】:
【参考方案18】:在 Kotlin 中:
fun FUNCTION_NAME(milliSeconds: Long): String
val s: Long = milliSeconds / 1000 % 60
val m: Long = milliSeconds / (1000*60) % 60
val h: Long = milliSeconds / (1000*60*60) % 24
return String.format("%02d:%02d:%02d", h, m, s)
【讨论】:
这个问题用JAVA问,请用Java回答。 这个问题已有 9 年历史,Kotlin 是“旨在与 Java 完全互操作的”,所以我认为这个问题可以扩展以允许在同一领域使用新技术。像这样的评论会让人们远离 SO。【参考方案19】:在 kotlin 中
private fun stringForTime(timeMs: Int): String
val totalSeconds = timeMs / 1000
val seconds = totalSeconds % 60
val minutes = totalSeconds / 60 % 60
val hours = totalSeconds / 3600
return if (hours > 0)
"%d:%02d:%02d".format(hours, minutes, seconds)
else
"%02d:%02d".format(minutes, seconds)
在 Java 中
private String stringForTime(int timeMs)
int totalSeconds = timeMs / 1000;
int seconds = totalSeconds % 60;
int minutes = totalSeconds / 60 % 60;
int hours = totalSeconds / 3600;
return hours > 0 ? String.format(Locale.getDefault(),
"%d:%02d:%02d",
hours,
minutes,
seconds) :
String.format(Locale.getDefault(),
"%02d:%02d",
minutes,
seconds);
【讨论】:
以上是关于如何将毫秒转换为“hh:mm:ss”格式?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Oracle 中将毫秒转换为 hh mm ss 格式