如何解析未指定的偏移量?

How to parse offset it is not specified?

我有时间 12:00:00 格式 HH:mm:ss。
我知道这次来自服务器 设置了 +3 偏移量。
如果我使用 SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");,它会根据设备解析时间,它可以处于不同的时区。
除了将它添加到原始字符串之外,还有另一种关于 +3 偏移量的解析方法吗?

在您的 SimpleDateFormat 对象上设置时区:

SimpleDateFormat fmt = new SimpleDateFormat("HH:mm:ss");
fmt.setTimeZone(TimeZone.getTimeZone("GMT+03:00"));

我建议你使用 Java 8 日期和时间 API(包 java.time)而不是旧的 API,其中 SimpleDateFormat一部分。

使用 Java 8 日期时间 API:

DateTimeFormatter formatter = DateTimeFormatter
        .ofPattern("HH:mm:ss");

LocalTime clientLocalTime = LocalTime
        .parse("12:00:00", formatter)
        // Create an OffsetTime object set to the server's +3 offset zone
        .atOffset(ZoneOffset.ofHours(3))
        // Convert the time from the server timezone to the client's local timezone.
        // This expects the time value to be from the same day,
        // otherwise the local timezone offset may be incorrect.
        .withOffsetSameInstant(ZoneId.systemDefault().getRules().getOffset(Instant.now()))
        // Drop the timezone info - not necessary
        .toLocalTime();

首先,您的服务器是否应该以 UTC 格式发送时间?如果客户无处不在,这似乎会更加中立和标准化时区。然而,在代码中处理它的方式并没有太大的不同。在任何情况下,UTC 的服务器偏移量可以是常量:

private static final ZoneOffset serverOffset = ZoneOffset.ofHours(3);

不过,在实际代码中,您可能希望以某种方式使其可配置。解析:

    OffsetTime serverTime = LocalTime.parse("12:00:00").atOffset(serverOffset);
    System.out.println(serverTime);

这会打印

12:00+03:00

由于您的时间格式与 LocalTime 的默认格式 (ISO 8601) 一致,我们不需要明确的格式化程序。如果您只需要带偏移量的时间表示,我们就完成了。如果您需要转换为用户的当地时间,为了可靠地做到这一点,您需要同时确定时区和日期:

    LocalTime clientTime = serverTime.atDate(LocalDate.of(2018, Month.JANUARY, 25))
            .atZoneSameInstant(ZoneId.of("Indian/Maldives"))
            .toLocalTime();
    System.out.println(clientTime);

根据选择的日期和区域,我们得到

14:00

请替换您想要的时区和日期。

只是假设,如果您知道用户与 UTC 的偏移量,您可以使用:

    LocalTime clientTime = serverTime.withOffsetSameInstant(ZoneOffset.of("-08:45"))
            .toLocalTime();

该示例产生 00:15。但是,没有人知道政治家什么时候引入夏令时 (DST) 或用户时区的其他异常,所以我不鼓励单独依赖偏移量。

是的,我也在使用 java.timeSimpleDateFormat不仅过时了,而且出了名的麻烦,所以java.time是我强烈推荐的。