如何添加/减去时区偏移到Java的时间戳



我正在使用JDK 8,并且我玩了很多 ZonedDateTimeTimestamp。但是我仍然无法解决我面临的问题的解决方案。

可以说,我在GMT(UTC)中获得了格式化的Timestamp,并且我的服务器位于某个地方。假设它设置为Asia/Calcutta时区(其区域offset为 +05:30)。

如何基本上添加/减去我的时区偏移到时间戳?

Input : 2017-09-13 13:10:30.333
Output: 2017-09-13 18:40:30.333

说明:在输入中,添加了5小时30mts的时区偏移量已添加到输入中。另外,输入是类型的时间戳,输出也是。

我使用ZoneID.systemDefault()功能检索JVM已知的时区。就我而言,时区结果为 Asia/Calcutta

a java.sql.Timestamp没有任何时区信息。它只有一个值*:自Unix Epoch(1970-01-01T00:00Z" 1月1日 ST 1970年午夜时分在UTC的nanseconds)的数量" )。您不会将此值转换为时区,因为此数字未连接到任何特定时区。

打印Timestamp时,它调用toString()方法,然后在JVM默认时区打印相应的日期和时间。但是Timestamp本身没有附带时区。

请查看本文以获取更多信息。它讨论了java.util.Date,但是概念是相同的:这些对象没有任何格式或时区信息,因此您无法在时区之间转换它们。您可以更改的是不同区域中这些值的表示

示例:如果我将1505308230333000000作为纳秒数的数量,则自时代以来。同样的数字在UTC中代表13:10,在圣保罗的10:10,伦敦14:10,在东京22:10,在加尔各答18:40,等等。

Timestamp类只能保持大数值*。相同的值对应于每个时区中的不同日期/时间,,但每个人的值始终相同

这就是为什么在不同区域之间转换 Timestamp是没有道理的:您的 Timestamp对象已经代表在utc中和calcutta中的18:40(它包含与这些相对应的大数字值各个时区的日期/时间 - 更改此值将改变各个时区的本地日期/时间)。

您可以更改的是此大数字的String表示(指定时区中的相应本地日期/时间)。


如果要在另一个时区中获得带有相应日期和时间的String,则可以使用java.time类。

首先,您需要将java.sql.Timestamp转换为java.time.Instant,然后将其转换为时区,从而产生java.time.ZonedDateTime。最后,我使用java.time.format.DateTimeFormatter

将其格式化为String
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
// convert the timestamp to a zoneddatetime
ZonedDateTime z = timestamp.toInstant().atZone(ZoneId.of("Asia/Calcutta"));
// format it
System.out.println(z.format(fmt)); // 2017-09-13 18:40:30.333

输出为:

2017-09-13 18:40:30.333


如果您已经知道要使用的时区(在这种情况下为Asia/Calcutta),请不要使用默认时区(ZoneID.systemDefault()) - 当然可以使用它请注意,即使在运行时,也最好始终明确您使用的是哪一个。


*实际上,Timestamp在两个字段中保持大数值:一个为秒,另一个用于纳秒值。但这是一个实现细节,并不会改变此值未连接到任何时区的概念,因此在区域之间转换Timestamp

没有意义。

相关内容

  • 没有找到相关文章

最新更新