如何在 Java 8 中用阿拉伯-印度数字解析字符串日期时间和时区?

Dar*_*nko 8 java datetime locale arabic java-8

我想用阿拉伯-印度数字解析字符串日期时间和时区,所以我编写了如下代码:

\n
    String dateTime = "\xd9\xa2\xd9\xa0\xd9\xa2\xd9\xa1-\xd9\xa1\xd9\xa1-\xd9\xa0\xd9\xa8T\xd9\xa0\xd9\xa2:\xd9\xa2\xd9\xa1:\xd9\xa0\xd9\xa8+\xd9\xa0\xd9\xa2:\xd9\xa0\xd9\xa0";\n    char zeroDigit = '\xd9\xa0';\n    Locale locale = Locale.forLanguageTag("ar");\n    DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX")\n            .withLocale(locale)\n            .withDecimalStyle(DecimalStyle.of(locale).withZeroDigit(zeroDigit));\n    ZonedDateTime parsedDateTime = ZonedDateTime.parse(dateTime, pattern);\n    assert parsedDateTime != null;\n
Run Code Online (Sandbox Code Playgroud)\n

但我收到了异常:

\n
\n

java.time.format.DateTimeParseException:文本'\xd9\xa2\xd9\xa0\xd9\xa2\xd9\xa1-\xd9\xa1\xd9\xa1-\xd9\xa0\xd9\xa8T\xd9\xa0\xd9 \xa2:\xd9\xa2\xd9\xa1:\xd9\xa0\xd9\xa8+\xd9\xa0\xd9\xa2:\xd9\xa0\xd9\xa0' 无法在索引 19 处解析

\n
\n

我在Stackoverflow上查了很多问题,但还是不明白我做错了什么。

\n

dateTime = "\xd9\xa2\xd9\xa0\xd9\xa2\xd9\xa1-\xd9\xa1\xd9\xa1-\xd9\xa0\xd9\xa8T\xd9\xa0\xd9\xa2:\xd9\xa2\xd9\xa1:\xd9\xa0\xd9\xa8+02:00"当时区不使用阿拉伯-印度数字时,它可以正常工作。

\n

Ole*_*.V. 5

你的dateTime字符串是错误的,被误解了。显然它试图遵循 ISO 8601 格式但失败了。因为 ISO 8601 格式使用 US-ASCII 数字。

\n

Instant如果只有数字对于 ISO 8601 来说是正确的,java.time( 、OffsetDateTime和)的类ZonedDateTime将在没有任何格式化程序的情况下解析您的字符串。在绝大多数情况下,我会采用您的方法:尝试按原样解析字符串。不是在这种情况下。对我来说,在解析之前更正字符串更有意义。

\n
    String dateTime = "\xd9\xa2\xd9\xa0\xd9\xa2\xd9\xa1-\xd9\xa1\xd9\xa1-\xd9\xa0\xd9\xa8T\xd9\xa0\xd9\xa2:\xd9\xa2\xd9\xa1:\xd9\xa0\xd9\xa8+\xd9\xa0\xd9\xa2:\xd9\xa0\xd9\xa0";\n    char[] dateTimeChars = dateTime.toCharArray();\n    for (int index = 0; index < dateTimeChars.length; index++) {\n        if (Character.isDigit(dateTimeChars[index])) {\n            int digitValue = Character.getNumericValue(dateTimeChars[index]);\n            dateTimeChars[index] = Character.forDigit(digitValue, 10);\n        }\n    }\n    \n    OffsetDateTime odt = OffsetDateTime.parse(CharBuffer.wrap(dateTimeChars));\n    \n    System.out.println(odt);\n
Run Code Online (Sandbox Code Playgroud)\n

输出:

\n
\n

2021-11-08T02:21:08+02:00

\n
\n

编辑:当然,如果您可以教育字符串的发布者使用 US-ASCII 数字,那就更好了。

\n

编辑:我知道我链接到下面的维基百科文章说:

\n
\n

表示形式必须以阿拉伯数字\n和特定计算机字符(例如“-”、“:”、“T”、“W”、“Z”)\n的组合编写,这些字符在标准中被指定了特定含义;\xe2\x80\xa6

\n
\n

这是造成混乱的一个可能原因。阿拉伯数字链接到的文章说:

\n
\n

阿拉伯数字是十个数字:0、1、2、3、4、5、6、7、8、9。

\n
\n

编辑:我如何转换每个数字:Character.getNumericValue()char代表数字的 a 转换为int等于该数字代表的数字的数字,因此转换为\'\xd9\xa0\'0、2\'\xd9\xa2\'等。它适用于所有数字字符(不仅是阿拉伯字符和 ASCII 字符) 。Character.forDigit()执行相反的转换,仅始终转换为 US ASCII,因此 0 到\'0\'、2 到\'2\'等。

\n

CharBuffer编辑:感谢@Holger在这方面引起我的注意。ACharBuffer实现了java.time 方法所需CharSequence的类型parse,因此我们无需将char数组转换回 a String

\n

链接

\n\n

  • @SreeKumar 感谢您指出您的错误。我认为其他人也可以做同样的事情,所以我添加了一段解释。 (2认同)