如何创建单个表达式,显示两个日期之间的时差,如年,月,日,小时,分钟,秒
我如何创建一个jasx报告JRExpression ,它可视化两个java.util.Date
之间的差异,格式为yy年(s)月(s),hh小时(s),mm分(s),ss秒
java.util.Date startDate java.util.Date endDate
JRExpression是一行不允许变量声明的行,但是你可以使用语法boolean ? yes:no
条件语句boolean ? yes:no
boolean ? yes:no
,对于你不熟悉的人想象一下System.out.println();
所需输出的示例(如果你有一个很好的解决方案,当不存在时删除单位的描述并考虑单数/复数但如果它是一系列if语句则不是必需的):
2年,8个月,12天,2小时,53分钟,10秒
1小时1分钟
2月2日至3月4日和3月4日 – 4月6日都是“1个月,2天”,夏令时可以忽略 – 感谢@Affe
其他要求:
- 只能使用jasper报告依赖项 (不包括joda)。
- 优选的jdk 1.7或更低(如果这只是解决方案,则接受1.8)
没有必要将答案格式化为jasper报表,它可以是一个简单的System.out.println
代码(我很乐意稍后编辑你的答案,也可以添加jasper报表表达式代码)。 例
((endDate.getTime()-startDate.getTime()) / (60 * 60 * 1000)) % 24 + " hour(s), " + ((endDate.getTime()-startDate.getTime()) / (60 * 1000)) % 60 + " minute(s)"
我试过了什么:
我在SO的jasper报告部分回答了多个问题,这个问题在报告生成中很常见。 我更喜欢java部分的一个很好的答案,我可以链接而不是在这个问题上传递我的代码(我只知道部分解决为例)
这是jasper-report中的一个问题示例: 计算时间和日期差异
一些参考代码:
在java中计算日期/时间差异
如何在java中找到两个日期之间的差异持续时间?
对于jasper报告中熟悉的人,我不想使用变量声明,因为如果用户需要在参数上使用它,这将使解决方案无效。
Calendar API不能直接用于此问题:每个操作都需要多行,因为有趣的方法返回void
并且无法链接。
这是一个非常大的延伸,但是,如JasperReports的依赖关系中所列,有org.codehaus.castor:castor-xml:1.3.3
,它取决于commons-lang:commons-lang:2.6
。 因此,我们可以使用在commons-lang
存在的DurationFormatUtils.formatPeriod(startMillis, endMillis, format)
方法。 这里使用的格式字符串是
"y' years 'M' months 'd' days 'H' hours 'm' minutes 's' seconds'"
这将打印想要的字符串。 必须小心:这将包括0(如"0 months"
),并且也会有不正确的复数(如"1 months"
)。
- 我们可以使用正则表达式
"(? 删除String的所有0。 此正则表达式匹配任何0, 不以数字开头 (例如,我们不想匹配10),后跟一个或多个单词字符,并可选地后跟空格。
- 然后,我们可以使用正则表达式
"(?匹配
"1 ...s"
每个出现,并将其替换为"1 ..."
以使其正确多元化。 此正则表达式匹配任何1,不以数字开头,后跟一个以s
结尾的一个或多个单词字符(在组中捕获); 它将被替换为"1 $1"
,即1后跟捕获的值。
例:
System.out.println( org.apache.commons.lang.time.DurationFormatUtils.formatPeriod( startDate.getTime(), endDate.getTime(), "y' years 'M' months 'd' days 'H' hours 'm' minutes 's' seconds'" ) .replaceAll("(?
所有这些都可以使用Java 7或更低版本完成。
在JasperReports中,这将是一个例子:
输出为:
如果上面看起来太脆弱了(因为明显依赖于commons-lang
而不是所有JasperReports版本都存在 ), 那么使用Java 8中引入的Java Time API 还有另一种可能的解决方案 。
这很糟糕 (我认为没有更简单的方法),但输出与上面完全相同,其中start
和end
都是LocalDateTime
对象:
System.out.println(( ChronoUnit.YEARS.between(start, end) + " years " + ChronoUnit.MONTHS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)), end) + " months " + ChronoUnit.DAYS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)).plusMonths(ChronoUnit.MONTHS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)), end)), end) + " days " + ChronoUnit.HOURS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)).plusMonths(ChronoUnit.MONTHS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)), end)).plusDays(ChronoUnit.DAYS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)).plusMonths(ChronoUnit.MONTHS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)), end)), end)), end) + " hours " + ChronoUnit.MINUTES.between(start.plusYears(ChronoUnit.YEARS.between(start, end)).plusMonths(ChronoUnit.MONTHS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)), end)).plusDays(ChronoUnit.DAYS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)).plusMonths(ChronoUnit.MONTHS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)), end)), end)).plusHours(ChronoUnit.HOURS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)).plusMonths(ChronoUnit.MONTHS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)), end)).plusDays(ChronoUnit.DAYS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)).plusMonths(ChronoUnit.MONTHS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)), end)), end)), end)), end) + " minutes " + ChronoUnit.SECONDS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)).plusMonths(ChronoUnit.MONTHS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)), end)).plusDays(ChronoUnit.DAYS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)).plusMonths(ChronoUnit.MONTHS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)), end)), end)).plusHours(ChronoUnit.HOURS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)).plusMonths(ChronoUnit.MONTHS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)), end)).plusDays(ChronoUnit.DAYS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)).plusMonths(ChronoUnit.MONTHS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)), end)), end)), end)).plusMinutes(ChronoUnit.MINUTES.between(start.plusYears(ChronoUnit.YEARS.between(start, end)).plusMonths(ChronoUnit.MONTHS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)), end)).plusDays(ChronoUnit.DAYS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)).plusMonths(ChronoUnit.MONTHS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)), end)), end)).plusHours(ChronoUnit.HOURS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)).plusMonths(ChronoUnit.MONTHS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)), end)).plusDays(ChronoUnit.DAYS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)).plusMonths(ChronoUnit.MONTHS.between(start.plusYears(ChronoUnit.YEARS.between(start, end)), end)), end)), end)), end)), end) + " seconds" ) .replaceAll("(?