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

从请求中获取zoneID以将请求日期和时间转换为java 8中的UTC格式,java,datetime,java-8,timezone,utc,Java,Datetime,Java 8,Timezone,Utc,我们有一个基于资源的服务,它将日期和时间作为参数从后端获取数据 数据以UTC格式存储在数据库中,服务器还配置了UTC时区 当从客户端收到请求时,我希望将日期和时间转换为UTC格式的日期和时间,然后相应地查询数据库 为了进行转换,我有下面的代码将给定的zoneId转换为UTC格式 public ZonedDateTime convertDateBetweenTimeZones(LocalDateTime sourceDateTime,String sourceZone,String targetZ

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

数据以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对象,我想我可以将它传递给数据库并相应地查询它

我的问题是,在我的例子中,我已经通过了“亚洲/加尔各答”作为源时区的zoneID。但是,源时区可以是任何东西,“美国/纽约”甚至“亚洲/新加坡”

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

有谁能帮助我如何获得zoneId或其他方法来处理我的场景

谢谢


JavaUser

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

HashMap<String, String> aliasMap = new HashMap<>();
aliasMap.put("FOO", "America/New_York");
ZoneId zoneId = ZoneId.of("FOO", aliasMap);
HashMap aliasMap=newhashmap();
别名map.put(“FOO”,“美国/纽约”);
ZoneId ZoneId=ZoneId.of(“FOO”,别名映射);

你每件事都做得很好,但有三件事你做得很好

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

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

您正在明智地使用
大陆/地区
格式,如
美洲/蒙特利尔
。切勿使用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规范对日期-时间处理过去这一主题几乎没有提及,只是模糊地无视了几天类型。一些人,比如博士后,对约会时间的支持很好,而另一些人的支持很差,而且他们的行为各不相同

浏览器时区 至于从网络浏览器中确定时区,这并不简单。更多信息,许多问题和答案已经发布

最后,唯一确定的方法是询问用户。从用户收集数据时包含时区字段