Adakah yang tahu tentang pustaka Java yang cukup bisa mencetak angka dalam milidetik dengan cara yang sama seperti C #?
Misalnya, 123456 md sepanjang akan dicetak sebagai 4d1h3m5s.
Adakah yang tahu tentang pustaka Java yang cukup bisa mencetak angka dalam milidetik dengan cara yang sama seperti C #?
Misalnya, 123456 md sepanjang akan dicetak sebagai 4d1h3m5s.
%
dan /
untuk membagi nomor menjadi beberapa bagian. Hampir lebih mudah daripada beberapa jawaban yang diajukan.
/
dan %
.
Jawaban:
Joda Time memiliki cara yang cukup bagus untuk melakukan ini menggunakan PeriodFormatterBuilder .
Menang cepat: PeriodFormat.getDefault().print(duration.toPeriod());
misalnya
//import org.joda.time.format.PeriodFormatter;
//import org.joda.time.format.PeriodFormatterBuilder;
//import org.joda.time.Duration;
Duration duration = new Duration(123456); // in milliseconds
PeriodFormatter formatter = new PeriodFormatterBuilder()
.appendDays()
.appendSuffix("d")
.appendHours()
.appendSuffix("h")
.appendMinutes()
.appendSuffix("m")
.appendSeconds()
.appendSuffix("s")
.toFormatter();
String formatted = formatter.print(duration.toPeriod());
System.out.println(formatted);
PeriodType.daysTime()
atau .standard()
tidak membantu
Saya telah membangun solusi sederhana, menggunakan Java 8 Duration.toString()
dan sedikit regex:
public static String humanReadableFormat(Duration duration) {
return duration.toString()
.substring(2)
.replaceAll("(\\d[HMS])(?!$)", "$1 ")
.toLowerCase();
}
Hasilnya akan terlihat seperti:
- 5h
- 7h 15m
- 6h 50m 15s
- 2h 5s
- 0.1s
Jika Anda tidak ingin spasi di antaranya, hapus saja replaceAll
.
Duration::toString
diformat sesuai dengan standar ISO 8601 yang ditentukan dengan baik dan sudah usang .
.replaceAll("\\.\\d+", "")
sebelum panggilan ke toLowerCase()
.
Apache commons-lang menyediakan kelas yang berguna untuk menyelesaikannya juga DurationFormatUtils
misal
DurationFormatUtils.formatDurationHMS( 15362 * 1000 ) )
=> 4: 16: 02.000 (H: m: s.millis)
DurationFormatUtils.formatDurationISO( 15362 * 1000 ) )
=> P0Y0M0DT4H16M2.000S, lih. ISO8601
JodaTime memiliki Period
kelas yang dapat mewakili kuantitas seperti itu, dan dapat dirender (melalui IsoPeriodFormat
) dalam format ISO8601 , mis.PT4D1H3M5S
, mis.
Period period = new Period(millis);
String formatted = ISOPeriodFormat.standard().print(period);
Jika format itu bukan yang Anda inginkan, maka PeriodFormatterBuilder
memungkinkan Anda menyusun tata letak sewenang-wenang, termasuk gaya C # Anda 4d1h3m5s
.
new Period(millis).toString()
gunakan ISOPeriodFormat.standard()
secara default.
Dengan Java 8 Anda juga dapat menggunakan toString()
metode java.time.Duration
untuk memformatnya tanpa pustaka eksternal menggunakan representasi berbasis ISO 8601 detik seperti PT8H6M12.345S.
Inilah cara Anda melakukannya menggunakan kode JDK murni:
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.Duration;
long diffTime = 215081000L;
Duration duration = DatatypeFactory.newInstance().newDuration(diffTime);
System.out.printf("%02d:%02d:%02d", duration.getDays() * 24 + duration.getHours(), duration.getMinutes(), duration.getSeconds());
org.threeten.extra.AmountFormats.wordBased
Proyek ThreeTen-Extra , yang dikelola oleh Stephen Colebourne, penulis JSR 310, java.time , dan Joda-Time , memiliki AmountFormats
kelas yang bekerja dengan kelas waktu tanggal 8 Java standar. Ini cukup bertele-tele, tanpa opsi untuk output yang lebih kompak.
Duration d = Duration.ofMinutes(1).plusSeconds(9).plusMillis(86);
System.out.println(AmountFormats.wordBased(d, Locale.getDefault()));
1 minute, 9 seconds and 86 milliseconds
Java 9+
Duration d1 = Duration.ofDays(0);
d1 = d1.plusHours(47);
d1 = d1.plusMinutes(124);
d1 = d1.plusSeconds(124);
System.out.println(String.format("%s d %sh %sm %ss",
d1.toDaysPart(),
d1.toHoursPart(),
d1.toMinutesPart(),
d1.toSecondsPart()));
2 d 1j 6m 4s
Sebuah alternatif untuk pendekatan pembangun dari Joda-Waktu akan menjadi solusi berbasis pola . Ini ditawarkan oleh perpustakaan saya Time4J . Contoh menggunakan kelas Duration.Formatter (menambahkan beberapa spasi agar lebih mudah dibaca - menghapus spasi akan menghasilkan gaya C # yang diinginkan):
IsoUnit unit = ClockUnit.MILLIS;
Duration<IsoUnit> dur = // normalized duration with multiple components
Duration.of(123456, unit).with(Duration.STD_PERIOD);
Duration.Formatter<IsoUnit> f = // create formatter/parser with optional millis
Duration.Formatter.ofPattern("D'd' h'h' m'm' s[.fff]'s'");
System.out.println(f.format(dur)); // output: 0d 0h 2m 3.456s
Pemformat ini juga dapat mencetak durasi java.time
-API (namun, fitur normalisasi jenis itu kurang kuat):
System.out.println(f.format(java.time.Duration.ofMillis(123456))); // output: 0d 0h 2m 3.456s
Perkiraan OP bahwa "123456 ms sepanjang akan dicetak sebagai 4d1h3m5s" dihitung dengan cara yang jelas salah. Saya menganggap kecerobohan sebagai alasan. Pemformat durasi yang sama yang ditentukan di atas juga dapat digunakan sebagai parser. Kode berikut menunjukkan bahwa "4d1h3m5s" agak sesuai dengan 349385000 = 1000 * (4 * 86400 + 1 * 3600 + 3 * 60 + 5)
:
System.out.println(
f.parse("4d 1h 3m 5s")
.toClockPeriodWithDaysAs24Hours()
.with(unit.only())
.getPartialAmount(unit)); // 349385000
Cara lain adalah menggunakan kelas net.time4j.PrettyTime
(yang juga bagus untuk keluaran yang dilokalkan dan mencetak waktu relatif seperti "kemarin", "Minggu depan", "4 hari yang lalu", dll.):
String s = PrettyTime.of(Locale.ENGLISH).print(dur, TextWidth.NARROW);
System.out.println(s); // output: 2m 3s 456ms
s = PrettyTime.of(Locale.ENGLISH).print(dur, TextWidth.WIDE);
System.out.println(s); // output: 2 minutes, 3 seconds, and 456 milliseconds
s = PrettyTime.of(Locale.UK).print(dur, TextWidth.WIDE);
System.out.println(s); // output: 2 minutes, 3 seconds and 456 milliseconds
Kontrol lebar teks apakah singkatan digunakan atau tidak. Format daftar juga dapat dikontrol dengan memilih lokal yang sesuai. Misalnya, bahasa Inggris standar menggunakan koma Oxform, sedangkan Inggris tidak. Versi terbaru v5.5 dari Time4J mendukung lebih dari 90 bahasa dan menggunakan terjemahan berdasarkan repositori CLDR (standar industri).
Versi Java 8 berdasarkan jawaban pengguna678573 :
private static String humanReadableFormat(Duration duration) {
return String.format("%s days and %sh %sm %ss", duration.toDays(),
duration.toHours() - TimeUnit.DAYS.toHours(duration.toDays()),
duration.toMinutes() - TimeUnit.HOURS.toMinutes(duration.toHours()),
duration.getSeconds() - TimeUnit.MINUTES.toSeconds(duration.toMinutes()));
}
... karena tidak ada PeriodFormatter di Java 8 dan tidak ada metode seperti getHours, getMinutes, ...
Saya akan senang melihat versi yang lebih baik untuk Java 8.
Saya menyadari ini mungkin tidak sesuai dengan kasus penggunaan Anda, tetapi PrettyTime mungkin berguna di sini.
PrettyTime p = new PrettyTime();
System.out.println(p.format(new Date()));
//prints: “right now”
System.out.println(p.format(new Date(1000*60*10)));
//prints: “10 minutes from now”
Duration
definisi dalam standar yang masuk akal, ISO 8601 : diPnYnMnDTnHnMnS
manaP
berarti "Periode" dan menandai awal,T
memisahkan bagian tanggal dari bagian waktu, dan di antaranya adalah kemunculan opsional angka dengan satu singkatan huruf. Misalnya,PT4H30M
= empat setengah jam.