дата и время показывают ошибку синтаксического анализа по определенному индексу

Я получаю дату и время из URL-адреса JSON API, формат которого похож на этот

          '2021-03-05 09:18:07' which is in String form.

но когда я хочу преобразовать его в миллисекунды, это дает мне ошибку индекса 10. Я не знаю, почему возникает эта проблема. Я проверяю другой ответ Stackoverflow, но не получил успеха.

        DateTimeFormatter formatter ;
                                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
                                    formatter = DateTimeFormatter.ofPattern(
                                            "yyyy-MM-dd'T'HH:mm:ss", Locale.ROOT);
                                    String dates = object.getString("created_at");
                                   long  timeInMilliseconds = OffsetDateTime.parse(dates, formatter)
                                            .toInstant()
                                            .toEpochMilli();
                                    System.out.println("Date in milli :: USING ThreeTenABP >>> " + 
                                   timeInMilliseconds);

                                }
                                String text = TimeAgo.using(timeInMilliseconds);
                                FeedModel.setDateSnap(text);

и вот ошибка

           java.time.format.DateTimeParseException: Text '2021-03-05 09:18:07' could not be parsed: Unable 
     to obtain OffsetDateTime from TemporalAccessor: {},ISO resolved to 2021-03-05T09:18:07 of type 
     java.time.format.Parsed
    at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1920)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1855)
    at java.time.OffsetDateTime.parse(OffsetDateTime.java:396)
    at com.example.wasigram.MainActivity$1.onResponse(MainActivity.java:91)
    at com.androidnetworking.common.ANRequest.deliverSuccessResponse(ANRequest.java:729)
    at com.androidnetworking.common.ANRequest.access$6500(ANRequest.java:80)
    at com.androidnetworking.common.ANRequest$6.run(ANRequest.java:709)
    at android.os.Handler.handleCallback(Handler.java:888)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loop(Looper.java:213)
    at android.app.ActivityThread.main(ActivityThread.java:8178)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
 Caused by: java.time.DateTimeException: Unable to obtain OffsetDateTime from TemporalAccessor: {},ISO resolved to 2021-03-05T09:18:07 of type java.time.format.Parsed
    

2 ответа

Использование Java SE 8 API:

Вы можете использовать <tcode id="4274738"></tcode> чтобы получить форматтер с указанной зоной.

Также используйте правильный формат, yyyy-MM-dd HH:mm:ss который не имеет 'T'которые вы по ошибке вставили в свой узор. На самом деле я предпочитаю использовать u к yкак объяснено в этом ответе .

Демо:

      import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "2021-03-05 09:18:07";
        
        DateTimeFormatter formatter = DateTimeFormatter
                                        .ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH)
                                        .withZone(ZoneOffset.UTC);
        
        long millis = OffsetDateTime
                        .parse(strDateTime, formatter)
                        .toInstant()
                        .toEpochMilli();
        
        System.out.println(millis);
    }
}

Выход:


Узнайте больше о современном API даты и времени из Trail: Date Time .

Использование ThreeTen-Backport API:

      import java.util.Locale;

import org.threeten.bp.LocalDateTime;
import org.threeten.bp.ZoneOffset;
import org.threeten.bp.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "2021-03-05 09:18:07";
        
        DateTimeFormatter formatter = DateTimeFormatter
                                        .ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
        
        long millis = LocalDateTime
                        .parse(strDateTime, formatter)
                        .toInstant(ZoneOffset.UTC)
                        .toEpochMilli();
        
        System.out.println(millis);
    }
}

Выход:

      1614935887000

У вас две проблемы:

  1. Строка шаблона формата не совсем соответствует строке из JSON.
  2. Вы не можете наивно разобрать событие, которое не содержит смещения UTC, в файл.

Строка шаблона формата

Индексируйте 10 в своей строке 2021-03-05 09:18:07это место, где находится пробел после дня месяца. Итак, давайте посмотрим на ваш шаблон формата, чтобы увидеть, что ожидается после дня месяца. Строка вашего шаблона формата yyyy-MM-dd'T'HH:mm:ss, а после наступает день месяца, что означает буквальное, то есть не шаблонное письмо. Ваше исключение возникает из-за того, что a и пробел не равны.

Совет по проблемам синтаксического анализа: если вы не видите, что не так при синтаксическом анализе, попробуйте сначала отформатировать.

          String dates = "2021-03-05 09:18:07";
    DateTimeFormatter formatter 
            = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss", Locale.ROOT);
    
    OffsetDateTime expectedResult
            = OffsetDateTime.of(2021, 3, 5, 9, 18, 7, 0, ZoneOffset.ofHours(1));
    
    System.out.println("Parsing:   " + dates);
    System.out.println("Formatted: " + expectedResult.format(formatter));

Выход:

       Parsing:   2021-03-05 09:18:07
Formatted: 2021-03-05T09:18:07

Я надеюсь, что теперь легче увидеть разницу между пробелом в вашей строке и T в строке, которую ожидает форматер.

Возможно, вы уже догадались, что решение: в строке шаблона формата введите пробел вместо 'T' (если хотите, можете заключить пробел в одинарные кавычки, но это необязательно).

Разбор в OffsetDateTime

Это исправление по-прежнему не удается:

          // Put a space in the format pattern string
    DateTimeFormatter formatter 
            = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.ROOT);
    
    OffsetDateTime odt = OffsetDateTime.parse(dates, formatter);

Исключение в потоке «main» java.time.format.DateTimeParseException: текст «2021-03-05 09:18:07» не может быть проанализирован: невозможно получить OffsetDateTime от TemporalAccessor: {}, ISO разрешено до 2021-03-05T09:18:07 типа java.time.format.Parsed

Как ни странно, это также исключение в трассировке стека в вашем вопросе.

An OffsetDateTimeдолжен содержать смещение от UTC, а Java не откуда его взять. Вы знаете, какой часовой пояс принимает API, из которого вы получили строку? Если да, воспользуйтесь им. Мое предложение:

          ZoneId zoneAssumedByApi = ZoneId.of("Antarctica/Troll");
    long  timeInMilliseconds = LocalDateTime.parse(dates, formatter)
            .atZone(zoneAssumedByApi)
            .toInstant()
            .toEpochMilli();
    System.out.println("Date in milli :: USING ThreeTenABP >>> "
            + timeInMilliseconds);

Дата в милли :: ИСПОЛЬЗОВАНИЕ ThreeTenABP >>> 1614935887000

Другие вопросы по тегам