Разница между parse () DateFormat и SimpleDateFormat - PullRequest
6 голосов
/ 12 марта 2019

Я пытаюсь разобрать дату, используя LocalDateTime.parse метод, однако я получаю ошибку ниже.строка даты становится анализируемой, если я использую SimpleDateFormat простой объект формата даты.

Кто-нибудь сталкивался с этой проблемой!В чем разница между синтаксическим анализом от DateFormat и LocalDateTime

package com.example.demo;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;

public class App {

    public static final String DATE_TIME_PATTERN = "dd-MM-yyyy hh:mm:ss.SSS";

    public static final DateFormat DATE_TIME_FORMAT = new SimpleDateFormat(DATE_TIME_PATTERN);

    public static final String SEPERATOR = ",";

    public static void main(String[] args) {
        try {
            Date date = DATE_TIME_FORMAT.parse("12-03-2019 10:28:50.013");
            System.out.println("date : {} " + date);

            LocalDateTime startTimestamp = LocalDateTime.parse("12-03-2019 10:28:50.013", DateTimeFormatter.ofPattern(DATE_TIME_PATTERN)).plusNanos(1000000);
            System.out.println("startTimestamp : {} " + startTimestamp);
        } catch(Exception e) {
            e.printStackTrace();
        }

    }

}

ВЫХОД

date : {} Tue Mar 12 10:28:50 SGT 2019
java.time.format.DateTimeParseException: Text '12-03-2019 10:28:50.013' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {NanoOfSecond=13000000, HourOfAmPm=10, MicroOfSecond=13000, SecondOfMinute=50, MilliOfSecond=13, MinuteOfHour=28},ISO resolved to 2019-03-12 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.LocalDateTime.parse(LocalDateTime.java:492)
    at com.example.demo.App.main(App.java:21)
Caused by: java.time.DateTimeException: Unable to obtain LocalDateTime from TemporalAccessor: {NanoOfSecond=13000000, HourOfAmPm=10, MicroOfSecond=13000, SecondOfMinute=50, MilliOfSecond=13, MinuteOfHour=28},ISO resolved to 2019-03-12 of type java.time.format.Parsed
    at java.time.LocalDateTime.from(LocalDateTime.java:461)
    at java.time.format.Parsed.query(Parsed.java:226)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
    ... 2 more
Caused by: java.time.DateTimeException: Unable to obtain LocalTime from TemporalAccessor: {NanoOfSecond=13000000, HourOfAmPm=10, MicroOfSecond=13000, SecondOfMinute=50, MilliOfSecond=13, MinuteOfHour=28},ISO resolved to 2019-03-12 of type java.time.format.Parsed
    at java.time.LocalTime.from(LocalTime.java:409)
    at java.time.LocalDateTime.from(LocalDateTime.java:457)
    ... 4 more

1 Ответ

4 голосов
/ 12 марта 2019

Вы используете часы-часа-часа-вечера (1-12) для часа, который h в вашем паттерне, а не час-дня (0-23) , что составляет H, поэтому требуется дополнительная информация о AM / PM.

enter image description here

Таким образом, в идеале AM / PM должны быть указаны в строке даты, которая должна быть проанализирована вместе с a для am-pm-of-day , котораятакже необходимо добавить в строку DATE_TIME_PATTERN.

public static final String DATE_TIME_PATTERN = "dd-MM-yyyy hh:mm:ss.SSS a";

public static final DateFormat DATE_TIME_FORMAT = new SimpleDateFormat(DATE_TIME_PATTERN);

  public static final String SEPERATOR = ",";

    public static void main(String[] args) {
        try {
            Date date = DATE_TIME_FORMAT.parse("12-03-2019 10:28:50.013 AM");
            System.out.println("date : {} " + date);

            LocalDateTime startTimestamp = LocalDateTime.parse("12-03-2019 10:28:50.013 AM", DateTimeFormatter.ofPattern(DATE_TIME_PATTERN)).plusNanos(1000000);
            System.out.println("startTimestamp : {} " + startTimestamp);
        } catch(Exception e) {
            e.printStackTrace();
        }

    }

Вывод:

date : {} Tue Mar 12 10:28:50 IST 2019
startTimestamp : {} 2019-03-12T10:28:50.014

Мы можем видеть, что без правильного формата SimpleDateFormat работает, в то время как LocalDateTimeболее строгим, когда дело доходит до разбора недопустимых строк даты.В вашем случае, поскольку требуемая информация AM / PM отсутствует, LocalTime, возвращаемое из TemporalAccessor, равно null, и, следовательно, вы получаете Unable to obtain LocalTime from TemporalAccessor.

. Не знаю, почему SimpleDateFormatработает, есть метод с именем setLenient(boolean lenient), если вы передаете час, который больше 12 без упоминания a в шаблоне, и AM / PM в строке даты, то java.text.ParseException: Unparseable date: будет выброшено.

Но поскольку в вашем случае вы передаёте час как 10, это меньше, чем 12, и, следовательно, по умолчанию оно интерпретируется как AM .

Это код в классе SimpleDateFormat, где выполняется эта проверка:

case PATTERN_HOUR1: // 'h' 1-based.  eg, 11PM + 1 hour =>> 12 AM
     if (!isLenient()) {
         // Validate the hour value in non-lenient
         if (value < 1 || value > 12) {
             break parsing;
         }
     }
     // [We computed 'value' above.]
     if (value == calendar.getLeastMaximum(Calendar.HOUR) + 1) {
         value = 0;
     }
     calb.set(Calendar.HOUR, value);
     return pos.index;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...