gpt4 book ai didi

java - 如何创建一个表达式,将两个日期之间的时差显示为年、月、日、小时、分钟、秒

转载 作者:行者123 更新时间:2023-11-30 08:42:10 24 4
gpt4 key购买 nike

如何创建单个 jasper 报告JRExpression可视化两个 java.util.Date 之间的差异,格式为 yy year(s) month(s) dd day(s), hh hour(s), mm minute(s), ss second( s)

java.util.Date startDate
java.util.Date endDate

JRExpression 是不允许变量声明的单行,但是您可以使用语法 boolean ? yes:no,不熟悉的你想象一下一行System.out.println();

所需输出的示例(如果您有一个很好的解决方案,请在不存在时删除单元描述并考虑单数/复数,但如果它是一系列 if 语句,则没有必要这样做):

2 years, 8 months, 12 days, 2 hours, 53 minutes, 10 s

1 hour, 1 minute

both Feb 2- Mar 4 and Mar 4 - April 6 are "1 month, 2 days", daylight savings however can be ignored - thanks @Affe

附加要求:

  • 只有 jasper 报告 dependencies可以使用(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 部分的一个很好的答案,我可以链接而不是传递我在这个问题上的代码(我只知道部分解决作为例子)

这是 中的一个问题示例: Calculating Time and Date difference

部分引用代码:

Calculate date/time difference in java

How to find the duration of difference between two dates in java?

对于熟悉 jasper 报告的人来说,我不想使用变量声明,因为如果用户需要在参数上使用它,这会使解决方案无效。

最佳答案

日历 API 不能直接用于此问题:每个操作都需要多行,因为有趣的方法是 void返回并且不能被链接。

这是一个很大的延伸,但是,如 the dependencies of JasperReports 中所列, 有 org.codehaus.castor:castor-xml:1.3.3 这取决于 commons-lang:commons-lang:2.6 .因此我们可以利用 DurationFormatUtils.formatPeriod(startMillis, endMillis, format) 方法,存在于 commons-lang 中.此处使用的格式字符串将是

"y' years 'M' months 'd' days 'H' hours 'm' minutes 's' seconds'"

这将打印想要的字符串。仍然必须小心:这将包括 0(如 "0 months" )并且还会有不正确的复数形式(如 "1 months" )。

  • 我们可以使用正则表达式"(?<!\\d)0 (\\w+) ?"删除字符串的所有 0。此正则表达式匹配任何 0, not preceded by a digit (例如,我们不想匹配 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>

输出为:

enter image description here


如果上面看起来太脆弱(因为对 commons-lang 的显式依赖,不可能对所有 JasperReports 版本都存在),there is another possible solution使用 Java Time API在 Java 8 中引入。

这很可怕(我不认为有更简单的方法),但输出与上面完全相同,其中startend都是 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")
);

关于java - 如何创建一个表达式,将两个日期之间的时差显示为年、月、日、小时、分钟、秒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34665069/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com