我花了整个上午试图找到一种方法来实现我最初认为相对容易的任务:将以数字方式表示的持续时间转换为可读方式。例如,对于3.5的输入,输出应为“3年零6个月”。
根据我所阅读的内容,强烈建议使用Joda Time库。使用该库并跟随this post我尝试了以下内容:
Period p = new Period(110451600000L); // 3 years and a half
PeriodFormatter formatter = new PeriodFormatterBuilder()
.appendYears()
.appendSuffix(" year", " years")
.appendSeparator(" and ")
.appendMonths()
.appendSuffix(" month", " months")
.toFormatter();
System.out.println(formatter.print(p));
但输出没什么。不知道为什么它不起作用。
我也尝试使用Apache DurationFormatUtils,但无效。
有人有想法吗?
提前致谢。
答案 0 :(得分:4)
经过一些研究,测试和本杰明的帮助,我有一个解决方案:
DateTime dt = new DateTime(); // Now
DateTime plusDuration = dt.plus(new Duration(110376000000L)); // Now plus three years and a half
// Define and calculate the interval of time
Interval interval = new Interval(dt.getMillis(), plusDuration.getMillis());
// Parse the interval to period using the proper PeriodType
Period period = interval.toPeriod(PeriodType.yearMonthDayTime());
// Define the period formatter for pretty printing the period
PeriodFormatter pf = new PeriodFormatterBuilder()
.appendYears().appendSuffix("y ", "y ")
.appendMonths().appendSuffix("m", "m ").appendDays()
.appendSuffix("d ", "d ").appendHours()
.appendSuffix("h ", "h ").appendMinutes()
.appendSuffix("m ", "m ").appendSeconds()
.appendSuffix("s ", "s ").toFormatter();
// Print the period using the previously created period formatter
System.out.println(pf.print(period).trim());
我发现Joda-Time的官方文档非常有用,特别是这篇文章:Correctly defining a duration using JodaTime
尽管如此,虽然它有效但我不是百分之百满意,因为上面发布的代码的输出是“3y 6m 11h”而且我不明白这11个小时的原因:S无论如何,我只需要精确几年和几个月所以我认为这不是一个大问题。如果有人知道原因和/或在某些情况下是否有问题,请通过评论告诉我。
答案 1 :(得分:2)
代码中的句点p
不包含年份或飞蛾,这就是格式化程序根本不输出任何内容的原因。使用格式化程序PeriodFormat.getDefault()
,您会看到它包含小时数,即正好是30681 = 110451600000 / 1000/60/60。
这就是原因:毫秒可以以定义的方式转换为秒,分钟和小时。但计算天数,飞蛾数或年数是模糊的,因为一天中的小时数可能不同(时区转移),一个月中的天数和一年中的天数也是如此。请参阅文档:http://joda-time.sourceforge.net/apidocs/org/joda/time/Period.html#Period%28long%29
在那里找到:
要更好地控制转化过程,您有两种选择:
- 将持续时间转换为间隔,并从那里获得期间
- 指定包含日期和更大字段的精确定义的句点类型,例如UTC