如何解析未指定的偏移量?
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.time
。 SimpleDateFormat
不仅过时了,而且出了名的麻烦,所以java.time
是我强烈推荐的。
我有时间 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.time
。 SimpleDateFormat
不仅过时了,而且出了名的麻烦,所以java.time
是我强烈推荐的。