C#と同じ方法でミリ秒単位で数値を出力できるJavaライブラリを知っている人はいますか?
たとえば、長さが123456ミリ秒の場合、4d1h3m5sとして出力されます。
C#と同じ方法でミリ秒単位で数値を出力できるJavaライブラリを知っている人はいますか?
たとえば、長さが123456ミリ秒の場合、4d1h3m5sとして出力されます。
%
して/
部品に番号を分割します。提案された回答のいくつかよりもほとんど簡単です。
/
と%
。
回答:
Joda Timeには、PeriodFormatterBuilderを使用してこれを行うためのかなり良い方法があります。
迅速な勝利: PeriodFormat.getDefault().print(duration.toPeriod());
例えば
//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()
か.standard()
助けていない
私は、Java 8 Duration.toString()
と少しの正規表現を使用して、単純なソリューションを構築しました。
public static String humanReadableFormat(Duration duration) {
return duration.toString()
.substring(2)
.replaceAll("(\\d[HMS])(?!$)", "$1 ")
.toLowerCase();
}
結果は次のようになります。
- 5h
- 7h 15m
- 6h 50m 15s
- 2h 5s
- 0.1s
間にスペースを入れたくない場合は、単に削除しreplaceAll
ます。
Duration::toString
、明確で使い古されたISO 8601標準に従ってフォーマットされているため、変更される可能性はほとんどありません。
.replaceAll("\\.\\d+", "")
、の呼び出しの前に追加しtoLowerCase()
ます。
Apacheのコモンズ-langが、これは、井戸として行わ取得するために有用なクラスを提供しDurationFormatUtils
例
DurationFormatUtils.formatDurationHMS( 15362 * 1000 ) )
=> 4:16:02.000(H:m:s.millis)
DurationFormatUtils.formatDurationISO( 15362 * 1000 ) )
=> P0Y0M0DT4H16M2.000S、cf。ISO8601
JodaTimeを有するPeriod
ような量を表すことができるクラスを、及び(介してレンダリングすることができるIsoPeriodFormat
で)ISO8601フォーマット、例えばPT4D1H3M5S
、例えば
Period period = new Period(millis);
String formatted = ISOPeriodFormat.standard().print(period);
その形式が必要な形式でない場合はPeriodFormatterBuilder
、C#スタイルを含む任意のレイアウトをアセンブルできます4d1h3m5s
。
new Period(millis).toString()
使用ISOPeriodFormat.standard()
します。
Java 8では、のtoString()
メソッドを使用して、PT8H6M12.345SなどのISO 8601秒ベースの表現java.time.Duration
を使用する外部ライブラリなしでフォーマットすることもできます。
純粋なJDKコードを使用してそれを行う方法を次に示します。
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-エクストラスティーブンColebourne、JSR 310、の著者によって維持されているプロジェクト、java.time、およびジョダタイムは、持っているAmountFormats
標準的なJava 8日付時刻クラスで動作するクラスを。ただし、これはかなり冗長で、よりコンパクトな出力のオプションはありません。
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日1時間6分4秒
Joda-Timeのビルダーアプローチに代わるものは、パターンベースのソリューションです。これは私のライブラリTime4Jによって提供されています。クラスDuration.Formatterを使用した例(読みやすくするためにいくつかのスペースを追加-スペースを削除すると、希望のC#スタイルが生成されます):
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
このフォーマッターはjava.time
-APIの期間も出力できます(ただし、そのタイプの正規化機能はそれほど強力ではありません)。
System.out.println(f.format(java.time.Duration.ofMillis(123456))); // output: 0d 0h 2m 3.456s
OPの「123456ミリ秒は4d1h3m5sとして出力される」という期待は、明らかに間違った方法で計算されます。だらしないと思う。上記で定義した同じ期間フォーマッターをパーサーとして使用することもできます。次のコードは、「4d1h3m5s」がどちらかに相当することを示しています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
別の方法はクラスを使用することです net.time4j.PrettyTime
ことです(ローカライズされた出力や、「昨日」、「次の日曜日」、「4日前」などの相対時間の印刷にも適しています)。
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
テキスト幅は、略語を使用するかどうかを制御します。リストの形式も、適切なロケールを選択することで制御できます。たとえば、標準の英語ではOxformカンマが使用されますが、英国では使用されません。Time4Jの最新バージョンv5.5は90を超える言語をサポートし、CLDRリポジトリ(業界標準)に基づいた翻訳を使用します。
Javaの8に基づくバージョンuser678573の答え:
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にはPeriodFormatterがなく、getHours、getMinutesなどのメソッドもないため...
Java 8のより良いバージョンが見られたら嬉しいです。
Duration
は、賢明な標準ISO 8601で定義されています。PnYnMnDTnHnMnS
ここで、P
「期間」とは開始を示しT
、日付の部分と時間の部分を区切り、その間にオプションで数字が1つ出現します。 -略語。たとえば、PT4H30M
= 4時間半です。