Saya ingin merekam waktu menggunakan System.currentTimeMillis()
ketika pengguna memulai sesuatu di program saya. Ketika dia selesai, saya akan mengurangi arus System.currentTimeMillis()
dari start
variabel, dan saya ingin menunjukkan kepada mereka waktu berlalu menggunakan format yang dapat dibaca manusia seperti "XX jam, XX menit, XX detik" atau bahkan "XX menit, XX detik" karena ini tidak mungkin membawa seseorang satu jam.
Apa cara terbaik untuk melakukan ini?
Jawaban:
Gunakan
java.util.concurrent.TimeUnit
kelas:Catatan:
TimeUnit
adalah bagian dari spesifikasi Java 1.5, tetapitoMinutes
ditambahkan sebagai Java 1.6.Untuk menambahkan nol awal untuk nilai 0-9, lakukan saja:
Jika
TimeUnit
atautoMinutes
tidak didukung (seperti pada Android sebelum API versi 9), gunakan persamaan berikut:sumber
int hours = (int) ((milliseconds / (1000*60*60)) % 24)
ini tidak berhasil! sebaliknya harus seperti iniint hours = (int) (milliseconds / (1000*60*60)) ;
String.format("%01d:%02d:%02d", hours, minutes, seconds);
Berdasarkan jawaban @ siddhadev, saya menulis sebuah fungsi yang mengubah milidetik menjadi string yang diformat:
sumber
1 Days 1 Hours 1 Minutes 1 Seconds
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;
dan juga metode String.format:return String.format("%d Days %d Hours %d Minutes %d Seconds %d Milliseconds", days, hours, minutes, seconds, milliseconds);
Cetakan:
sumber
Duration dur = new Duration(start, end);
long millis = dur.getMillis();
DateTimeFormat.forPattern("mm:ss:SSS").print(new DateTime(time));
Atau konversi Durasi ke Periode yang dapat secara otomatis dicetak menggunakan JodaPeriodFormatter
. Konversi bisa kehilangan presisi jika selain kronologi ISO. Misalkan Durasi diwakili oleh variabelduration
.Period period = duration.toPeriod().normalizedStandard(PeriodType.time());
PeriodFormat.getDefault().print(period))
Output luar biasa: 1 detik dan 581 milidetik, menjawab pertanyaan utama di atas.Uhm ... berapa milidetik dalam sedetik? Dan sebentar lagi? Divisi tidak terlalu sulit.
Terus seperti itu selama berjam-jam, berhari-hari, berminggu-minggu, berbulan-bulan, setahun, berpuluh-puluh tahun, apa pun.
sumber
Menggunakan paket java.time di Java 8:
Output dalam format Durasi ISO 8601 :
PT1M3.553S
(1 menit dan 3,553 detik).sumber
Saya tidak akan menarik ketergantungan ekstra hanya untuk itu (pembagian tidak sulit, setelah semua), tetapi jika Anda menggunakan Commons Lang pula, ada DurationFormatUtils .
Contoh Penggunaan (diadaptasi dari sini ):
Contoh:
Catatan : Untuk mendapatkan millis dari dua objek LocalDateTime Anda dapat menggunakan:
sumber
Entah pembagian tangan, atau gunakan API SimpleDateFormat .
Sunting oleh Bombe : Telah ditunjukkan di komentar bahwa pendekatan ini hanya berfungsi untuk durasi yang lebih kecil (yaitu kurang dari sehari).
sumber
Hanya untuk menambahkan lebih banyak info jika Anda ingin memformat seperti: HH: mm: ss
0 <= HH <= tak terbatas
0 <= mm <60
0 <= dtk <60
Gunakan ini:
Saya baru saja mengalami masalah ini sekarang dan menemukan jawabannya
sumber
Saya pikir cara terbaik adalah:
sumber
Solusi terpendek:
Ini mungkin yang terpendek yang juga berkaitan dengan zona waktu.
Output mana misalnya:
Penjelasan:
%tT
adalah waktu yang diformat untuk jam 24 jam sebagai%tH:%tM:%tS
.%tT
juga menerima rindu sebagai input, jadi tidak perlu membuatDate
.printf()
hanya akan mencetak waktu yang ditentukan dalam milidetik, tetapi dalam zona waktu saat ini karena itu kita harus mengurangi offset mentah dari zona waktu saat ini sehingga 0 milidetik akan menjadi 0 jam dan bukan nilai offset waktu dari zona waktu saat ini.Catatan # 1: Jika Anda membutuhkan hasilnya sebagai
String
, Anda bisa mendapatkannya seperti ini:Catatan # 2: Ini hanya memberikan hasil yang benar jika
millis
kurang dari satu hari karena bagian hari tidak termasuk dalam output.sumber
long millis = 8398;
dan ketika saya meneruskannya keString.format("%tT", millis)
output saya adalah 19:00:08. Dari mana 19 berasal?TimeZone.getDefault().getRawOffset()
itu, persis seperti yang tertulis dalam jawaban:String.format("%tT", millis-TimeZone.getDefault().getRawOffset())
Joda-Time
Menggunakan Joda-Time :
sumber
PeriodFormat
di baris terakhir. Cukup panggilPeriod::toString
untuk mendapatkan string Durasi ISO 8601 secara default.Meninjau kembali kontribusi @ brent-nash, kita dapat menggunakan fungsi modulus alih-alih pengurangan dan menggunakan metode String.format untuk string hasil:
sumber
untuk Android di bawah API 9
sumber
Untuk waktu kecil, kurang dari satu jam, saya lebih suka:
untuk interferensi yang lebih lama:
sumber
%tH
hanya tampil dari 0 hingga 23 jam? Itu berarti bahwa misalnya 24 jam akan ditampilkan sebagai00
, 25 jam sebagai01
... valid yang sama untuk%tT
- hari akan secara diam-diam dibuang. Tentu, bisa juga ada hari-hari yang ditampilkan, tetapi itu akan menjadi kesalahan besar untuk masalah yang saya miliki ketika saya menulis ini (kembali pada tahun 2011) [:-)Perhitungan sederhana saya:
Selamat coding :)
sumber
Ini jawaban berdasarkan jawaban Brent Nash, Semoga itu membantu!
sumber
sumber
diff=diff-(hours*60*1000);
seharusnyadiff=diff-(hours*60*60*1000);
. Saya mencoba mengeditnya tetapi kebijakan edit yang menjengkelkan StackOverflow mengatakan itu tidak cukup karakter untuk diedit.Pertama,
System.currentTimeMillis()
danInstant.now()
tidak ideal untuk penentuan waktu. Keduanya melaporkan waktu jam dinding, yang tidak diketahui oleh komputer dengan tepat, dan mana yang dapat bergerak tidak menentu, termasuk mundur jika misalnya daemon NTP mengoreksi waktu sistem. Jika waktu Anda terjadi pada satu mesin, Anda harus menggunakan System.nanoTime () .Kedua, dari Java 8 dan seterusnya java.time.Duration adalah cara terbaik untuk mewakili durasi:
sumber
Jika Anda tahu perbedaan waktu akan kurang dari satu jam, maka Anda dapat menggunakan kode berikut:
Ini akan menghasilkan: 51:00
sumber
Jawaban ini mirip dengan beberapa jawaban di atas. Namun, saya merasa itu akan bermanfaat karena, tidak seperti jawaban lain, ini akan menghilangkan koma atau spasi tambahan dan menangani singkatan.
sumber
Ada masalah. Ketika milidetik 59999, sebenarnya itu 1 menit tetapi akan dihitung sebagai 59 detik dan 999 milidetik hilang.
Berikut adalah versi yang dimodifikasi berdasarkan jawaban sebelumnya, yang dapat mengatasi kehilangan ini:
sumber
Ini lebih mudah di Java 9:
Ini menghasilkan string seperti
0 hours, 39 mins, 9 seconds
.Jika Anda ingin membulatkan seluruh detik sebelum memformat:
Untuk meninggalkan jam jika mereka 0:
Sekarang kita bisa punya contoh
39 mins, 9 seconds
.Untuk mencetak menit dan detik dengan nol di depan untuk membuatnya selalu dua digit, cukup masukkan
02
ke penentu format yang relevan, dengan demikian:Sekarang kita bisa punya contoh
0 hours, 39 mins, 09 seconds
.sumber
if
- dielse
sana.untuk string yang benar ("1 jam, 3 dtk", "3 mnt" tetapi tidak "0 jam, 0 mnt, 3 dtk") saya menulis kode ini:
sumber
Saya memodifikasi jawaban @MyKuLLSKI dan menambahkan dukungan plurlisasi. Saya mengambil detik karena saya tidak membutuhkannya, meskipun merasa bebas untuk menambahkannya kembali jika Anda membutuhkannya.
sumber
int intervalMins
vslong millis
Saya telah membahas ini dalam jawaban lain tetapi Anda dapat melakukannya:
Outputnya seperti
Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0}
, dengan unit yang dipesan.Terserah kepada Anda untuk mengetahui cara menginternasionalkan data ini sesuai dengan target lokal.
sumber
Gunakan java.util.concurrent.TimeUnit, dan gunakan metode sederhana ini:
Sebagai contoh:
sumber
DurasiFormatUtils.formatDurationHMS (panjang)
sumber