Преобразование строки с арабскими c символами в дату - PullRequest
2 голосов
/ 15 января 2020

Я пытаюсь проверить, что список элементов отсортирован по их дате от c до Java и appium. Мне удалось извлечь даты с экрана в виде строки, но я сталкиваюсь с трудностями при преобразовании этих строк в даты, потому что строка в основном содержит арабскую c дату, как показано ниже: يناير ٧ ٢٠٢٠

Я пытался использовать приведенный ниже код,

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$000(SuiteRunner.java:41)
    at org.testng.SuiteRunner$SuiteWorker.run(SuiteRunner.java:443)
    at org.testng.internal.thread.ThreadUtil.lambda$execute$0(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)

Не могли бы вы посоветовать правильное решение этой проблемы?

Спасибо

Ответы [ 2 ]

4 голосов
/ 15 января 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);

Выходные данные из этого фрагмента:

Дата анализа: 2020-01-07

По моему наиболее честному мнению, вы поступили правильно, пытаясь использовать DateTimeFormatter для этой работы. Этот класс является частью java .time, современного Java API даты и времени. В отличие от старого и давно устаревшего SimpleDateFormat он использует западные цифры по умолчанию, поэтому нам необходимо явно указать арабские c цифры. Как обсуждалось в комментариях, этот дизайн позволяет нам создавать средства форматирования с любой комбинацией названий месяцев из одной культуры и цифр из другой, как для форматирования, так и для анализа.

2 голосов
/ 15 января 2020

Пожалуйста, ознакомьтесь с моим решением, действительно очень сложно конвертировать из ar в другую локаль, потому что когда вы читаете из арабского языка c, вы должны читать текст справа налево следующим образом:

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
...