forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   C++ (http://forum.boolean.name/forumdisplay.php?f=22)
-   -   Календарь (http://forum.boolean.name/showthread.php?t=476)

alcosholik 28.12.2005 02:46

Сделал ради тренировки:
Код:

#include <conio.h>
#include <iostream>
#include <string>
using namespace std;

class Date {
        enum { jan=1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec };
        int d, m, y;        //переменные для дня, месяца и года соответственно
        static Date default_date;
        const static int year_limit=3000;
public:
        class Out_of_range {        //класс исключения
        public:
 *Out_of_range() { default_date=Date (1, 1, 1900); }
        };


        Date(int dd=0, int mm=0, int yy=0);
        static void set_default (int, int, int);


        Date& add_day(int n=1);
        Date& add_month(int n=1);
        Date& add_year(int n=1);


        inline int day() const { return d; }
        inline int month() const { return m; }
        inline int year() const { return y; }

        inline void print(const string msg="") const { cout<<endl<<msg<<day()<<'.'<<month()<<'.'<<year(); }


        int limit() const; //возвращает количество дней в текущем месяце


        Date& operator= (const Date&);
        Date& operator+= (const Date&);
};

Date Date::default_date (1, 1, 1900);

bool leapyear(int year)        //проверяет является ли год высокосным
{
        if (year%4==0) return true;
        return false;
}

Date& Date::operator= (const Date& date)
{
        d=date.day();
        m=date.month();
        y=date.year();
        return *this;
}

Date& Date::operator+= (const Date& date)
{
        add_year(date.year());
        add_month(date.month());
        add_day(date.day());
        return *this;
}

bool operator== (const Date& date1, const Date& date2)
{
        if (date1.day()==date2.day() && date1.month()==date2.month() && date1.year()==date2.year()) return true;
        return false;
}

bool operator> (const Date& date1, const Date& date2)
{
        if (date1.year()>date2.year()) return true;
        else if (date1.year()==date2.year())
        {
 *if (date1.month()>date2.month()) return true;
 *else if (date1.month()==date2.month())
 *{
 *        if (date1.day()>date2.day()) return true;
 *}
        }
        return false;
}

Date operator+ (const Date& arg1, const Date& arg2)
{
        Date result (arg1.day(), arg1.month(), arg1.year());
        result+=arg2;
        return result;
}

Date operator+ (const Date& date, const int arg)
{
        Date result (date.day(), date.month(), date.year());
        result.add_day(arg);
        return result;
}

int operator- (const Date& date1, const Date& date2)        //считает количество дней между date1 и date2
{ * * * * * * *//date1 всегда больше date2
        if (date2>date1 || date1==date2) return 0;

        Date date=date2;

        int days=0;
        int days_add;

        if (date1.year()!=date2.year()) {
 *while (date.year()<date1.year()) {
 * * * * * *days_add=365;
 *        if (leapyear(date.year())) days_add=366;
 *        days+=days_add;
 *        date.add_year();
 *}
        }

        Date temp_date (1, 1, 1);
        int month1_days=0;

        while (temp_date.month()<date1.month()) {
 *month1_days+=temp_date.limit();
 *temp_date.add_month();
        }
        month1_days+=date1.day();

        temp_date=Date (1, 1, 1);
        int month2_days=0;
        while (temp_date.month()<date2.month()) {
 *month2_days+=temp_date.limit();
 *temp_date.add_month(1);
        }
        month2_days+=date2.day();

        days+=month1_days-month2_days;

        return days;
}

void Date::set_default (int d, int m, int y)
{
        default_date=Date (d, m, y);
}

Date::Date (int dd, int mm, int yy)
{
        d=dd ? dd : default_date.d;
        m=mm ? mm : default_date.m;
        y=yy ? yy : default_date.y;
        try {
 * * * *if (d<1 || d>limit() || m<1 || m>12 || y>year_limit) throw Out_of_range();
        }
        catch (Out_of_range) {
 *cout<<"ERROR. Bad date format.\n";
        }
}

int Date::limit() const
{
        switch (m)
        {
        case jan:
        case mar:
        case may:
        case jul:
        case aug:
        case oct:
        case dec:
 *return 31;
        case apr:
        case jun:
        case sep:
        case nov:
 *return 30;
        case feb:
 *if (leapyear(y)) return 29;
 *return 28;
        }
        return 0;
}

Date& Date::add_year(int n)
{
        y+=n;
        try {
 * * * *if (y>year_limit) throw Out_of_range();
        }
        catch (Out_of_range) {
 *y=default_date.y;
 *cout<<"ERROR. Date out of range.\n";
        }
        return *this;
}

Date& Date::add_month(int n)
{
        m+=n;
        while (m>12) {
 *m=m-12;
 *add_year();
        }
        add_day(0);
        return *this;
}

Date& Date::add_day(int n)
{
        int lim;

        d+=n;
        while (d>(lim=limit())) {
 *d=d-lim;
 *add_month();
        }
        return *this;
}

int main()
{
        Date date1(1, 1, 1972);

        date1.add_year(10);
        date1.print("date1: ");

        Date date2(1, 1, 1973);
        date2.print("date2: ");
       
        cout<<"\n\ndate1==date2: "<<(date1==date2)<<endl;

        int days=date2-date1;
       
        cout<<"\nNumber of days between (date2-date1): "<<days;
        days=date1-date2;
        cout<<"\nNumber of days between (date1-date2): "<<days<<endl;

        date2.add_month(240);
        date2.print("date2: ");
        days=date2-date1;
        cout<<"\nNumber of days between (date2-date1): "<<days;
       
        getch();
}

Возможности:
- создавать новые объекты класса;
- прибавлять n-е количество дней, месяцев, лет;
- расчитывать количество дней между двумя датами;
- все проверки на количество дней в месяце и высокосный год выполняются автоматически;


Думаю скоро добавить вычисление дня недели по дате.



Правка: внес некоторые коррективы в код по совету impersonalis'a.

jimon 28.12.2005 13:58

код не очень разборчивый
а так неплохо ! :)


Часовой пояс GMT +4, время: 10:41.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot