如何解析偏移量未指定?

时间:2018-01-24 10:05:37

标签: java time timezone-offset datetime-parsing

我的时间是12:00:00,格式为HH:mm:ss。
我知道这次来自服务器女巫设置为+3偏移 如果我使用SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");,它会解析设备的时间,设备可能位于不同的时区 除了将其添加到原始字符串之外,是否有其他方法可以解析+3偏移量?

3 个答案:

答案 0 :(得分:2)

SimpleDateFormat对象上设置时区:

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

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

答案 1 :(得分:2)

首先,您的服务器是否应该以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是我热烈推荐的。

答案 2 :(得分:1)

使用Java 8 DateTime 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();