C # ile aynı şekilde milisaniye cinsinden bir sayıyı yazdırabilen bir Java kitaplığı bilen var mı?
Örneğin, 123456 ms uzunluğunda 4d1h3m5s olarak yazdırılacaktır.
C # ile aynı şekilde milisaniye cinsinden bir sayıyı yazdırabilen bir Java kitaplığı bilen var mı?
Örneğin, 123456 ms uzunluğunda 4d1h3m5s olarak yazdırılacaktır.
%
ve /
bölüme sayısını bölmek. Önerilen cevapların bazılarından neredeyse daha kolay.
/
ve %
.
Yanıtlar:
Joda Zaman bir kullanarak bunu yapmak için oldukça iyi bir yol var PeriodFormatterBuilder .
Hızlı Kazan: PeriodFormat.getDefault().print(duration.toPeriod());
Örneğin
//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()
veya .standard()
yardım etmedi
Java Duration.toString()
8'leri ve biraz regex kullanarak basit bir çözüm geliştirdim :
public static String humanReadableFormat(Duration duration) {
return duration.toString()
.substring(2)
.replaceAll("(\\d[HMS])(?!$)", "$1 ")
.toLowerCase();
}
Sonuç şöyle görünecek:
- 5h
- 7h 15m
- 6h 50m 15s
- 2h 5s
- 0.1s
Arada boşluk olmasını istemiyorsanız, kaldırmanız yeterlidir replaceAll
.
Duration::toString
, iyi tanımlanmış ve iyi kullanılmış ISO 8601 standardına göre biçimlendirildiği için değişmesi olası değildir .
.replaceAll("\\.\\d+", "")
, çağrıdan önce ekleyin toLowerCase()
.
Apache commons-lang, bunu yapmak için de yararlı bir sınıf sağlar. DurationFormatUtils
örneğin
DurationFormatUtils.formatDurationHMS( 15362 * 1000 ) )
=> 4: 16: 02.000 (H: m: s.millis)
DurationFormatUtils.formatDurationISO( 15362 * 1000 ) )
=> P0Y0M0DT4H16M2.000S, cf. ISO8601
JodaTime , Period
bu tür miktarları temsil edebilen IsoPeriodFormat
ve ISO8601 formatında (aracılığıyla ) oluşturulabilen bir sınıfa sahiptir PT4D1H3M5S
, ör.
Period period = new Period(millis);
String formatted = ISOPeriodFormat.standard().print(period);
Bu format istediğiniz format değilse, PeriodFormatterBuilder
C # stiliniz de dahil olmak üzere rastgele düzenleri bir araya getirmenize izin verir 4d1h3m5s
.
new Period(millis).toString()
kullanır ISOPeriodFormat.standard()
.
Java 8 ile , PT8H6M12.345S gibi ISO 8601 saniye tabanlı gösterimi kullanarak harici kitaplıklar olmadan biçimlendirme toString()
yöntemini de kullanabilirsiniz .java.time.Duration
Saf JDK kodunu kullanarak bunu şu şekilde yapabilirsiniz:
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
ThreeTen-Ekstra Stephen Colebourne, JSR 310, yazarı tarafından korunur proje, java.time ve Joda-Time , bir sahip AmountFormats
standart bir Java 8 tarih saat sınıfları ile çalışır sınıfı. Yine de oldukça ayrıntılı, daha kompakt çıktı seçeneği yok.
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 gün 1s 6d 4sn
Joda-Time'ın oluşturucu yaklaşımına bir alternatif, model tabanlı bir çözüm olabilir . Bu, kütüphanem Time4J tarafından sunulmaktadır . Duration.Formatter sınıfını kullanan örnek (daha fazla okunabilirlik için bazı boşluklar eklendi - boşlukların kaldırılması istenen C #-stilini verecektir):
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
Bu formatlayıcı, java.time
-API sürelerini de yazdırabilir (ancak, bu türün normalleştirme özellikleri daha az güçlüdür):
System.out.println(f.format(java.time.Duration.ofMillis(123456))); // output: 0d 0h 2m 3.456s
OP'nin "123456 ms uzunluğunda 4d1h3m5s olarak yazdırılacağı" beklentisi açıkça yanlış bir şekilde hesaplanmıştır. Uyumsuzluğu sebep olarak kabul ediyorum. Yukarıda tanımlanan aynı süre biçimlendiricisi, ayrıştırıcı olarak da kullanılabilir. Aşağıdaki kod, "4d1h3m5s" değerinin aşağıdakilere karşılık geldiğini gösterir 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
Başka bir yol da sınıfı kullanmaktır net.time4j.PrettyTime
(yerelleştirilmiş çıktı ve "dün", "sonraki Pazar", "4 gün önce" gibi göreli zamanları yazdırmak için de iyidir):
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
Metin genişliği, kısaltmaların kullanılıp kullanılmadığını denetler. Liste formatı da uygun yerel ayar seçilerek kontrol edilebilir. Örneğin, standart İngilizce Oxform virgülünü kullanırken Birleşik Krallık kullanmaz. Time4J'nin en son v5.5 sürümü 90'dan fazla dili destekler ve CLDR deposuna (endüstri standardı) dayalı çeviriler kullanır.
User678573'ün cevabına dayalı bir Java 8 sürümü :
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()));
}
... Java 8'de PeriodFormatter olmadığı ve getHours, getMinutes gibi yöntemler olmadığı için ...
Java 8 için daha iyi bir sürüm görmekten mutlu olurum.
Bunun sizin kullanım durumunuza tam olarak uymayabileceğinin farkındayım, ancak PrettyTime burada yararlı olabilir.
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
, mantıklı standart ISO 8601'de tanımlanmıştır :PnYnMnDTnHnMnS
buradaP
"Dönem" anlamına gelir ve başlangıcı işaretlerT
, tarih bölümünü saat bölümünden ayırır ve bunların arasında, bir sayının isteğe bağlı olarak tek bir -letter kısaltması. Örneğin,PT4H30M
= dört buçuk saat.