package main import "encoding/csv" import "encoding/json" import "time" import "io" import "log" import "os" import "strconv" var COLUMNS []string type FinancialData struct { Date time.Time Open, High, Low, Close, Adj_Close, Volume float64 } func readCsvLine(line []string) *FinancialData { data := new(FinancialData) for i, col := range line { switch COLUMNS[i] { case "Date": d, err := time.Parse("2006-01-02", col) if err != nil { panic(err) } else { data.Date = d } case "Open": data.Open = toFloat(col) case "High": data.High = toFloat(col) case "Low": data.Low = toFloat(col) case "Close": data.Close = toFloat(col) case "Adj Close": data.Adj_Close = toFloat(col) case "Volume": data.Volume = toFloat(col) } } return data } func toFloat(v string) float64 { f, err := strconv.ParseFloat(v, 64) if err != nil { log.Fatalln(err) } return f } func readCsvHeader(line []string) { for _, col := range line { COLUMNS = append(COLUMNS, col) } } func readCsv(in io.Reader) []FinancialData { data := []FinancialData{} csvReader := csv.NewReader(in) for { line, err := csvReader.Read() if err == io.EOF { break } else if err != nil { log.Fatal(err) } if len(COLUMNS) == 0 { readCsvHeader(line) } else { data = append(data, *readCsvLine(line)) } } return data } func main() { if len(os.Args) < 2 { log.Fatalln("Usage go-financial ") } // read input csv, err := os.Open(os.Args[1]) if err != nil { log.Fatalln("Error reading file", err) } defer csv.Close() // parse data data := readCsv(csv) // convert JSON var writer io.Writer if len(os.Args) > 2 { f, ferr := os.Create(os.Args[2]) if ferr != nil { panic(ferr) } defer f.Close() writer = f } else { writer = os.Stdout } err = json.NewEncoder(writer).Encode(data) if err != nil { panic(err) } }