Проблемы с синтаксическим анализом даты

#java #parsing

#java #синтаксический анализ

Вопрос:

Добрый вечер, подскажите, пожалуйста, как решить проблему с синтаксическим анализом даты. Данные записываются в формате txt. файл, когда я его читаю и анализирую (включая дату объекта), выдает ошибку с датой (((пожалуйста, помогите мне это исправить. Я использую только javaCore.

 public class DemoRoom {

public static SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy");

public static void main(String[] args) throws Exception {
    Path path = new Path();
    RoomRepository roomRepository = new RoomRepository();


    Hotel hotel1 = new Hotel(1L, "Ajax", "Holland", "Amsterdam", "Amsterdamskaja");
    Hotel hotel2 = new Hotel(2L, "Slask", "Poland", "Wroclaw", "Wroclawskaja");
    Hotel hotel3 = new Hotel(3L, "Dynamo", "Ukraine", "Kyiv", "Obolonskaja");


    String newDate1 = "07-Jun-2019";
    String newDate2 = "10-Nov-2020";
    String newDate3 = "31-Dec-2020";

    Room room1 = new Room(1L, 2, 200.0, false, false, dateFormat.parse(newDate1), hotel1);
    Room room2 = new Room(2L, 5, 1900.99, true, true, dateFormat.parse(newDate2), hotel2);
    Room room3 = new Room(3L, 1, 499.99, true, false, dateFormat.parse(newDate3), hotel3);

    
    roomRepository.addRoom(room1, path.getRoomDB());
  

Синтаксический анализ
Дата находится под пятым элементом.

     @Override
public Room pars(String str) throws Exception {
    if (str == null)
        throw new Exception("String does not exist!");
    String[] arr = str.split(",");
    Room room = new Room();
    room.setId(Long.parseLong(arr[0]));
    room.setNumberOfGuests(Integer.parseInt(arr[1]));
    room.setPrice(Double.parseDouble(arr[2]));
    room.setBreakfastIncluded(Boolean.parseBoolean(arr[3]));
    room.setPetsAllowed(Boolean.parseBoolean(arr[4]));
    room.setDateAvailableFrom(DemoRoom.dateFormat.parse(arr[5]));
    new HotelRepository().findHotelById((arr[6]));
    return room;
}
  

Результат
введите описание изображения здесь
введите описание изображения здесь

Комментарии:

1. Почему вы не используете класс SimpleDateFormat, как в 1-м примере?

2. @MironBalcerzak Я пробовал, это тоже не работает((( room.setDateAvailableFrom(SimpleDateFormat.getInstance().parse(arr[5]));

3. Смотрите мой ответ.. @MironBalcerzak имеет в виду, почему вы вызываете getInstance() .

Ответ №1:

java.time

Вы используете ужасные классы даты и времени, которые были вытеснены несколько лет назад современной java.time framework. Никогда не используйте Date , Calendar , SimpleDateFormat , и так далее.

LocalDate

Для значения только для даты без времени суток и без часового пояса используйте LocalDate class .

Избегайте текстового обмена значениями даты и времени с использованием локализованных форматов. При обмене строками используйте только стандартные форматы ISO 8601. Для значения только для даты этот формат равен ГГГГ-ММ-ДД. Классы java.time по умолчанию используют форматы ISO 8601, поэтому нет необходимости указывать шаблон форматирования.

 LocalDate localDate = LocalDate.parse( "2019-06-07" ) ;
  

Если вам необходимо проанализировать локализованные строки, позвольте DateTimeFormatter выполнить эту работу.

 DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MMM-uuuu" ) ;
  

Укажите Locale , что нужно использовать при синтаксическом анализе названия месяца.

 Locale locale = Locale.US ;  
f = f.withLocale( locale ) ;
  

Проанализируйте входящие данные.

 String input = "07-Jun-2019" ; 
LocalDate localDate = LocalDate.parse( input , f ) ;
  

Ваш Room класс должен содержать поле-член типа LocalDate .

 Room x = new Room ( … , localDate , … ) ;
  

И хорошо проанализируйте свои входные данные перед передачей в конструктор. Вы всегда должны ожидать ошибочных входных данных.

 try{
    LocalDate localDate = LocalDate.parse( input , f ) ;
    …
} catch ( DateTimeParseException e ) {
    … 
}
  

Комментарии:

1. Большое вам спасибо, я этого не знал (((( Я это исправлю.

Ответ №2:

Когда вы запускаете приведенный ниже код, вы вызываете метод, который возвращает новый экземпляр SimpleDateFormat, который использует конструктор по умолчанию вместо конструктора, определяющего требуемый формат («дд-МММ-гггг»).

     dateFormat.getInstance().parse(newDate1);
  

Удалите часть «getInstance ()», и вы будете в восторге.

получить документацию экземпляра из простой даты из

Комментарии:

1. Но когда я пытаюсь удалить «getInstance ()», я получаю сообщение об ошибке. Я не могу вызвать анализатор без него. что делать?(((

2. @NikZim Вам нужно передать экземпляр DateFormat, который вы создали ранее в коде. Вы вызываете статический метод DateFormat для получения экземпляра по умолчанию, вам нужно вызвать свой экземпляр класса DateFormat, потому что только ваш экземпляр знает стиль (.. МММ ..), Который вы установили.

3.Я сделал DateFormat статическим полем. Передал его в анализатор и все еще не работает.(((( public static SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy"); Метод анализирует room.setDateAvailableFrom(DemoRoom.dateFormat.parse(arr[5])); исключение в потоке «main» java.text.ParseException: Неразрешимая дата: «07-Jun-2019» в java.base / java.text.DateFormat.parse(DateFormat.java:396) в Demo.DemoRoom.main(DemoRoom.java:32)

4. Можете ли вы обновить исходное сообщение со всем вашим кодом для материала dateformat?

5. Вы все еще не показываете ту часть, где вы вызываете DateFormat . Вы вызываете DateFormat.parse вместо DateFormat.parse ….