ミリ秒を「hh:mm:ss」形式に変換する方法は?


184

よくわかりません。このスレッドに偶然出会った後、私はフォーマットを備えたカウントダウンタイマーをフォーマットする方法を理解しようとしました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))代わりにこれであるはずです。


1
3,600,000ミリ秒は3,600秒、つまり60分、つまり1時間です。あるべきではない00:59:59、そうであるべきだ01:00:00
Borealid 2012年

回答:


355

あなたは本当に近かったです:

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)));   

あなたは使用してmillissecondsに時間を変換したの代わりに、時間を

ところで、私はあなたのTimeUnitAPIの使用が好きです:)

ここにいくつかのテストコードがあります:

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を引き続き使用し、まったく同じ出力を提供します。


2
アーメン、TimeUnit APIの使い方と同じように:)
Dheeraj Bhaskar 2013

2
車輪を再発明するのは良い考えではありません!トリトンマンの答えはより良い解決策です。
محمدباقر

5
@محمدباقرしかし、他の答えは外部ライブラリを使用していますが、私のコードはコアJDKのみを使用しています。これは、ニーズが何であるかによって異なります。たとえば、外部ライブラリを使用できない場合があります。他の答えも良いです。
ボヘミアン

2
@Ozufは.replaceAll("^00:", "")、分と.replaceAll("^00:(00:)?", "")、両方がゼロの場合は時間を追加または削除します。
ボヘミアン

2
@Ozufをそれぞれ取得"15:00""10:00:23"ます。一致がによって入力の開始に固定されているため、先行ゼロのみが削除され^ます。
ボヘミアン

77

この一般的な方法はかなり単純です。

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);
}

1
Javaman59 @、もしかしてString.format("% 02 d:%02d:%02d", h,m,s)
KarenAnne 2013年

2
@KarenAnne。これは、たとえば「03:59:59」または「3:59:59」のどちらにするかによって異なります。
Stephen Hosking 2013年

2
時間はミリ秒単位で、秒に1000を掛ける必要があります
Apurva

5
著者は秒ではなくミリ秒について尋ねました!
user924 '24年


26

私はこれを使いました:

String.format("%1$tH:%1$tM:%1$tS.%1$tL", millis);

クラスFormatterの説明を参照してください。

2400 msの入力を使用した実行可能な例を参照してください。


動作していないようです。パス100、1000、1200テストすると05: 30 : 00、05 : 30: 01、05 : 30 : 01と応答します。
CoDe 2017年

2
@CoDe、それはあなたのタイムゾーンで動作します。UTCとは異なるタイムゾーンにいる必要があります。 String.format()タイムゾーンに依存します。ただし、理想的な正解はタイムゾーンに依存しないものである必要があります。
Derek Mahar

@CoDe、それはあなたのタイムゾーンに対応する時間を示しています。これはUTCとは異なる必要があります。String.format()タイムゾーンに依存します。ただし、理想的な正解はタイムゾーンに依存しないものである必要があります。
デレク・マハール

25
// 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 );

1200 msの入力を使用した実行可能な例を参照してください。


3
これにより、1日を超える時間に対して誤った結果が生成されます。これは、23時間から0時間に戻る時間をラップします。これは、おそらくここでは望ましくありません。
ケンスター2014年

相棒がいない...それでも同じように動作すると思います。今日の日付で試してください
Vinay Lodha 2014年

1
SimpleDateFormat sdf = new SimpleDateFormat( "hh:mm aa"); 誰かが午前/午後で12時間形式で希望する場合
Ajji


10

4つの実装のテスト結果

大量のデータに対して多くのフォーマットを行う必要があり、最高のパフォーマンスが必要だったので、(驚くべき)結果は次のとおりです。

for(int i = 0; i <1000000; i ++){FUNCTION_CALL}

期間:

  • CombinationFormatter:196CombinationFormatterミリ秒
  • formatDuration:272ミリ秒
  • apacheFormat:754ミリ秒
  • formatTimeUnit: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(); 
     }

これらのようなメトリックはどの程度信頼できますか?私はそのプロセスを本当に理解したことがありません。
mre

数千のオブジェクトが連続して作成される私の状況では、このテストはかなり便利だと思います。いくつかの文字列だけを設定するのではなく、1つのフィールドがフォーマットされた文字列であるオブジェクトを作成します。
MariusA 2014

@marius使いに行っStringBuilderて「0」+数字の「廃墟」を使って間違えた。@mre JVMのGCは、存続期間の短いオブジェクトの割り当てや収集に非常に優れており、心配する必要はありません。String.format対処するための先行ゼロロジックはありませんでした。
escape-llc

7

これは私のために働いた、コトリン

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"
            }
        }
    }

私には完璧に働きました。これは0時間を処理するため、最良の答えになるはずです
vNext

6

ボヘミアンの答えによれば、既知の値を見つけるために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êクアンDuyと

@LêQuangDuy01:24:51,123のような3桁のミリ秒が必要ですが、あなたは最後に3をチョッピングしていますか?
naanu

@naanuだけ使うmillisLeft%1000
LêクアンDuyと

6
 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
}

回答はタイムゾーンに依存しているため、異なるタイムゾーンで実行すると結果が異なります。
デレク・マハール

6

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ます。

toMinutesParttoSecondsPart、私が使用した方法は、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バックポートを取得します(JSR 310の場合はThreeTen。下部にあるリンクを参照)。
  • (古い)Androidでは、ThreeTen BackportのAndroidエディションを使用します。それはThreeTenABPと呼ばれています。またorg.threeten.bp、サブパッケージを使用して日付と時刻のクラスをインポートするようにしてください。

リンク集


5

以下のコードは両方の方法で変換を行います

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;
    }
}

私はこの解決策に賛成しました。秒とmlsの間にドットを置くだけです。そして、なぜJavaでは時間と日付の処理が非常に難しいのかわかりません。最もよく使用される関数はすでに利用可能で、クラスの一部である必要があります。
Baruch Atta 2018年

5
        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


5

正しいとマークされた答えには少し間違いがあります、

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);

4

最初の答えのようにしてみました。それは機能しますが、マイナスは私を混乱に導きました。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])
}

3

Kotlinの場合

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はミリ秒


1

まあ、あなたはこのようなものを試すことができます:

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;  
 }  

ミリ秒を時間値に変換する

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.