Làm cách nào để chuyển đổi định dạng mili giây sang định dạng hh: mm: ss?


183

Tôi bối rối. Sau khi tình cờ tìm thấy chủ đề này , tôi đã cố gắng tìm ra cách định dạng đồng hồ đếm ngược có định dạng hh:mm:ss.

Đây là nỗ lực của tôi -

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

Vì vậy, khi tôi thử một giá trị như 3600000ms, tôi nhận được 01:59:00, đó là sai vì nó phải như vậy 01:00:00. Rõ ràng có gì đó không đúng với logic của tôi, nhưng hiện tại, tôi không thể thấy nó là gì!

Có ai giúp được không?

Biên tập -

Đã sửa nó. Đây là cách đúng để định dạng mili giây để hh:mm:ssđịnh dạng -

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

Vấn đề là thế này TimeUnit.MINUTES.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)). Đáng lẽ ra nó phải thế này TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)).


1
3.600.000 mili giây là 3.600 giây, hoặc 60 phút hoặc 1 giờ. Nó không nên 00:59:59, nó nên được 01:00:00.
Borealid

Câu trả lời:


354

Bạn đã thực sự gần gũi:

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

Bạn đã chuyển đổi giờ thành mili giây bằng phút thay vì giờ .

BTW, tôi thích việc bạn sử dụng TimeUnitAPI :)

Đây là một số mã kiểm tra:

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

Đầu ra:

01:00:00

Tôi nhận ra rằng mã của tôi ở trên có thể được đơn giản hóa rất nhiều bằng cách sử dụng phân chia mô đun thay vì trừ:

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

Vẫn sử dụng TimeUnitAPI cho tất cả các giá trị ma thuật và cung cấp chính xác cùng một đầu ra.


2
Amen, giống như cách bạn sử dụng API TimeUnit :)
Dheeraj Bhaskar

2
Nó không phải là một ý tưởng tốt để phát minh lại bánh xe! Câu trả lời của Triton Man là giải pháp tốt hơn.
ممدباقر

5
@ محمدباقر Nhưng câu trả lời khác sử dụng một thư viện bên ngoài, trong khi mã của tôi chỉ sử dụng JDK lõi. Nó phụ thuộc vào nhu cầu của bạn là gì - ví dụ bạn có thể không sử dụng được thư viện bên ngoài. Các câu trả lời khác là tốt mặc dù.
Bohemian

2
@Ozuf thêm .replaceAll("^00:", "")hoặc .replaceAll("^00:(00:)?", "")xóa phút cũng như giờ nếu cả hai đều bằng không.
Bohemian

2
@Ozuf bạn nhận được "15:00""10:00:23"tương ứng; chỉ các số 0 đứng đầu được loại bỏ, do trận đấu được neo để bắt đầu nhập bằng ^.
Bohemian

77

Phương pháp chung cho việc này khá đơn giản:

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, ý bạn là String.format("% 02 d:%02d:%02d", h,m,s) ?
KarenAnne

2
@KarenAnne. Điều đó phụ thuộc vào việc bạn muốn, ví dụ: "03:59:59" hoặc "3:59:59".
Stephen Hosking

2
Thời gian tính bằng mili giây, bạn cần nhân số giây với 1000
Apurva

5
tác giả hỏi về mili giây, không phải giây!
dùng924


26

Tôi đã sử dụng điều này:

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

Xem mô tả về lớp học Formatter .

Xem ví dụ có thể chạy bằng cách sử dụng đầu vào 2400 ms.


Có vẻ như không hoạt động, tôi chỉ đơn giản kiểm tra nó bằng cách vượt qua 100, 1000, 1200 và nó trả lời là 05:30:00 , 05:30:01 , 05:30:01 .
CoDe

2
@CoDe, nó hoạt động cho múi giờ của bạn. Bạn phải ở múi giờ khác với UTC. String.format()phụ thuộc múi giờ . Câu trả lời đúng lý tưởng, tuy nhiên, nên độc lập múi giờ .
Derek Mahar

@CoDe, nó hiển thị thời gian tương ứng với múi giờ của bạn phải khác với UTC. String.format()phụ thuộc múi giờ . Câu trả lời đúng lý tưởng, tuy nhiên, nên độc lập múi giờ .
Derek Mahar

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

Xem ví dụ có thể chạy bằng cách sử dụng đầu vào 1200 ms.


3
Điều này sẽ tạo ra kết quả không chính xác trong khoảng thời gian hơn một ngày. Nó sẽ bao gồm số giờ từ 23 trở về 0, có lẽ không mong muốn ở đây.
Kenster

Không có bạn thân ... Tôi nghĩ nó vẫn sẽ hoạt động như vậy. thử với ngày hôm nay
Vinay Lodha

1
SimpleDateFormat sdf = new SimpleDateFormat ("hh: mm aa"); trong trường hợp ai đó muốn ở định dạng 12 giờ với sáng / chiều
Ajji

14
DateFormat df = new SimpleDateFormat("HH:mm:ss");
String formatted = df.format(aDateObject);

1
Câu trả lời tương tự như stackoverflow.com/questions/9027317/ với vấn đề tương tự trong thời gian trên 1 ngày
OneWorld

Nó cũng phụ thuộc vào múi giờ, điều đó có nghĩa là kết quả sẽ khác nhau khi chạy ở các múi giờ khác nhau.
Derek Mahar

10

Kết quả kiểm tra cho 4 lần thực hiện

Phải thực hiện nhiều định dạng cho dữ liệu khổng lồ, cần hiệu suất tốt nhất, vì vậy đây là kết quả (đáng ngạc nhiên):

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

Thời lượng:

  • tổ hợpFormatter : 196 millis
  • formatDuration: 272 millis
  • apacheFormat: 754 millis
  • formatTimeUnit: 2216 millis

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

Làm thế nào đáng tin cậy là số liệu như thế này? Tôi chưa bao giờ thực sự hiểu quá trình.
MRE

Trong tình huống của tôi, nơi một số hàng ngàn đối tượng được tạo ra liên tiếp, thử nghiệm này tôi nghĩ là khá hữu ích. Được rồi không chỉ thiết lập một số chuỗi, nhưng tạo các đối tượng có một trường một chuỗi được định dạng.
MariusA

@marius bạn đã gặp rắc rối khi sử dụng StringBuilderrồi mắc lỗi sử dụng "0" + số loại "hủy hoại" nó. @mre GC của JVM cực kỳ giỏi trong việc phân bổ và thu thập nhiều đối tượng tồn tại trong thời gian ngắn, không phải lo lắng gì cả. Tôi đã String.formatkhông có logic hàng đầu để giải quyết.
thoát-llc

6

Đi theo câu trả lời của Bohemian, chúng ta không cần sử dụng TimeUnit để tìm giá trị đã biết. Mã tối ưu hơn nhiều sẽ là

String hms = String.format("%02d:%02d:%02d", millisLeft/(3600*1000),
                    millisLeft/(60*1000) % 60,
                    millisLeft/1000 % 60);

Hy vọng nó giúp


Giống như câu trả lời của bạn nhất! Chỉ cần toán đơn giản. Btw trong trường hợp của tôi, tôi đã thêm một phần nghìn giây vào cuối millisLeft%1000/10để chúng ta có được định dạnghour:minutes:seconds:milliseconds
Lê Quang Duy

@ LêQuangDuy tôi cần mili giây trong 3 chữ số như 01: 24: 51,123 nhưng cuối cùng bạn đang chặt 3 cái thì phải làm sao?
naanu

@naanu chỉ cần sử dụngmillisLeft%1000
Lê Quang 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
}

Câu trả lời phụ thuộc vào múi giờ có nghĩa là kết quả sẽ khác nhau khi chạy ở các múi giờ khác nhau.
Derek Mahar

6

điều này làm việc cho tôi, với 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"
            }
        }
    }

Làm việc hoàn hảo cho tôi. Đây sẽ là câu trả lời tốt nhất vì nó xử lý 0 giờ
vNext

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

Bản in này:

01:00:00

Bạn đang làm đúng trong việc để các phương thức thư viện thực hiện các chuyển đổi liên quan đến bạn. java.time, API ngày và giờ Java hiện đại, hay chính xác hơn là Durationlớp của nó thực hiện nó một cách thanh lịch hơn và theo cách ít bị lỗi hơn TimeUnit.

Các phương thức toMinutesParttoSecondsParttôi đã sử dụng đã được giới thiệu trong Java 9.

Java 6, 7 và 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);

Đầu ra giống như trên.

Câu hỏi: Làm thế nào mà nó có thể hoạt động trong Java 6 và 7?

  • Trong Java 8 trở lên và trên các thiết bị Android mới hơn (từ API cấp 26, tôi đã nói) java.time được tích hợp sẵn.
  • Trong Java 6 và 7, lấy ThreeTen Backport, backport của các lớp hiện đại (ThreeTen cho JSR 310; xem các liên kết ở phía dưới).
  • Trên (cũ) Android sử dụng phiên bản Android của ThreeTen Backport. Nó được gọi là ThreeTenABP. Và hãy chắc chắn rằng bạn nhập các lớp ngày và thời gian từ org.threeten.bpvới các gói con.

Liên kết


5

Mã dưới đây thực hiện chuyển đổi theo cả hai cách

23: 59: 58: 999 đến 86398999

và hơn

86398999 đến 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;
    }
}

Tôi ủng hộ giải pháp này. Chỉ cần đặt một dấu chấm giữa giây và ml. Và tôi không biết tại sao việc xử lý thời gian và ngày rất khó khăn trong Java. Các hàm được sử dụng nhiều nhất nên đã có sẵn và là một phần của lớp.
Baruch Atta

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

Định dạng: 00: 00: 00.000

Ví dụ: 615605 Millisecend

00:00: 15.605


5

Câu trả lời được đánh dấu là đúng có một chút sai lầm,

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

ví dụ đây là một ví dụ về giá trị mà tôi nhận được:

417474:44:19

Đây là giải pháp để có được định dạng đúng là:

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

kết quả là một định dạng chính xác:

18:44:19

tùy chọn khác để có được định dạng hh:mm:sschỉ là:

   Date myDate = new Date(timeinMillis);
   SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
   String myTime = formatter.format(myDate);

4

Tôi đã cố gắng như thể hiện trong câu trả lời đầu tiên. Nó hoạt động, nhưng trừ đi làm tôi bối rối. Câu trả lời của tôi bởi 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

Đối với 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)))

ở đâu, milSecslà mili giây


1

Chà, bạn có thể thử một cái gì đó như thế này:

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

để chuyển đổi mili giây thành giá trị thời gian

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.