我们有一个基于资源的服务,它以日期和时间作为参数从后端获取数据。
数据以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
你做得很好,但有三件事。
忽略服务器时区设置
服务器的时区设置应该与您的编码无关。服务器设置可以随时更改,因此您不能依赖于此。
总是将可选的时区对象传递给所有相关的java。时间方法,以指定您期望/希望的任何时区。
您明智地使用continent/region
格式的适当IANA 'tz'时区名称,例如America/Montreal
。永远不要使用3-4个字母的缩写,如EST
或IST
,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
对于数据库交换,您可能需要通过toInstant
方法从ZonedDateTime
中提取Instant
。大多数正规数据库都以UTC格式存储日期时间。Instant
类表示UTC时间轴上的时刻,分辨率为纳秒。
符合JDBC 4.2或更高版本的JDBC驱动程序可能直接通过ResultSet::getObject
和PrepatedStatement::setObject
使用Instant
。如果没有,请回到简单地转换为java。sql类型,如java.sql.Timestamp
。
仔细研究数据库的日期时间处理行为;不同的数据库在这方面差异很大 !SQL规范很少提到日期时间处理的主题,只是模糊地反对几天类型。有些像Postgres有很好的日期时间支持,而其他的支持很差,而且行为各不相同。
浏览器时区
至于从web浏览器中确定时区,这并不简单。搜索堆栈溢出的更多信息与许多问题和答案已经发布。
最终,唯一确定的方法是询问用户。在从用户收集数据时包含时区字段。 标题>一个解决方案是您可以使用别名映射来保留非标准时区id并传递给ZoneId.of(id, alias)
方法。例子:
HashMap<String, String> aliasMap = new HashMap<>();
aliasMap.put("FOO", "America/New_York");
ZoneId zoneId = ZoneId.of("FOO", aliasMap);