【发布时间】:2016-02-25 14:06:44
【问题描述】:
我在解析本地分区时间字符串时遇到问题(例如"12:00:00")。一些远程服务提供带有本地时间字符串的数据。服务的本地时区不时更改。有时服务的时钟不准确(最多几秒钟)。我的时钟也可能没有很好地校准。但我们很清楚,服务器上的数据总是最新的。
这是解释代码
private static ZoneOffset parseOffset(Clock now, String serviceLocal) {
LocalTime lt = LocalTime.parse(serviceLocal);
for (long s = HOURS.toSeconds(12); s > -HOURS.toSeconds(12); s -= MINUTES.toSeconds(30)) {
final ZoneOffset offset = ZoneOffset.ofTotalSeconds((int) s);
final LocalDate ld = LocalDate.now(now);
final ZonedDateTime zdt = ZonedDateTime.of(ld, lt, offset);
final long seconds = zdt.getLong(ChronoField.INSTANT_SECONDS);
if (seconds > now.instant().minusSeconds(MINUTES.toSeconds(30)).getEpochSecond()
&& seconds <= now.instant().getEpochSecond()) {
return offset;
}
}
throw new DateTimeException(String.format("Can't determine time zone of \"%s\". Current UTC time is \"%s\".",
serviceLocal, now.instant()));
}
/**
* This test passes. Detected offset is "GMT+6:00".
*/
@Test
public void shouldParseOffset_1() {
// given
String serviceLocal = "23:59:59";
Clock systemTime = Clock.fixed(Instant.parse("2016-02-25T18:00:00Z"), ZoneOffset.UTC);
// when
ZoneOffset offset = parseOffset(systemTime, serviceLocal);
// then
assertThat(offset, equalTo(ZoneOffset.of("+06:00")));
}
/**
* This test fails. As I said before data is always latest. It is easy to
* guess that some of systems (dedicated service or local) clock is not well
* calibrated. So zone offset should be still equal to "GMT+6:00".
*/
@Test
public void shouldParseOffset_2() {
// given
String serviceLocal = "00:00:01";
Clock systemTime = Clock.fixed(Instant.parse("2016-02-25T18:00:00Z"), ZoneOffset.UTC);
// when
ZoneOffset offset = parseOffset(systemTime, serviceLocal);
// then
assertThat(offset, equalTo(ZoneOffset.of("+06:00")));
}
让总误差不超过 10 秒。 100%的情况下如何确定服务器数据的准确时间?
【问题讨论】:
-
所以你有一个来自服务器的本地时间 - 你知道它是准确的 +/- 10 秒,你准确地知道当前时间并基于你想找到服务器 ZoneOffset?
-
@assylias 完全正确。我的
parseOffset方法的主要问题在于极端情况。例如。服务器的LocalDate可能与当前时间不同。
标签: java datetime timezone java-8 java-time