Sorting Date mm/dd/yyyy to yyyymmdd
Oct 1, 2012 at 2:52am UTC
I am trying to read in some stock data from Yahoo and the date comes in this format mm/dd/yyyy. I want to sort the data and create a field that is yyyymmdd. If you look at my while statement, where I read in the file. I can't figure out how to change this so that it reads the date in without the "/" and changes the order of the input (so I can store the individual fields yyyy mm dd in the struct vector)
Thanks
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;
struct quote
{
string date;
double open;
double high;
double low;
double close;
double vol;
double adjClose;
};
void printData(const vector<quote> q);
void highestPrice(const vector<quote> q);
void lowestPrice(const vector<quote> q);
void sortData(vector<quote> &q);
bool dateCompare(const quote &q1, const quote &q2)
{
return q1.date < q2.date;
}
int main(int argc, char *argv[])
{
ifstream in(argv[1]);
if (!in)
{
cout << "Unable to open " << argv[1] << endl;
}
else
cout << "File opened " << endl;
string str; // eat headers
getline(in, str);
cout << str << endl;
vector<quote> Quotes;
quote entry; // temp
int recCnt = 0;
while (in >> entry.date >> entry.open >> entry.high
>> entry.low >> entry.close >> entry.vol
>> entry.adjClose)
{
Quotes.push_back(entry);
recCnt++;
}
in.close();
printData(Quotes);
cout << endl << "Summary Data " << endl;
highestPrice(Quotes);
lowestPrice(Quotes);
cout << "The Number of Records Processed : " << recCnt << endl;
cout << "Sorted Data " << endl;
sortData(Quotes);
printData(Quotes);
}
void printData(vector<quote> q)
{
for (vector<quote>::const_iterator it = q.begin();
it != q.end(); it++)
{
cout << it->date << " " << it->open << " "
<< it ->high << " " << it -> low << " "
<< it-> close << " " << it-> vol << " "
<< it-> adjClose << endl;
}
}
void highestPrice(vector<quote> q)
{
vector<quote>::const_iterator it = q.begin();
double highest = it->high;
string highDate = it->date;
for (vector<quote>:: const_iterator it = q.begin();
it!= q.end(); it++)
{
if (it->high > highest)
{
highest = it->high;
highDate = it->date;
}
}
cout << "The highest price is " << highest << " and it occurred on "
<< highDate << endl;
}
void lowestPrice(vector<quote> q)
{
double lowest;
string lowDate;
vector<quote>::const_iterator it = q.begin();
lowest = it->low;
lowDate = it->date;
for (it=q.begin(); it!= q.end(); it++)
{
if (it->low < lowest)
{
lowest = it->low;
lowDate = it->date;
}
}
cout << "The lowest price is " << lowest << " and it occurred on "
<< lowDate << endl;
}
void sortData(vector<quote> &q)
{
sort ( q.begin(), q.end(), dateCompare);
}
Oct 1, 2012 at 6:00am UTC
1 2 3
//s ~ "MM/DD/YYYY"
s=s.substr(6,4)+s.substr(0,2)+s.substr(3,2);
//s ~ "YYYYMMDD"
Oct 1, 2012 at 12:46pm UTC
This works for all instances when the month field is 2 digits long. But for months 1-9 it doesn't work.
How can I tell if there are 2 numbers in the month field or one?
Oct 1, 2012 at 2:40pm UTC
Parsing it using a
std::istringstream
is simple.
(though it is not the most efficient way of doing this)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
#include <string>
#include <sstream>
#include <iomanip>
std::string to_yyyymmdd( const std::string& mdyy )
{
std::istringstream stm(mdyy) ;
int month, day, year ;
char sep1, sep2 ;
if ( ( stm >> month >> sep1 >> day >> sep2 >> year ) && (sep1=='/' ) && (sep2=='/' )
&& stm.eof() && (year>0) && (month>0) && (month<13) && (day>0) && (day<32) )
{
if ( year < 1000 ) year += 2000 ;
std::ostringstream ostm ;
auto width = std::setw(2) ;
auto fill = std::setfill('0' ) ;
ostm << year << width << fill << month << width << fill << day ;
return ostm.str() ;
}
else { /* format error */ return "invalid date: " + mdyy ; }
}
Last edited on Oct 1, 2012 at 2:41pm UTC
Oct 1, 2012 at 3:02pm UTC
To avoid confusion in the future, MM in a format string is typically understood as meaning "the month padded with zeroes to two digits". Likewise for DD and YYYY.
Topic archived. No new replies allowed.