Проблема при синтаксическом анализе строки в тип GregoriamCalendar для использования в ArrayList

поэтому у меня возникли некоторые проблемы - я пытаюсь создать класс для загрузки исторических данных фондового рынка из Yahoo. По сути, в строке 64 мне нужно разобрать строку вида гггг-мм-дд в тип GregorianCalendar. Я уже некоторое время пытаюсь и смотрю на другие решения здесь и в других местах - хотя я могу проанализировать строку в григорианском календаре, я не могу заставить ее добавлять даты в ArrayList в той же форме yyyy-MM-dd. Я использую .split(,) для разделения каждой строки csv на отдельные элементы, а все остальные типы — это Doubles и Ints, что достаточно просто.

строка возвращает строку, такую ​​как: 2015-11-12,116.260002,116,82,115.650002,115.720001,32262600,115.720001

Заранее спасибо!

    public StockDownloader(String symbol, GregorianCalendar start, GregorianCalendar end) { 
        dates = new ArrayList<GregorianCalendar>(); 
        opens = new ArrayList<Double>(); 
        highs = new ArrayList<Double>(); 
        lows = new ArrayList<Double>();
        closes = new ArrayList<Double>();
        volumes = new ArrayList<Integer>();
        adjCloses = new ArrayList<Double>(); 

        //deconstructed URL
        String url = "http://real-chart.finance.yahoo.com/table.csv?s="+symbol+
                "&a="+start.get(Calendar.MONTH)+
                "&b="+start.get(Calendar.DAY_OF_MONTH)+
                "&c="+start.get(Calendar.YEAR)+
                "&d="+end.get(Calendar.MONTH)+
                "&e="+end.get(Calendar.DAY_OF_MONTH)+
                "&f="+end.get(Calendar.YEAR)+
                "&g=d&ignore=.csv";

        try { 
            URL yhoofin = new URL(url); //creates URL from String url
            URLConnection data = yhoofin.openConnection(); //invokes openConnection method on URL
            Scanner input = new Scanner(data.getInputStream()); //Returns an input stream that reads from this open connection.
            if(input.hasNext()) //skip line, it's just the header
                input.nextLine(); //advances to next line

            //start reading data
            while(input.hasNextLine()) {
                String line = input.nextLine();

                String[] splitLine = line.split(","); 

>>Problem here  //dates.add( add the date );
                opens.add(Double.parseDouble(splitLine[OPEN]));
                highs.add(Double.parseDouble(splitLine[HIGH]));
                lows.add(Double.parseDouble(splitLine[LOW]));
                closes.add(Double.parseDouble(splitLine[CLOSE]));
                volumes.add(Integer.parseInt(splitLine[VOLUME]));
                adjCloses.add(Double.parseDouble(splitLine[ADJCLOSE]));


            }
        }
        catch(Exception e) { //catch any error (exception) that happens
            System.err.println(e);
        }
    }

person Tom Keyte    schedule 13.11.2015    source источник
comment
Почему вы используете экземпляры GregorianCalendar для хранения дат?   -  person Nyavro    schedule 13.11.2015
comment
Я очень новичок в Java, поэтому я не уверен - если вы можете предложить лучший метод, пожалуйста :)   -  person Tom Keyte    schedule 13.11.2015


Ответы (2)


Вы должны хранить даты в списке не как GregorianCalendar, а как даты:

List<Date> dates = new ArrayList<>()

Затем вы можете анализировать даты с помощью SimpleDateFormat:

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
...
dates.add(format.parse(splitLine[0]));

SimpleDateFormat может помочь вам отформатировать дату в обратном порядке, например:

SimpleDateFormat newFormat = new SimpleDateFormat("dd-MM-yyyy HH"); //another format
String formattedDate = newFormat.format(date); //14-11-2015 11

http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html http://docs.oracle.com/javase/7/docs/api/java/util/Date.html

person Nyavro    schedule 13.11.2015
comment
При построении URL-адреса, как мне затем каждый элемент (то, что сейчас Calendar.Month и т.д....) - person Tom Keyte; 13.11.2015
comment
Извините, я не понял вашего вопроса. Как вам тогда каждый элемент какой? Я отредактировал свой ответ, может быть, это поможет - person Nyavro; 14.11.2015

Используйте univocity-parsers, чтобы обработать это для вас. Это будет быстрее, так как входной поток обрабатывается в отдельном потоке, и ваш код будет проще поддерживать:

public StockDownload(String symbol, GregorianCalendar start, GregorianCalendar end) {
    //deconstructed URL
    String url = "http://real-chart.finance.yahoo.com/table.csv?s=" + symbol +
            "&a=" + start.get(Calendar.MONTH) +
            "&b=" + start.get(Calendar.DAY_OF_MONTH) +
            "&c=" + start.get(Calendar.YEAR) +
            "&d=" + end.get(Calendar.MONTH) +
            "&e=" + end.get(Calendar.DAY_OF_MONTH) +
            "&f=" + end.get(Calendar.YEAR) +
            "&g=d&ignore=.csv";

    //Csv parser configuration - many options here, check the tutorial
    CsvParserSettings settings = new CsvParserSettings();
    //there's headers in the input, let's use them
    settings.setHeaderExtractionEnabled(true);

    //You want the data split into columns, so let's use a column processor for that
    ObjectColumnProcessor columnProcessor = new ObjectColumnProcessor();
    //here we assign a conversion to the fields you are interested in getting.
    columnProcessor.convertFields(Conversions.toCalendar("yyyy-mm-dd")).add("Date");
    columnProcessor.convertFields(Conversions.toDouble()).add("Open","High","Low","Close","Adj Close");
    columnProcessor.convertFields(Conversions.toInteger()).add("Volume");

    //Let's tell the parser to submit all parsed rows to the column processor.
    settings.setRowProcessor(columnProcessor);
    //Creates a CSV parser with our configuration
    CsvParser parser = new CsvParser(settings);

    try {
        URL yhoofin = new URL(url); //creates URL from String url
        URLConnection data = yhoofin.openConnection(); //invokes openConnection method on URL

        //opens the connection and parses everything. All rows are sent to the the column processor.
        parser.parseAll(new InputStreamReader(data.getInputStream()));
    } catch (Exception e) { //catch any error (exception) that happens
        System.err.println(e);
    }

    //Parsing is done. Let's just get the values.
    Map<String, List<Object>> columns = columnProcessor.getColumnValuesAsMapOfNames();

    //Each header in the input is a key in the map. Here we get the list of values for the "close" column.
    System.out.println(columns.get("Close"));
}

Раскрытие информации: я являюсь автором этой библиотеки. Это бесплатно и с открытым исходным кодом (лицензия Apache V2.0).

person Jeronimo Backes    schedule 16.11.2015