【问题标题】:How to format java.time.LocalDateTime and java.time.LocalDate with pattern?如何用模式格式化 java.time.LocalDateTime 和 java.time.LocalDate?
【发布时间】:2016-12-14 07:38:10
【问题描述】:

在下面截断属性$F 属于java.time.LocalDateTimejava.time.LocalDate 类。

<textField pattern="EE. dd.MM.yyyy">
    <reportElement...>
    </reportElement>
    <textFieldExpression><![CDATA[$F{theLocalDateTime}]]></textFieldExpression>
</textField>

如何在 jasper 报告中使用 textField pattern 格式化此属性?

【问题讨论】:

  • 使用像这里显示的常规格式化程序stackoverflow.com/a/15817417/1743880,但是对于 Java 8?应该是DateTimeFormatter.ofPattern(myPattern).format($F{thedatetime})
  • @Tunaki 在这种情况下,用户喜欢使用在导出为不同格式时也更可取的模式(因此在 excel 等中格式正确),模式可以用于 java.util.Date 对象,因此解决方案是将字段转换为此类(或子类)并等待 jasper-reports 更新其库以支持使用 LocalDateTime 类的模式进行格式化
  • 您不想要LocalDateTimejava.sql.Timestamp 类已替换为 java.time.InstantOffsetDateTime(其偏移量设置为 UTC)。请参阅此问题,What's the difference between Instant and LocalDateTime?

标签: java jasper-reports java-time


【解决方案1】:

要在当前版本的 jasper-report 中为日期/时间对象使用 pattern 属性,您需要一个 java.util.Date 类或其子类之一。

解决办法是转换java.time.LocalDatejava.time.LocalDateTime

转换为java.util.Date

from java.time.LocalDate

<textField pattern="EE. dd.MM.yyyy">
    <reportElement...>
    </reportElement>
    <textFieldExpression><![CDATA[java.util.Date.from($F{theLocalDate}.atStartOfDay(java.time.ZoneId.systemDefault()).toInstant())]]></textFieldExpression>
</textField>

from java.time.LocalDateTime

<textField pattern="EE. dd.MM.yyyy">
    <reportElement...>
    </reportElement>
    <textFieldExpression><![CDATA[java.util.Date.from($F{theLocalDateTime}.atZone(java.time.ZoneId.systemDefault()).toInstant())]]></textFieldExpression>
</textField>

Converting to java.sql.Timestamp

来自java.time.LocalDate

<textField pattern="EE. dd.MM.yyyy">
    <reportElement...>
    </reportElement>
    <textFieldExpression><![CDATA[java.sql.Timestamp.valueOf($F{theLocalDate}.atStartOfDay())]]></textFieldExpression>
</textField>

来自java.time.LocalDateTime

<textField pattern="EE. dd.MM.yyyy">
    <reportElement...>
    </reportElement>
    <textFieldExpression><![CDATA[java.sql.Timestamp.valueOf($F{theLocalDateTime})]]></textFieldExpression>
</textField>

注意: 应用模式总是更好的解决方案,特别是当 导出到 excel,因为正确的类将被传递给 poi(因此 excel 会将列识别为日期并应用与中相同的格式 模式)

【讨论】:

  • Timestamp 确实 映射到LocalDateTimeTimestamp 代表一个时刻,时间线上的一个特定点。 LocalDateTime 故意缺少任何时区或从 UTC 偏移的概念。因此,它不能代表片刻。它代表大约 26-27 小时(全球时区范围)范围内的潜在时刻。 TimestampInstant 类或偏移设置为 UTC 的 OffsetDateTime 替换。因此java.sql.Timestamp::toInstant 方法。
【解决方案2】:

由于java.time 模块有点复杂和冗长,我通常会创建一些变量来保存已编译的 DateTimeFormatter 以供进一步使用。

我希望我的报告适应任何语言环境,因此我不使用字符串文字进行格式化。

我正在使用报告区域设置,但您可以使用java.util.Locale.forLanguageTag("en-US") 选择您的区域设置,例如。

如果需要,您还可以更改java.time.format.FormatStyle

LocalDate 格式化程序:

    <variable name="dateFormatter" class="java.time.format.DateTimeFormatter">
        <variableExpression><![CDATA[java.time.format.DateTimeFormatter
  .ofLocalizedDate(java.time.format.FormatStyle.SHORT)
  .withLocale($P{REPORT_LOCALE})
  .withChronology(java.time.chrono.Chronology.ofLocale($P{REPORT_LOCALE}))]]></variableExpression>
    </variable>

LocalDateTime 格式化程序:

    <variable name="dateTimeFormatter" class="java.time.format.DateTimeFormatter">
        <variableExpression><![CDATA[java.time.format.DateTimeFormatter
  .ofLocalizedDateTime(java.time.format.FormatStyle.SHORT)
  .withLocale($P{REPORT_LOCALE})
  .withChronology(java.time.chrono.Chronology.ofLocale($P{REPORT_LOCALE}))]]></variableExpression>
    </variable>

现在我可以用这种方式格式化 LocalDate 字段:

$F{localDateField}.format($V{dateFormatter})

这样一个 LocalDateTime 字段:

$F{localDateTimeField}.format($V{dateTimeFormatter})

【讨论】:

  • 谢谢 - 这拯救了我的一天!我更喜欢这个解决方案,因为它允许在文本字段中使用字符串文字以及格式化的日期,例如"formatted date is " + $F{localDateField}.format($V{dateFormatter})
猜你喜欢
  • 1970-01-01
  • 2017-07-30
  • 1970-01-01
  • 1970-01-01
  • 2022-12-17
  • 2012-09-30
  • 2020-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多