[英]How would I convert the exact amount of time (years, months, days, hours, minutes, seconds) between two Calendar objects?
[英]How to create a single expression displaying time difference between two Date's as years, months, days, hours, minutes, seconds
如何创建单个 jasper报告JRExpression ,以yy年月日dd天,hh小时,mm分钟,ss的格式可视化两个java.util.Date
之间的差异秒
java.util.Date startDate
java.util.Date endDate
JRExpression是单行,其中不允许声明变量,但是您可以使用条件语句(使用语法boolean ? yes:no
boolean ? yes:no
,对于不熟悉的人,请想象一行System.out.println();
所需输出的示例(如果您有一个不错的解决方案,请删除不存在的单位描述,并考虑单数/复数,但是如果它是一系列if语句,则不必这样做):
2年8个月12天2小时53分钟10 s
1小时1分钟
2月2日至3月4日和3月4日至4月6日均为“ 1个月2天”,但是可以忽略夏令时-谢谢@Affe
其他要求:
无需将答案格式化为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的碧玉报告部分回答了多个问题,这个问题在报告生成中很常见。 我希望我可以链接一个java部分中的一个好答案,而不是在这个问题上传递代码(我只知道部分解决此问题)
这是在jasper-report中有关问题的示例: 计算时间和日期差
一些参考代码:
对于您熟悉的jasper report,我不想使用变量声明,因为如果用户需要在参数上使用它,这会使解决方案无效。
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"
)。
"(?<!\\\\d)0 (\\\\w+) ?"
删除字符串的所有0。 此正则表达式匹配任何0, 不以数字开头 (例如,我们不希望匹配10),后接一个或多个单词字符,并可选地后面跟一个空格。 "(?<!\\\\d)1 (\\\\w+)s"
来匹配每次出现的"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("(?<!\\d)0 (\\w+) ?", "")
.replaceAll("(?<!\\d)1 (\\w+)s", "1 $1")
);
所有这些都可以使用Java 7或更低版本来完成。
在JasperReports中,这将是一个示例:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.2.1.final using JasperReports Library version 6.2.1 -->
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports jasperreports.sourceforge.net/…" name="Blank_A4" pageWidth="595" pageHeight="842" whenNoDataType="AllSectionsNoDetail" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="f067f2c4-395f-4669-9fda-4fe81cc59227">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
<parameter name="dateStart" class="java.util.Date" isForPrompting="false">
<defaultValueExpression><![CDATA[new java.util.Date(1)]]></defaultValueExpression>
</parameter>
<parameter name="dateEnd" class="java.util.Date" isForPrompting="false">
<defaultValueExpression><![CDATA[new java.util.Date()]]></defaultValueExpression>
</parameter>
<queryString><![CDATA[]]></queryString>
<title>
<band height="43" splitType="Stretch">
<textField>
<reportElement x="0" y="0" width="560" height="30" uuid="cc03531c-2983-4f9a-9619-2826ed92760e"/>
<textFieldExpression><![CDATA[org.apache.commons.lang.time.DurationFormatUtils.formatPeriod($P{dateStart}.getTime(),$P{dateEnd}.getTime(),"y' years 'M' months 'd' days 'H' hours 'm' minutes 's' seconds'").replaceAll("(?<!\\d)0 (\\w+) ?", "").replaceAll("(?<!\\d)1 (\\w+)s", "1 $1")]]></textFieldExpression>
</textField>
</band>
</title>
</jasperReport>
输出为:
如果以上内容看起来太脆弱(因为不可能对所有JasperReports版本都存在对commons-lang
的显式依赖), 那么还有另一种可能的解决方案,使用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("(?<!\\d)0 (\\w+) ?", "")
.replaceAll("(?<!\\d)1 (\\w+)s", "1 $1")
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.