2015-11-13 44 views
1

所以我在这里有一些麻烦 - 我试图创建一个类从雅虎下载历史股市数据。基本上,在64行我需要解析一个格式为yyyy-MM-dd的字符串为GregorianCalendar类型。我一直在尝试一段时间,看看这里和其他地方的其他解决方案 - 虽然我可以将字符串解析为公历,但我无法用相同的格式yyyy-MM-dd将它添加到ArrayList日期。我正在使用.split(,)将csv的每一行分割为单独的元素,而其他所有类型都是Doubles和Ints,这很容易。麻烦分析字符串GregoriamCalendar类型使用ArrayList

线返回一个字符串,如:事先 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); 
     } 
    } 
+0

为什么使用GregorianCalendar实例来保存日期? – Nyavro

+0

我对Java很陌生,所以我不确定 - 如果你能建议一个更好的方法,请做:) –

回答

2

,可以储存在名单的日期不是的GregorianCalendar但日期:

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

的SimpleDateFormat可以帮助你日期格式:

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

然后你就可以用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

+0

当构建URL时,我该如何处理每个元素(现在是什么Calendar.Month等等。 ..) –

+0

对不起,我没有得到你的问题。那么你怎么样每个元素是什么?我编辑了我的答案,也许这会有所帮助 – Nyavro

0

使用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许可证)。