我需要在运行时更改DTO的每个时区。今天,当用户在我的web服务上执行请求时,时区是通过参数通知的,我想知道是否有可能对所有日期属性应用新的时区。我唯一不会用的是"时区"。setDefault (myTimeZone),因为这种方法适用于所有JVM,并且存在不同时区的用户,所以这种解决方案是不可行的。
我正在尝试这样做:
Query query = em.createNativeQuery(SQL.toString(), AgendamentoDTO.class);
collection = query.setParameter(1, idEmpresa).getResultList();
for (Field atributo : AgendamentoDTO.class.getDeclaredFields()) {
if (atributo.getType().isAssignableFrom(Date.class)) {
//Change time zone here
}
}
谢谢
避免设置默认时区
正如Question中明智的建议,您应该将JVM当前的默认时区设置为在最绝望的情况下的最后手段。设置默认值会影响在JVM中运行的所有应用程序的所有线程中的所有代码,并在它们执行时立即影响它们。
相反,在所有日期时间工作中,始终将可选的时区参数传递给各种方法。永远不要隐式地依赖JVM当前的默认区域。
避免使用旧的日期时间类
与早期Java版本捆绑在一起的旧的遗留日期时间类已被证明是设计不良、麻烦和令人困惑的。避免它们。现在被爪哇取代了。时间类。
所以用java.time.Instant
代替java.util.Date
。Instant
类表示UTC时间轴上的时刻,分辨率为纳秒。这个Instant
类是日期时间处理的基本构建块。经常使用这个类,因为您的大部分业务逻辑、数据存储、数据交换和数据库工作都应该使用UTC。不要认为UTC只是时区的另一种变化,相反,将UTC视为唯一的真实时间。在编程时,忘记您自己的本地时区,因为狭隘的思维会混淆您的编程。
Instant
一般来说,你的web服务应该接受并给出UTC值。Instant
类可以直接解析和生成字符串,以标准ISO 8601格式表示这些值。
Instant instant = Instant.parse( "2016-09-09T22:34:08Z" );
String output = instant.toString(); // Generates: 2016-09-09T22:34:08Z
所以不需要操作这些UTC值。让他们留在身边。数据提供服务应该在大多数情况下使用UTC。
在您的情况下,dto作为dto,应该坚持存储UTC值(Instant
对象或以Z
结尾的ISO 8601格式的UTC字符串)。根据定义,DTO在缺乏业务对象的意义上应该是"哑的",而应该只是传输基本的数据元素。使用这些dto的其他对象应该处理任何所需的时区分配。
ZonedDateTime
生成其他时区的字符串,仅用于向用户显示。在这里,我们指定了一个qusamubec时区,通过不同的挂钟时间来观察这一刻。应用ZoneId
得到ZonedDateTime
。ZonedDateTime
和Instant
都代表在历史上的同一时刻,在时间线上的同一点。
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
注意,我们在业务对象中保留了Instant
对象,未被修改。我们生成一个单独的对象,ZonedDateTime
,用于不同的时钟时间。
- 在代码中进行这些时区分配时,传递
ZoneId
对象。 - 当通过web服务API指定这些时区分配时,以字符串形式传递时区名称。始终使用正确的IANA ' tz '时区名称,格式为
continent/region
,如America/Montreal
或Pacific/Auckland
。永远不要使用3-4个字母的缩写,如EST
或IST
,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
当您的web服务提供要作为数据而不是表示来使用的数据时,生成ISO 8601格式的字符串。java。Time类默认使用这些标准格式来解析和生成字符串。只需调用toString
以生成标准格式的字符串。请注意,ZonedDateTime
通过在方括号中附加时区名称来扩展标准格式。
String output = instant.toString(); // 2016-09-09T22:34:08Z
String output = zdt.toString(); // 2016-09-09T19:34:08-03:00[America/Montreal]
当您的web服务向用户提供用于表示的信息,而不是作为数据使用时,请以适合用户的人类语言和文化规范的格式生成字符串。您可以指定一个特定的格式。但通常最好让java。时间自动为您定位。
Locale locale = Locale.CANADA_FRENCH;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( l );
String output = zdt.format( f );
标题>