#include
#include
#include
#include
using namespace std;
class Date
{
private:
int year;
int month;
int day;
int totalDays;
public:
Date(int year, int month, int day);
int getYear() const {
return year; }
int getMonth() const {
return month; }
int getDay() const {
return day; }
int getMaxDay() const;
bool isLeapYear() const{
return(year%4==0&&year%100!=0)||(year%400==0);
}
void show() const;
int distance(const Date& date) const{
return totalDays - date.totalDays;
}
};
namespace{
const int DAYS_BEFORE_MONTH[] = {
0,31,59,90,120,151,181,212,243,273,304,334,365 };
}
Date::Date(int year, int month, int day):year(year), month(month), day(day){
if ((day <= 0)|| (day > getMaxDay())){
cout << "Invalid date:"; show(); cout << endl; exit(1);
}
int years = year - 1;
totalDays = years * 365 + years / 4 - years / 100 + years / 400 + DAYS_BEFORE_MONTH[month - 1] + day;
if (isLeapYear() && month > 2){
totalDays++;
}
}
int Date::getMaxDay() const{
if (isLeapYear() && month == 2){
return 29;
}else{
return DAYS_BEFORE_MONTH[month] - DAYS_BEFORE_MONTH[month - 1];
}
}
void Date::show()const{
cout << getYear() << "-" << getMonth() << "-" << getDay();
}
class SavingsAccount
{
private:
string id;
double balance;
double rate;
Date lastDate;
double accumulation;
static double total;
void record(const Date& date, double amount,const string &desc);
void error(const string& msg) const;
double accumulate(const Date& date) const {
return accumulation + balance * date.distance(lastDate);
}
public:
SavingsAccount(Date & date, string& id1, double rate);
const string& getId() {
return id; }
const double getBalance() {
return balance; }
const double getRate() {
return rate; }
static double getTotal() {
return total; }
void deposit(const Date& date, double amount,const string&desc);
void withdraw(const Date& date, double amount,const string&desc);
void settle(const Date& date);
const void show();
};
double SavingsAccount::total = 0;
SavingsAccount::SavingsAccount(Date &date, string &id1, double rate)
:id(id1), balance(0), rate(rate), lastDate(date), accumulation(0){
date.show(); cout << "\t#"<< id << "is created" << endl;
}
void SavingsAccount::record(const Date& date, double amount,const string& desc){
accumulation = accumulate(date);
lastDate = date;
amount = floor(amount * 100 + 0.5) / 100;
balance += amount;
total += amount;
date.show();
cout << "\t#" << id << "\t" << amount << "\t" << balance<<"\t"<<desc << endl;
}
void SavingsAccount::error(const string& msg)const{
cout << "Error(#" << id << "):" << msg << endl;
}
void SavingsAccount::deposit(const Date& date, double amount, const string&desc){
record(date, amount,desc);
}
void SavingsAccount::withdraw(const Date& date, double amount,const string&desc){
record(date, -amount,desc);
}
void SavingsAccount::settle(const Date& date){
double interest = accumulate(date) * rate / date.distance(Date(date.getYear()-1,1,1));
if (interest != 0){
record(date, interest,"interest");
}
accumulation = 0;
}
const void SavingsAccount::show(){
cout << "#" << id << "\tBalance: " << balance;
}
int main()
{
Date date(2008, 11, 1);
string a = "S3755217";
string b = "02342342";
SavingsAccount accounts[] = {
SavingsAccount(date,a,0.015), SavingsAccount(date,b,0.015)
};
const int n = sizeof(accounts) / sizeof(SavingsAccount);
accounts[0].deposit(Date(2008, 11, 5), 5000, "salary");
accounts[1].deposit(Date(2008, 11, 25), 10000, "sell stock 0323");
accounts[0].deposit(Date(2008, 12, 5), 5500, "salary");
accounts[1].withdraw(Date(2008, 12, 20), 4000, "buy a laptop");
cout << endl; for (int i = 0; i < n; i++){
accounts[i].settle(Date(2009, 1, 1));
accounts[i].show(); cout << endl;
}
cout << "Total: " << SavingsAccount::getTotal() << endl;
return 0;
}