【发布时间】:2018-05-29 12:29:46
【问题描述】:
This question 非常接近我的,但是我发现答案不适合我。我的时间戳是 Long。
ts = 1362156863140L
因为它很长,我认为它是时区天真的时间戳,对吗?这是科隆当地时间的时间戳 - UTC+0200 (CET)。因此,当我将其转换为字符串时区感知时间戳时,我想获得:
2013-03-01T14:54:23.140Z
或
2013-03-01T16:54:23.140+02:00
我在问题开头使用答案中的解决方案:
Instant.ofEpochMilli(timestamp).atOffset(ZoneOffset.of("+2"));
返回:
2013-03-01T18:54:23.140+02:00
另一个时区:
Instant.ofEpochMilli(timestamp).atOffset(ZoneOffset.of("Z"));
返回:
2013-03-01T16:54:23.140Z
所以这些方法并没有真正改变时区,它们只是改变时间戳的表示。我还尝试了另一种方法:
OffsetDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.of("UTC"));
但结果完全一样。 This solutions 很有用,但方法新颖:
int offset = TimeZone.getTimeZone("Europe/Amsterdam").getRawOffset();
long newTime = timestamp - offset;
不考虑夏季/冬季时间。建议的答案使用 JDK8 已过时的 Calendar 类。有效且足够明显的是:
OffsetDateTime.ofInstant(Instant.ofEpochMilli(Timestamp), ZoneId.of("UTC")).minusSeconds(7200);
但这显然不是正确的方法,那么我该如何使用时区来做到这一点?
【问题讨论】:
-
您的问题太宽泛了?准确告诉我们您需要什么?
-
如何将这个 1362156863140L 转换成那个 2013-03-01T14:54:23.140Z
-
“因为它很长,我认为它是时区幼稚时间戳”。我会说相反。鉴于 long 不能(轻松)包含时区信息,因此以这种方式存储它是不可移植的。长时间戳必须是即时的,与时区无关(即 Unix 时间戳)。
-
这是我为您的输入时间戳值得到的。
2013-03-01T21:24:23.140 -
要么你的假设是错误的,要么你的长期价值是错误的。像您这样的长值通常表示自 1970 年 1 月 1 日 00:00 UTC 以来的毫秒数。这样理解,您的 long 值表示
2013-03-01T16:54:23.140Z,而不是2013-03-01T14:54:23.140Z(Z表示 UTC)。如果有人给你长期的价值并打算后者,他们会以非标准的方式做事,这势必会引起混乱。如果是这样,我不知道他们会如何处理夏季时间,所以我也无法告诉你应该如何处理。
标签: java java-8 timezone timestamp