【发布时间】:2018-09-14 05:55:56
【问题描述】:
尝试使用 Java 的 DateTimeFormatter 支持 Javascript 的 new Date().toString() 输出格式,但似乎无法正常工作。
Js 输出具有以下性质:
- 2018 年 4 月 4 日星期三 09:56:16 GMT-0500(南非太平洋标准时间)
- 2018 年 4 月 4 日星期三 16:12:41 GMT+0200 (CEST)
我目前的格式化程序:
int defaultOffset = ZonedDateTime.now().getOffset().getTotalSeconds();
DateTimeFormatter dtfJs = new DateTimeFormatterBuilder()
.appendPattern("EE MMM dd yyyy HH:mm:ss [OOOO (zzzz)]")
.parseDefaulting(ChronoField.OFFSET_SECONDS,defaultOffset
.toFormatter();
如果我 .parse() 来自 js 的那些日期字符串,我会收到以下错误:
[date] 无法在索引 25 处解析
提到的两个日期的索引 25 是:
- GMT-0500(南非太平洋标准时间)
- GMT+0200 (CEST)
我知道问题出在 :(冒号),因为如果我用 dtfJs 打印当前日期,我会得到:
2018 年 4 月 4 日星期三 10:25:10 GMT-05:00(哥伦比亚时间)
所以GMT-05:00 的部分在收到的字符串中被执行为GMT-0500,但我找不到与此匹配的reserved pattern letter。
文档说:
Offset O:这会根据数量来格式化本地化的偏移量 图案字母。一个字母输出本地化的简写形式 offset,即本地化的偏移文本,例如'GMT',带小时 没有前导零,如果非零,可选的 2 位数分钟和秒, 和冒号,例如“GMT+8”。四个字母输出完整的形式, 这是本地化的偏移文本,例如 'GMT,带有 2 位数的小时和 分钟字段,可选的第二个字段(如果非零)和冒号,用于 例如“GMT+08:00”。任何其他的字母计数 IllegalArgumentException。
偏移 Z:这会根据图案的数量格式化偏移 字母。一个、两个或三个字母输出
小时和分钟,不带冒号,例如“+0130”。输出将 当偏移量为零时为“+0000”。四个字母输出完整形式 本地化偏移量,相当于四个字母的 Offset-O。这 如果偏移量,输出将是相应的本地化偏移量文本 为零。五个字母输出小时、分钟,可选秒 如果非零,则使用冒号。如果偏移量为零,则输出“Z”。六或 更多字母会引发 IllegalArgumentException。
这意味着四个字母将始终以冒号“:”输出,从而抛出DateTimeParseException
非常感谢您的帮助,谢谢
编辑
感谢@mszymborski,我成功地验证了括号部分“(CEST)”,这里有什么用处?
我尝试使用 EE MMM dd yyyy HH:mm:ss 'GMT'Z (zz) 但这仅适用于列表中的第二个日期,而不是第一个日期
- GMT-0500(南非太平洋标准时间)错误
- GMT+0200 (CEST) 通行证
【问题讨论】:
-
您可以转义 GMT 部分并使用 Z,例如:
EE MMM dd yyyy HH:mm:ss 'GMT'Z -
有趣的是,如果你遍历
TimeZone.getAvailableIDs(),然后从这些 ID 中获取 TimeZone (TimeZone.getTimeZone(id)),然后打印 ID 和显示名称,似乎 SA 太平洋标准时间不是那里。 CEST 也不存在,但中欧时间 (CET) 存在。不同之处在于 CEST 不跟踪夏令时。我认为使用 DateTimeFormatter 是不可行的。 -
进一步补充——有人发布了这个:github.com/nfergu/Java-Time-Zone-List/blob/master/TimeZones/src/…,看来你需要准备某种字典来在 JS 区域和 Java 区域之间进行翻译。
-
您绝对不应该依赖 JS
Date.toString()返回的内容:每个应用程序/浏览器/用户区域设置都不同。如果您想通过 REST 调用进行通信,请确保双方完全确定数据传输的格式:这种方式对双方来说要容易得多。例如,使用Date.toISOString -
@estebanrincon,您实际上根本不需要时区名称。您已经有了时区偏移,这足以构建一个明确的
Instant值。不管名字是什么,你都可以忽略它。
标签: javascript java java-8 java-time