даты для синтаксического анализа строки

Учитывая текстовый файл здесь:

       Date    Opening    Closing
 6-Mar-2012   500         1000
 9-Jun-2011   110         970
 7-Dec-2015   1090        980.69
28-Feb-2010   500         800

Мне нужно построить даты в GregorianCalendar и иметь конструкторы даты в String. В моем выводе дата отображается как NULL, есть идеи по исправлению?

Вывод:

The date is null, the opening is 500, and the closing is 800   

Дата объявлена ​​GregorianCalendar, однако конструкторы принимают дату в строке и должны ожидать форму «дд-ММ-гггг».

Класс Джиа:

public class Djia implements Comparable<Djia> {
    // instance variables
    private GregorianCalendar date; 
    private double opening;
    private double closing; 

    public Djia(String dt, double opening, double closing) throws ParseException {
        DateFormat stringDate = new SimpleDateFormat("dd-MM-yyyy");
        Date date = stringDate.parse(dt);
        Calendar gCal = new GregorianCalendar();
        gCal.setTime(date);
        this.opening = opening;
        this.closing = closing;
    }

    public String date() {
        String date;
        SimpleDateFormat dateformat = new SimpleDateFormat("dd-MM-yyyy");
        date = dateformat.format(this.date.getTime());
        return date;
    }

    public double opening() {
        return opening;
    }

    public double closing() {
        return closing;
    }

    //...
}

Основной метод:
Я выполнил здесь синтаксический анализ и форматирование, потому что месяцы являются строковыми представлениями в данном текстовом файле. Сначала я проанализировал месяцы до целочисленного представления, а затем отформатировал их с даты на строку, потому что класс Djia принимает только дату как строку.

Scanner input = new Scanner(new File("file.txt"));
while (input.hasNextLine()) {
    String line = input.nextLine();
    String[] fields = line.split(" ");
    String date = fields[0];
    SimpleDateFormat simpleDate = new SimpleDateFormat("d-MMM-yyyy");
    Date nDate = simpleDate.parse(date);
    Format stringDate = new SimpleDateFormat("dd-MM-yyyy");
    String newDate = stringDate.format(nDate); 
    double closing = Double.parseDouble(fields[2]);
    double opening = Double.parseDouble(fields[1]);
    Djia newDjia = new Djia(newDate, opening, closing);
    //...
}

person Katherine    schedule 22.05.2015    source источник
comment
Вы уверены в формате даты? В API я вижу много ГГГГ-ММ-ДД, но не ДД-ММ-ГГГГ   -  person Zooly    schedule 22.05.2015
comment
Было бы здорово, если бы вы предоставили короткую, но полную программу, а не отрывки. (Не помогает то, что у вас есть 4 разных формата в вашем коде, без указания причин.) Однако: а) вы не хотите использовать YYYY при форматировании; б) вы должны использовать d-MMM-yyyy при синтаксическом разборе, учитывая, что у вас не всегда есть две цифры. c) dd-mm-yyyy должно быть dd-MM-yyyy, поскольку mm означает минуты, а не месяцы. См. codeblog.jonskeet.uk/ 2015/05/05 / для получения дополнительных советов.   -  person Jon Skeet    schedule 22.05.2015
comment
Используйте Java 8 или JodaTime и избавьтесь от ненужных поездок в учреждение.   -  person Tim Biegeleisen    schedule 22.05.2015
comment
@JonSkeet Спасибо, Джон, наш профессор сказал делать это таким образом (4 разных формата), у нас нет выбора .. и она не очень хороша в преподавании, если честно ..   -  person Katherine    schedule 22.05.2015
comment
Ну, вы точно не объяснили, чего пытаетесь достичь. Почему следует использовать 4 формата даты? Как ваша последняя строка построена из Djia? Хотя ваш профессор может плохо преподавать, это не мешает вам четко объяснить свою проблему. Прочтите tinyurl.com/stack-hints   -  person Jon Skeet    schedule 22.05.2015
comment
@JonSkeet извините, отредактировал форматы даты. Дата объявлена ​​GregorianCalendar в классе Djia, конструкторы и конечный результат должны ожидать строковую форму dd-MM-yyyy.   -  person Katherine    schedule 22.05.2015
comment
Это все еще не короткая, но полная программа, демонстрирующая проблему. Мы до сих пор не знаем, из чего строится ваша окончательная строка, какие шаги по отладке вы предприняли, или почему вы выполняете синтаксический анализ и форматирование несколько раз (кроме нечеткого описания в комментарии).   -  person Jon Skeet    schedule 22.05.2015
comment
@JonSkeet Не могли бы вы еще раз взглянуть, я отредактировал свой вопрос.   -  person Katherine    schedule 22.05.2015
comment
По-прежнему нет короткой, но полной программы, по-прежнему нет объяснения почему Djia принимает String, а не Date или Caledar, по-прежнему нет указаний на то, как создается последняя строка. Вы прочитали tinyurl.com/stack-hints, как я предлагал?   -  person Jon Skeet    schedule 22.05.2015
comment
@JonSkeet Да, есть :) Профессор заставил Джиа только принимать String. Программа длинная, я не хотел все здесь выкладывать. Я написал метод вставки, чтобы добавить строки текста в LinkedList и распечатать результат.   -  person Katherine    schedule 22.05.2015
comment
@Katherine: Где это сказано в вопросе? Людям, читающим ваш вопрос, не следует не читать длинную цепочку комментариев, чтобы понять его. Если вы прочитали мои предложения, мне непонятно, почему ваш вопрос все еще не включает короткую, но полную программу или все детали, о которых я спрашивал. Обратите внимание, что это не обязательно должна быть ваша полная программа - это просто должна быть короткая, но полная программа, демонстрирующая проблему.   -  person Jon Skeet    schedule 22.05.2015
comment
Что ж, ваша дата private GregorianCalendar date; все еще null, потому что вы не инициализируете ее где-то. Вы создаете несколько локальных переменных с именем date, но это не имеет ничего общего с вашим полем экземпляра date.   -  person Tom    schedule 22.05.2015
comment
@Katherine Я ответил вам 10 минут назад с решением   -  person Xithias    schedule 22.05.2015
comment
@Xithias, спасибо большое! Можно ли использовать реализацию LinkedList вместо ArrayList?   -  person Katherine    schedule 22.05.2015
comment
@Katherine да, в результатах нет никаких изменений   -  person Xithias    schedule 22.05.2015


Ответы (2)


Возможно, у вас есть пробелы в начале строки:

попробуйте изменить строку:

String[] fields=line.split(" ");

to

String[] fields=line.trim().split(" ");

добавив вызов trim (), который удалит все пробелы в начале и в конце вашей строки.

or do:

 String dateString = line.substring(0, 12);

если всегда одинаковая длина и выравнивание части строки даты.

person Krzysztof Cichocki    schedule 22.05.2015
comment
По-прежнему выводит Null :) - person Katherine; 22.05.2015

Вы должны сделать это в основном:

  • Установите свой языковой стандарт в SimpleDateFormat
  • Составьте список (не массив) с разделением и удалите пустые элементы

Вот результат:

import java.io.File;
import java.io.FileNotFoundException;
import java.text.DateFormat;
import java.text.Format;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Scanner;

public class Djia {

    private GregorianCalendar date;
    private double opening;
    private double closing;

    public Djia(String dt, double opening, double closing)
            throws ParseException {

        DateFormat stringDate = new SimpleDateFormat("dd-mm-yyyy");
        Date date = stringDate.parse(dt);
        GregorianCalendar gCal = new GregorianCalendar();
        gCal.setTime(date);

        this.opening = opening;
        this.closing = closing;
        this.date = gCal;
    }

    public String date() {
        String date;
        SimpleDateFormat dateformat = new SimpleDateFormat("MM/dd/YYYY");
        date = dateformat.format(this.date.getTime());
        return date;

    }

    public static void main(String[] args) {
        try {
            Scanner input = new Scanner(new File("file.txt"));
            while (input.hasNextLine()) {
                String line = input.nextLine();
                LinkedList fields=new LinkedList<String>(Arrays.asList(line.trim().split(" ")));
                for (int i=fields.size()-1; i>=0; i--) {
                    if (fields.get(i).equals("")) {
                        fields.remove(i);
                    }
                }
                String date = (String) fields.get(0);
                SimpleDateFormat simpleDate = new SimpleDateFormat("d-MMM-yyyy", Locale.US);
                Date nDate = simpleDate.parse(date);
                Format stringDate = new SimpleDateFormat("dd-MM-yyyy", Locale.US);
                String newDate = stringDate.format(nDate);
                double closing = Double.parseDouble((String) fields.get(2));
                double opening = Double.parseDouble((String) fields.get(1));
                Djia newDjia = new Djia(newDate, opening, closing);
                System.out.println("The date is " + newDate + ", the opening is " + opening + ", and the closing is " + closing);

            }
        } catch (NumberFormatException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}
person Xithias    schedule 22.05.2015
comment
Вам не понадобится необработанный тип ArrayList, если бы вы использовали правильный разделитель для разделения. - person Tom; 22.05.2015
comment
А где исправляет проблему в классе Djia? - person Tom; 22.05.2015
comment
@Tom, я ничего не менял в классе Djia, который опубликовала Кэтрин. Код работает, попробовал. - person Xithias; 22.05.2015
comment
@Tom Да, я снова проверил, это не решает проблему - person Katherine; 22.05.2015
comment
@Tom Как инициализировать дату GregorianCalendar, когда Public Djia принимает только дату String? - person Katherine; 22.05.2015
comment
@Katherine Ну, вы используете this.opening = opening; для инициализации поля opening. Значит, вам нужно что-то подобное для поля date. И вам нужен экземпляр GregorianCalender, который у вас уже есть в вашем конструкторе. Вам нужно использовать это только для инициализации вашего this.date;). - person Tom; 22.05.2015
comment
@Xithias Код у вас работает? Вы игнорируете результаты конструктора Dija и значения полей экземпляра. Неудивительно, что вы не заметили неинициализированное поле date. - person Tom; 22.05.2015
comment
@Tom теперь я понимаю. Я был сосредоточен только на том, чтобы показать результат в основном. Редактировал ответ инициализацией календаря. :) - person Xithias; 22.05.2015
comment
@Katherine Я уже редактировал свой ответ, у вас там все есть :) - person Xithias; 22.05.2015
comment
@Xithias вывод: Дата - java.util.GregorianCalendar [time = 1142506800000, areFieldsSet = true, areAllFieldsSet = true, lenient = true, zone = s .......... :) - person Katherine; 22.05.2015
comment
@Katherine Это вывод по умолчанию, если вы напечатаете GregorianCalendar на консоли (вызвав на нем toString). Если вам нужна текущая дата и время вашего экземпляра, попробуйте gCal.getTime() (или this.date.getTime()). Это возвращает java.util.Date, который имеет отформатированную реализацию toString. - person Tom; 22.05.2015
comment
@ Том, извини, это все меня очень сбивает с толку, думаю, я начну еще один вопрос :) Большое спасибо, Том - person Katherine; 22.05.2015