有什么问题?
严重问题清单包括:
- 您正在使用设计不佳且早已过时的 Java 日期和时间类
Date
,TimeZone
并且SimpleDateFormat
.
- 您正在使用已弃用的方法
getMonth
和getDate
类。这些方法跨时区工作不可靠,这是它们被弃用的主要原因。getYear
Date
- 您正在使用加法、减法和乘法手动进行时区转换。日期和时间数学容易出错,您应该始终将其留给经过验证的库方法。
- 您获得的毫秒数
Date.getTime
是自 1970-01-01T00:00:00 UTC 的纪元以来。这是一个独特的时间时刻,与时区无关,因此为时区转换添加和减去毫秒计数是没有意义的。
- 当我将 JVM 的默认时区设置为 Asia/Seoul 并假设
HOUR
为 0(或 0 到 111 范围内的某个值)时,我可以重现您的结果。我假设您想要HOUR
表示一小时内的毫秒数,3 600 000(至少通常存在例外)。
- 您通过连接调用结果来格式化日期
Strirg.format
。最好将格式化留给专门的日期格式化程序。
修复:java.time
ZoneId serverTimeZone = ZoneId.of("Asia/Seoul");
DateTimeFormatter serverFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
ZoneId clientTimeZone = ZoneId.systemDefault();
String checkedDate = "2019-06-24 16:15:31";
ZonedDateTime serverDateTime = LocalDateTime.parse(checkedDate, serverFormatter)
.atZone(serverTimeZone);
ZonedDateTime clientDateTime = serverDateTime.withZoneSameInstant(clientTimeZone);
System.out.println("clientDateTime: " + clientDateTime);
抱歉,我只能编写和运行 Java 代码,我相信你会翻译。我的 JVM 时区仍设置为亚洲/首尔,我得到:
客户日期时间:2019-06-24T16:15:31+09:00[亚洲/首尔]
根据您的要求,服务器时间和客户端时间相同。相反,如果我保留自己的时区,我会得到:
客户日期时间:2019-06-24T09:15:31+02:00[欧洲/哥本哈根]
所以发生了转换。
要格式化日期:
DateTimeFormatter displayFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)
.withLocale(Locale.forLanguageTag("ko-KR"));
String transformedLocalDate = clientDateTime.format(displayFormatter);
System.out.println("transformedLocalDate: " + transformedLocalDate);
转换本地日期:2019 年 6 月 24 日。
或者如果你坚持要月.日期.年:
DateTimeFormatter displayFormatter = DateTimeFormatter.ofPattern("MM.dd.u");
转换本地日期:06.24.2019
进一步的建议是让您的服务器以 UTC 格式以 ISO 8601 格式提供日期时间字符串。就像2019-06-24T07:15:31Z
示例中使用的那一刻一样。
问:我可以在 Android 上将 java.time 与 minSdk API 级别 23 一起使用吗?
是的,java.time 在较旧和较新的 Android 设备上运行良好。它只需要至少Java 6。
- 在 Java 8 及更高版本以及更新的 Android 设备(从 API 级别 26 开始)中,现代 API 是内置的。
- 在 Java 6 和 7 中获得 ThreeTen Backport,现代类的后向端口(ThreeTen 用于 JSR 310;请参阅底部的链接)。
- 在(较旧的)Android 上使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。并确保从
org.threeten.bp
子包中导入日期和时间类。
链接