这个问题与我非常接近,但是我发现答案不适合我。我有时间戳一样长。
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"));
但结果是完全相同的。这个解决方案很有用,但原始的方法:
int offset = TimeZone.getTimeZone("Europe/Amsterdam").getRawOffset();
long newTime = timestamp - offset;
不适用夏令时/冬令时。建议的答案使用日历类,该类在JDK8中已过时。有效且足够明显的是:
OffsetDateTime.ofInstant(Instant.ofEpochMilli(Timestamp), ZoneId.of("UTC")).minusSeconds(7200);
但这绝对不是一种正确的方法,那么我如何使用时区来做到这一点呢?
我想时间戳是UTC
的,您需要将时间戳更改为CET
.看看withZoneSameInstant()
方法,可能会有所帮助。
long timeStamp = 1362156863140L;
ZoneId sourceZone = ZoneId.of("UTC");
ZoneId targetZone = ZoneId.of("CET");
String s = ZonedDateTime.ofInstant(Instant.ofEpochMilli(timeStamp), sourceZone)
.withZoneSameLocal(targetZone)
.toString();
System.out.println(s);