Primefaces 日历时区处理固定后端时区

Primefaces calendar timezone handling to fixed backend timezone

在网络应用程序中,用户可以选择传递给日历小部件的 timezone 属性的时区:

<p:calendar value="#{curValue}" timeZone="#{settingsBL.getTimeZoneIdSet()}" />

支持 bean 中的交付日期被转换为服务器的时区(JBoss 在我使用 CEST 的情况下)。后端希望日期和时间与 UTC 一样(并以 UTC 格式提供)。 因此,当我存储日期时,我必须将 CEST 日期转换为 UTC 并保存。如果日期是从后端传递的,则为 UTC。我必须将它转换为系统默认值(JBoss with CEST)并且日历会确保它在客户端上正确显示。 这个对吗?我对此有点困惑。服务器时区是可变的,不能硬设置为 UTC 或其他。 对于我的示例,来自客户端的日期始终转换为 CEST。不管我在 web.xml.

中设置了什么 javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE

我正在使用 primefaces 5.2.13 和 Mojarra 2.2.12 JBoss 6.4

任何允许操作时间部分的基于 java.util.Date 的 JSF 组件的 timeZone 属性必须设置为视图(前端)所期望的。将 java.util.Date 实例从模型(后端)转换为 String 表示时将使用它,后者将嵌入生成的 HTML 输出中。当将传入的 String 请求参数值转换为将在模型中使用的具体 java.util.Date 实例时,也会使用它。如果你不允许操纵时间部分,那么就坚持默认的 timeZone="GMT".

现在关键来了:java.util.Date 保存任何时区信息。它在内部始终是 GMT。 JSF 知道这一点。 JDBC 知道这一点。 JPA 知道这一点。只要您告诉 JSF 视图使用什么时区,并且告诉 JDBC/JPA 数据库使用什么时区,那么一切都应该没问题。

也许你的困惑是因为你做了类似System.out.println(date)的事情来验证一个和另一个。它是 toString() result will internally use TimeZone#getDefault(),因此在 String 生成期间没有明确使用 GMT/UTC。然后,您会困惑地看到正在打印系统默认时区的 date。要使用 GMT 时区打印 date(为了 debug/log/verify 等),请执行以下操作:

System.out.println(DateTimeFormatter.ISO_DATE_TIME.format(date.toInstant().atZone(ZoneId.of("GMT"))));