Java.util.date在客户端时区获取实际日期

问题描述 投票:0回答:2

上下左右搜索 - 找不到这个问题的简单答案:

我有java.util.Date实例,它从mySQL获取它的值。

我也有登录用户的时区代码。

我需要在用户时区获取实际时间。

例如:

我的服务器 - 机器时区是GMT + 2。

我在DB中的日期值是:2017-02-09 16:38:58.000

根据我的服务器机器时区我把它变成了日期实例:2017-02-09T16:38:58.000 + 0200

现在我需要知道如果做什么:

如果是示例,我的客户端时区代码是GMT + 4,我想得到:

2017-02-09 20:38:58.000

纯日期,这是我的时区,不包含“+4”或“GMT”指示。

简而言之:将我的java.util.date转换为特定时区的纯日期。

听起来很简单?在阅读了很多文档后,我已经不确定这是非常简单的。

java timezone java.util.date
2个回答
0
投票

java.util.Date不存储任何时区。它只存储自'epoch'以来的毫秒数,即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);

附:是的,您必须手动操作时区,如上所述,java.util.Date不存储此信息(假设每个日期都是UTC)。


3
投票

时间戳(带时区)

据我所知,您的数据库中的日期时间是UTC,但是当您检索它时,您(错误地)收到2017-02-09T16:38:58.000 + 02:00。

首先,如果可以,将MySQL数据库列的数据类型更改为timestamp(在其他一些数据库中,它将被称为timestamp with time zone)。这将确保MySQL知道时间是UTC,并且应该使您能够在正确的时间点检索它们,而不是在错误的时区中正确的时间。这反过来将为您提供转换到客户端时区的最佳起点。

java.time

其次,从java.time(现代Java日期和时间API)中将您的值检索为适当的类型。避免使用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这样的偏移量。它更容易理解,更具有前瞻性。 Indian / Reunion只是一个例子,当然,为您的客户使用正确的一个。

上面的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 tutorial: Date Time解释如何使用java.time。

© www.soinside.com 2019 - 2024. All rights reserved.