มีใครรู้จักไลบรารี Java ที่สามารถพิมพ์ตัวเลขในหน่วยมิลลิวินาทีแบบเดียวกับ C # ได้บ้าง?
เช่น 123456 ms เป็นแบบยาวจะพิมพ์เป็น 4d1h3m5s
มีใครรู้จักไลบรารี Java ที่สามารถพิมพ์ตัวเลขในหน่วยมิลลิวินาทีแบบเดียวกับ C # ได้บ้าง?
เช่น 123456 ms เป็นแบบยาวจะพิมพ์เป็น 4d1h3m5s
%
และ/
เพื่อแบ่งหมายเลขออกเป็นส่วน ๆ เกือบจะง่ายกว่าคำตอบที่เสนอ
/
%
คำตอบ:
Joda เวลามีวิธีที่ดีงามที่จะทำนี้ใช้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()
และ regex เล็กน้อย:
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 commons-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()
วิธีjava.time.Duration
การจัดรูปแบบโดยไม่มีไลบรารีภายนอกโดยใช้การแทนค่าตาม ISO 8601 วินาทีเช่น PT8H6M12.345S
นี่คือวิธีที่คุณสามารถทำได้โดยใช้รหัส 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-Extraซึ่งดูแลโดย Stephen Colebourne ผู้เขียน JSR 310, java.timeและJoda-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 เวลาจะเป็นวิธีการแก้ปัญหารูปแบบตาม นี้ถูกนำเสนอโดยห้องสมุดของฉันTime4J ตัวอย่างการใช้คลาสDuration.Formatter (เพิ่มช่องว่างบางส่วนเพื่อให้อ่านง่ายขึ้น - การลบช่องว่างจะทำให้ได้ C # -style ที่ต้องการ):
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 ms as a long จะพิมพ์เป็น 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 ในขณะที่สหราชอาณาจักรไม่ใช้ เวอร์ชันล่าสุด v5.5 ของ Time4J รองรับมากกว่า 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()));
}
... เนื่องจากไม่มี PeriodFormatter ใน Java 8 และไม่มีเมธอดเช่น getHours, getMinutes, ...
ฉันยินดีที่จะเห็นเวอร์ชันที่ดีกว่าสำหรับ Java 8
ฉันตระหนักดีว่าสิ่งนี้อาจไม่เหมาะกับกรณีการใช้งานของคุณ แต่PrettyTimeอาจมีประโยชน์ที่นี่
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
กำหนดไว้ในมาตรฐานที่เหมาะสมISO 8601 :PnYnMnDTnHnMnS
โดยที่P
หมายถึง "ช่วงเวลา" และทำเครื่องหมายจุดเริ่มต้นT
แยกส่วนของวันที่ออกจากส่วนของเวลาและในระหว่างนั้นเป็นส่วนที่เป็นทางเลือกของตัวเลขที่มีค่าเดียว - อักษรย่อ ตัวอย่างเช่นPT4H30M
= สี่ชั่วโมงครึ่ง