尽管系统时钟不准确,但解析ISO_LOCAL_TIME

时间:2016-02-25 14:06:45

标签: java datetime timezone java-8 java-time

我在解析本地分区时间字符串时遇到问题(例如"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%的情况下确定服务器数据的确切时间?

1 个答案:

答案 0 :(得分:2)

一种方法是首先调整服务器时间以反映“准确”时间(即向上或向下调整几秒以匹配正确的分钟数)。

然后,您可以计算服务器与当地时间之间的时差。

它可能看起来像:

onevent='onEventLink(#{user.getProperty()})'