如何在 Java 中向时间戳添加/减去时区偏移量?

2024-05-15

我正在使用 JDK 8 并且玩过ZonedDateTime and Timestamp很多。但我仍然无法解决我面临的问题。

假设我得到了格式化的Timestamp在格林威治标准时间(UTC),我的服务器位于某处。假设它设置为Asia/CalcuttaTimeZone(其 ZoneOffset 为+05:30).

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

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

解释 :在输入中,时区偏移量 5hrs 30mts 已添加到输入中。此外,输入是 Timestamp 类型,输出也是 Timestamp 类型。

I use ZoneID.systemDefault()函数来检索 JVM 已知的时区。就我而言,时区结果是Asia/Calcutta.


A java.sql.Timestamp doesn't have any timezone information. It just has one value*: the number of nanoseconds since unix epoch (1970-01-01T00:00Z or "January 1st 1970 at midnight in UTC"). You don't convert this value to a timezone because this number is not attached to any specific timezone.

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

看一眼本文 https://codeblog.jonskeet.uk/2017/04/23/all-about-java-util-date/了解更多信息。它谈到java.util.Date,但概念是相同的:这些对象不携带任何格式或时区信息,因此您无法在时区之间转换它们。你可以改变的是表示不同区域中的这些值。

示例:如果我采取1505308230333000000作为自纪元以来的纳秒数。这个数字代表 UTC 的 13:10、圣保罗的 10:10、伦敦的 14:10、东京的 22:10、加尔各答的 18:40 等等。

The Timestamp类只保留大数值*。这个相同的值对应于每个时区的不同日期/时间,但它的价值对每个人来说都是一样的.

这就是为什么要转换Timestamp不同区域之间没有任何意义:您的Timestamp对象已经代表bothUTC 的 13:10 和加尔各答的 18:40(它包含与相应时区中的这些日期/时间相对应的大数值 - 更改此值将更改所有时区的相应本地日期/时间)。

你可以改变的是String这个大数值的表示(指定时区中相应的本地日期/时间)。


如果你想获得一个String不过,您可以使用另一个时区的相应日期和时间java.time类。

首先你需要转换java.sql.Timestamp to a java.time.Instant,然后将其转换为时区,结果是java.time.ZonedDateTime。最后,我将其格式化为String, 用一个java.time.format.DateTimeFormatter:

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()) - 当然,如果你愿意,你可以使用它,只要记住它即使在运行时也可以更改,恕不另行通知 https://stackoverflow.com/a/45797132/7605325,因此最好始终明确您正在使用哪一个。


*Actually, the Timestamp keeps the big number value in two fields: one for the seconds and another for the nanoseconds value. But that's an implementation detail, that doesn't change the concept that this value is not attached to any timezone and so there's no point in converting the Timestamp between zones

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Java 中向时间戳添加/减去时区偏移量? 的相关文章

随机推荐