将包含阿拉伯字符的字符串转换为日期
Converting a string with Arabic characters to a date
我正在尝试验证项目列表是否根据其日期 desc 通过 Java 和 appium 进行了排序。我设法从屏幕上将日期作为字符串提取出来,但我在将这些字符串转换为日期时遇到了困难,因为该字符串基本上包含阿拉伯语日期,如下所示:
يناير٧٢٠٢٠
我试过使用下面的代码,
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu d MMMM ", new Locale("ar"));
LocalDate orderDate = LocalDate.parse(date, formatter);
但是,我收到以下错误:
java.time.format.DateTimeParseException: Text 'يناير ٧ ٢٠٢٠' could not be parsed at index 0
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
at java.base/java.time.LocalDate.parse(LocalDate.java:428)
at com.hs.mobile.steps.MyOrdersSteps.getDate(MyOrdersSteps.java:142)
at com.hs.mobile.steps.MyOrdersSteps.getOrdersDates(MyOrdersSteps.java:133)
at com.hs.mobile.steps.MyOrdersSteps.verifyOrdersSortedByDateDesc(MyOrdersSteps.java:119)
at com.hs.mobile.tests.MyOrdersTests.navigateToOrders_OrdersShouldBeSortedByDate(MyOrdersTests.java:30)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:133)
at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:584)
at org.testng.internal.TestInvoker.invokeTestMethod(TestInvoker.java:172)
at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:46)
at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:804)
at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:145)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
at org.testng.TestRunner.privateRun(TestRunner.java:770)
at org.testng.TestRunner.run(TestRunner.java:591)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:402)
at org.testng.SuiteRunner.access[=11=]0(SuiteRunner.java:41)
at org.testng.SuiteRunner$SuiteWorker.run(SuiteRunner.java:443)
at org.testng.internal.thread.ThreadUtil.lambda$execute[=11=](ThreadUtil.java:67)
at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
您能否就此问题提供适当的解决方案?
谢谢
请查看我的解决方案,从 ar 转换为另一个语言环境确实非常棘手,因为当您从阿拉伯语阅读时,您必须像这样从右到左阅读文本:
the -> "يناير ٧ ٢٠٢٠" will be: january 7 2020
因此 DateFormatter 将如下所示:
SimpleDateFormat sdf =
new SimpleDateFormat("MMMM d yyyy", Locale.forLanguageTag("ar-SA-nu-arab"));
然后解析为日期:
Date d = sdf.parse(date);
并打印出来:
System.out.println(d);
它将打印:
Tue Jan 07 00:00:00 MSK 2020
只需使用 java.time 和 DateTimeFormatter
char arabicZero = '\u0660';
DateTimeFormatter dateFormatter = DateTimeFormatter
.ofPattern("MMMM d uuuu", Locale.forLanguageTag("ar"));
DecimalStyle arabicDecimalStyle
= dateFormatter.getDecimalStyle().withZeroDigit(arabicZero);
dateFormatter = dateFormatter.withDecimalStyle(arabicDecimalStyle);
String dateString = "يناير ٧ ٢٠٢٠";
LocalDate date = LocalDate.parse(dateString, dateFormatter);
System.out.println("Parsed date: " + date);
此片段的输出是:
Parsed date: 2020-01-07
在我最诚实的意见中,您尝试使用 DateTimeFormatter
来完成这项工作是正确的。此 class 是 java.time 的一部分,现代 Java 日期和时间 API。与旧的和过时的 SimpleDateFormat
相比,它默认使用西方数字,因此我们需要明确告诉它使用阿拉伯数字。正如评论中所讨论的,这种设计允许我们使用来自一种文化的月份名称和来自另一种文化的数字的任意组合来构建格式化程序,用于格式化和解析。
我正在尝试验证项目列表是否根据其日期 desc 通过 Java 和 appium 进行了排序。我设法从屏幕上将日期作为字符串提取出来,但我在将这些字符串转换为日期时遇到了困难,因为该字符串基本上包含阿拉伯语日期,如下所示: يناير٧٢٠٢٠
我试过使用下面的代码,
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu d MMMM ", new Locale("ar"));
LocalDate orderDate = LocalDate.parse(date, formatter);
但是,我收到以下错误:
java.time.format.DateTimeParseException: Text 'يناير ٧ ٢٠٢٠' could not be parsed at index 0
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
at java.base/java.time.LocalDate.parse(LocalDate.java:428)
at com.hs.mobile.steps.MyOrdersSteps.getDate(MyOrdersSteps.java:142)
at com.hs.mobile.steps.MyOrdersSteps.getOrdersDates(MyOrdersSteps.java:133)
at com.hs.mobile.steps.MyOrdersSteps.verifyOrdersSortedByDateDesc(MyOrdersSteps.java:119)
at com.hs.mobile.tests.MyOrdersTests.navigateToOrders_OrdersShouldBeSortedByDate(MyOrdersTests.java:30)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:133)
at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:584)
at org.testng.internal.TestInvoker.invokeTestMethod(TestInvoker.java:172)
at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:46)
at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:804)
at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:145)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
at org.testng.TestRunner.privateRun(TestRunner.java:770)
at org.testng.TestRunner.run(TestRunner.java:591)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:402)
at org.testng.SuiteRunner.access[=11=]0(SuiteRunner.java:41)
at org.testng.SuiteRunner$SuiteWorker.run(SuiteRunner.java:443)
at org.testng.internal.thread.ThreadUtil.lambda$execute[=11=](ThreadUtil.java:67)
at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
您能否就此问题提供适当的解决方案?
谢谢
请查看我的解决方案,从 ar 转换为另一个语言环境确实非常棘手,因为当您从阿拉伯语阅读时,您必须像这样从右到左阅读文本:
the -> "يناير ٧ ٢٠٢٠" will be: january 7 2020
因此 DateFormatter 将如下所示:
SimpleDateFormat sdf =
new SimpleDateFormat("MMMM d yyyy", Locale.forLanguageTag("ar-SA-nu-arab"));
然后解析为日期:
Date d = sdf.parse(date);
并打印出来:
System.out.println(d);
它将打印:
Tue Jan 07 00:00:00 MSK 2020
只需使用 java.time 和 DateTimeFormatter
char arabicZero = '\u0660';
DateTimeFormatter dateFormatter = DateTimeFormatter
.ofPattern("MMMM d uuuu", Locale.forLanguageTag("ar"));
DecimalStyle arabicDecimalStyle
= dateFormatter.getDecimalStyle().withZeroDigit(arabicZero);
dateFormatter = dateFormatter.withDecimalStyle(arabicDecimalStyle);
String dateString = "يناير ٧ ٢٠٢٠";
LocalDate date = LocalDate.parse(dateString, dateFormatter);
System.out.println("Parsed date: " + date);
此片段的输出是:
Parsed date: 2020-01-07
在我最诚实的意见中,您尝试使用 DateTimeFormatter
来完成这项工作是正确的。此 class 是 java.time 的一部分,现代 Java 日期和时间 API。与旧的和过时的 SimpleDateFormat
相比,它默认使用西方数字,因此我们需要明确告诉它使用阿拉伯数字。正如评论中所讨论的,这种设计允许我们使用来自一种文化的月份名称和来自另一种文化的数字的任意组合来构建格式化程序,用于格式化和解析。