Sorting Date mm/dd/yyyy to yyyymmdd

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);	
	
}


1
2
3
//s ~ "MM/DD/YYYY"
s=s.substr(6,4)+s.substr(0,2)+s.substr(3,2);
//s ~ "YYYYMMDD" 
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?
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
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.