Метка времени не может быть проанализирована Проблема java.time.format.DateTimeParseException: текст "25.09.2020, 12:46:00 PM" не может быть проанализирован с индексом 0
Я пытаюсь зафиксировать время до и после того, как проверяю значение временной метки на веб-странице, а затем подтверждаю, что моя временная метка попадает между этими временами. Однако я изо всех сил пытаюсь преобразовать мою временную метку String в сопоставимый формат чистым способом.
Instant b4 = Instant.now();
//My code submites a file that then triggers the timestamp. I retrieve it as a string
//exa string"9/25/2020, 11:03:18 AM"
DateTimeFormatter dtf = DateTimeFormatter
.ofPattern("MM/dd/yyyy, HH:mm:ss a")
.withZone(ZoneId.systemDefault());
Instant instantTimestamp = Instant.from(dtf.parse(timeStamp));
Instant after = Instant.now();
if (instantTimestamp.isAfter(b4) && instantTimestamp.isBefore(after)) {
testPass = true;
}
Assert.assertTrue(testPass);
Моя ошибка: java.time.format.DateTimeParseException: текст '25.09.2020, 12:46:00 PM' не может быть проанализирован с индексом 0
2 ответа
Несоответствие формата месяца и его значения в строке. Формат
MM
который указывает две цифры, но значение равно
9
что представляет собой одну цифру. Вы можете использовать отдельные буквы для месяца, дня, года, часа, минуты, секунды и т. Д., Чтобы уместить все допустимое количество цифр. Кроме того, я предлагаю вам проанализировать его без учета регистра, чтобы верхний и нижний регистр (например,
AM
и
am
) оба могут быть размещены.
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
// Given date-time string
String dateTimeString = "9/25/2020, 12:46:00 PM";
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("M/d/u, H:m:s a")
.toFormatter(Locale.ENGLISH);
// Convert the given date-time string to LocalDateTime
LocalDateTime ldt = LocalDateTime.parse(dateTimeString, dtf);
System.out.println(ldt);
//Convert to LocalDateTime Instant if required
Instant instant=ldt.toInstant(ZoneOffset.UTC);
System.out.println(instant);
}
}
Вывод:
2020-09-25T12:46
2020-09-25T12:46:00Z
Ошибка связана с используемой строкой формата. "MM" требует, чтобы часть входной строки, содержащая месяц, состояла из двух цифр, а "9" - это только одна цифра. Другими словами, он работает "25.09.2020, 11:03:18 AM", но не "25.09.2020, 11:03:18 AM".
Здесь нужна буква "M", которая не требует, чтобы перед значением был "0":
DateTimeFormatter dtf = DateTimeFormatter
.ofPattern("M/dd/yyyy, HH:mm:ss a")
.withZone(ZoneId.systemDefault());
Если дата также должна быть одной цифрой и не дополняться нулями для дней 0-9,
"M/d/yyyy, HH:mm:ss a"
вместо этого следует использовать шаблон.
Это описывается DateTimeFormatter
Документация Javadoc:
Все буквы от "A" до "Z" и от "a" до "z" зарезервированы как буквы шаблона. Определены следующие буквы шаблона:
Symbol Meaning Presentation Examples ------ ------- ------------ ------- [...] M/L month-of-year number/text 7; 07; Jul; July; J [...]
Текст: [...]
Число: если количество букв равно единице, то значение выводится с использованием минимального количества цифр и без заполнения. В противном случае в качестве ширины выходного поля используется количество цифр, при необходимости значение дополняется нулями. [...]
Число / текст: если количество букв шаблона равно 3 или больше, используйте правила для текста, указанные выше. В противном случае используйте числовые правила выше.
Поскольку "M" использует представление "число / текст", а количество букв в вашем формате ("MM") равно 2, то для месяца требуется ровно две цифры. При переключении на одну букву "M" используется минимальное количество цифр (одна цифра для месяцев 1–9 и две цифры для месяцев 10–12).