从请求中获取zoneID以将请求日期和时间转换为java格式的{8}

时间:2016-09-11 10:18:25

标签: java datetime java-8 timezone utc

我们有一个基于资源的服务,它以日期和时间作为参数来从后端获取数据。

数据以UTC格式存储在数据库中,服务器也使用UTC时区配置。

当从客户端收到请求时,我想将日期和时间转换为UTC格式的日期和时间,然后相应地查询数据库。

为了进行转换,我有以下代码,它从给定的zoneId转换为UTC格式。

public ZonedDateTime convertDateBetweenTimeZones(LocalDateTime sourceDateTime,String sourceZone,String targetZone){
     return sourceDateTime.atZone( ZoneId.of(sourceZone)).withZoneSameInstant( ZoneId.of(targetZone));
    }

我调用上面的方法,

 ZonedDateTime zonedDateTime=convertDateBetweenTimeZones(LocalDateTime.now(),"Asia/Calcutta","UTC");

一旦我可以获得zonedDateTime对象,我想我可以将它传递给数据库并相应地查询它。

我的问题是,在我的情况下,我已将“Asia / Calcutta”作为源时区的zoneID。但是,源时区可以是任何东西,“America / New_York”甚至是“Asia / Singapore”。

因此,在这种情况下,我不确定如何从客户端收到的请求中动态获取zoneId,以便我可以相应地转换它。

任何人都可以帮助我如何获得zoneId或替代方式来处理我的场景。

谢谢,

JavaUser

2 个答案:

答案 0 :(得分:1)

你做得很好,但有三件事。

忽略服务器时区设置

服务器的时区设置应与您的编码无关。服务器设置可以随时更改,因此您不能依赖它。

始终将可选的时区对象传递给所有相关的java.time方法,以指定您期望/期望的任何时区。

明智地使用continent/region格式的proper IANA 'tz' time zone names,例如America/Montreal。切勿使用诸如ESTIST之类的3-4个字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

数据库

对于数据库交换,您可能需要从Instant通过ZonedDateTime方法提取toInstant。大多数严重的数据库都以UTC格式存储日期时间。 Instant类表示UTC时间轴上的一个时刻,分辨率为纳秒。

符合JDBC 4.2或更高版本的JDBC驱动程序可能直接通过InstantResultSet::getObject使用PrepatedStatement::setObject。如果没有,则回退到简要转换为java {s}类型,例如java.sql.Timestamp

使用日期时间处理仔细研究数据库的行为;各种数据库在此(!)上广泛地广泛。 SQL规范对日期时间处理的主题几乎没有说明,过去模糊地违反了几天的类型。像Postgres这样的人有很好的日期时间支持,而其他人的支持很差,而且行为各不相同。

浏览器时区

至于从网络浏览器确定时区,这并不简单。 Search Stack Overflow了解有关已发布的许多问题和解答的详细信息。

最终,唯一可靠的方法是询问用户。从用户收集数据时包括时区字段。

答案 1 :(得分:0)

一种解决方案是您可以使用别名映射来保留非标准时区ID并传递到ZoneId.of(id, alias)方法。例如:

HashMap<String, String> aliasMap = new HashMap<>();
aliasMap.put("FOO", "America/New_York");
ZoneId zoneId = ZoneId.of("FOO", aliasMap);