上下搜索,左右 - 找不到此问题的简单答案:
我有java.util.date实例,从mysql获得其值。
也有登录用户的时区代码。
我需要在用户时区获取实际时间。
例如:
我的服务器机器时间区域是GMT 2。
我的日期值 db 是:2017-02-09 16:38:58.000
根据我的服务器机器时间区域,我将其放入 date实例 as:2017-02-09t16:38:58.000 0200
现在我需要知道:
对于示例,我的客户时间区域代码是GMT 4,我想获得:
2017-02-09 20:38:58.000
纯日期,这是我的时区的正确的,不包含" 4"或" GMT"指示。
简而
听起来很简单吗?阅读了很多文档后,我已经不确定这真的很简单。
时间戳记(带时区)
据我了解,在UTC中数据库中的日期时间,但是当您检索它时,您(错误地)收到2017-02-09T16:38:38:58.000 02:00。
首先,如果可以的话,将MySQL数据库列的数据类型更改为timestamp
(在其他一些数据库中,它称为timestamp with time zone
)。这将确保MySQL知道时代在UTC中,并且应该使您能够以正确的时间点来检索它们,而不是在错误的时区中的一天中的正确时间。反过来,这将为您提供转换为客户时区的最佳起点。
java.Time
第二,将您的价值从Java中检索到适当的类型。避免使用java.util.Date
,因为它的设计不佳并且无法处理不同的时区。例如,如果您的数据库数据类型为datetime
:
LocalDateTime dateTime = yourResultSet.getObject("your_col", LocalDateTime.class);
LocalDateTime
是没有时区的一天中的日期和时间,因此您无法获得错误的时区。提供您知道正确的偏移:
OffsetDateTime odt = dateTime.atOffset(ZoneOffset.UTC);
转换为客户时区:
ZoneId clientTimeZone = ZoneId.of("Indian/Reunion");
ZonedDateTime clientDateTime = odt.atZoneSameInstant(clientTimeZone);
System.out.println(clientDateTime);
2017-02-09T20:38:58 04:00 [印度/团圆]
对自己使用区域/城市格式中的实时区域的支持,而不是像 +04:00
这样的偏移。它更容易理解和更适合未来。当然,印度/聚会只是一个例子,请使用正确的客户。
上面的ZonedDateTime
在其中既有偏移量又有时区。建议保持这种方式,我认为它不会造成任何伤害。客户端总是可以选择不显示它。如果您仍然坚持,请再次转换为LocalDateTime
:
LocalDateTime clientDateTimeWithoutOffset = clientDateTime.toLocalDateTime();
System.out.println(clientDateTimeWithoutOffset);
2017-02-09T20:38:58
如果数据库数据类型为 timestamp
:
OffsetDateTime odt = yourResultSet.getObject("your_col", OffsetDateTime.class);
这节省了上面的第一步。其余的是相同的。
链接
Oracle教程:说明如何使用Java.Time。
java.util.date不存储任何时区。自1970年1月1日,00:00:00 UTC。
以来因此,您要做的就是了解服务器计算机的时区,找到该时区和要将其转换为并添加或减去期间的时区之间的时期。
更新:
int clientGMT = 4; //GMT you want to convert to
int serverGMT = 2; //server's GMT
int delta = clientGMT - serverGMT; //delta between the dates
//assume this is the date in GMT + 2 received from the server
Date d1 = new SimpleDateFormat("dd.MM.yyyy hh:mm:ss").parse("12.03.2019 13:00:00");
//... and you want to convert it to GMT + 4 (client side's time zone)
Date resultDate = new Date(d1.getTime() + delta * 3600000);
p.s。是的,您必须手动操纵时区,正如我上面所说,java.util.Date
不存储此信息(每个日期都假定在UTC中)。