This is a Date class I made for a hobby project. It does not deal with time at all; that is, the smallest unit of time it considers is one day, and no concern with time zones.Where I do most of my coding, I'm not allowed C++11, so if there are any new languages features that would apply here, I am definitely interested in hearing about it. I'd also like to hear about the overall design of the class, or any edge cases I may have missed.Date.h#pragma once#include <memory>#include <string>#include <vector>#include <time.h>/** * Represents a date. Does not account for time. Does not account for time zones */class Date{public:    /**     * @brief Construct current, local Date     */    Date();    /**     * @brief Construct local Date from timestamp     * @param timestamp seconds since January 1 1970 UTC     */    Date(time_t timestamp);    /**     * Return the year     */    size_t getYear() const;    /**     * @brief Return a number representing the month.     *     * @return represented month     */    size_t getMonth() const;    /**     * @brief get name of month, in English     */    std::string getMonthString() const;    /**     * @brief get day of month     */    size_t getDate() const;    /**     * @brief Increment current date by given number of years.     */    void addYears(int numberOfYears);    /**     * @brief Increment current date by given number of months.     */    void addMonths(int numberOfMonths);    /**     * @brief Increment current date by given number of days.     */    void addDays(int numberOfDays);    /**     * @brief return String representation of date     * example: 1 February 1983     */    std::string toString() const;    bool operator==(const Date& rhs) const;    bool operator!=(const Date& rhs) const;private:    bool isLeapYear(size_t year) const;    bool isLeapYear() const;    void init(time_t timestamp);    const static std::vector<std::string> monthNames;    size_t daysPerMonth() const;    int date;    int month;    int year;};std::ostream& operator<<(std::ostream& stream, const Date& rhs);Date.cpp#include stdafx.h#include Date.h#include <cassert>#include <vector>Date::Date(){    init(time(NULL));}Date::Date(time_t timestamp){    init(timestamp);}void Date::init(time_t timestamp){    struct tm datetime;    localtime_s(&datetime, &timestamp);    year = datetime.tm_year + 1900;    month = datetime.tm_mon;    date = datetime.tm_mday;}size_t Date::getYear() const{    return year;}size_t Date::getMonth() const{    //1-index for human use    return month + 1;}size_t Date::getDate() const{    return date;}std::string Date::toString() const{    return std::to_string(getDate()) +   + getMonthString() +   + std::to_string(getYear());}const std::vector<std::string> Date::monthNames = {    January,    February,    March,    April,    May,    June,    July,    August,    September,    October,    November,    December};std::string Date::getMonthString() const{    return monthNames[getMonth()];}bool Date::operator==(const Date& rhs) const{    return getYear() == rhs.getYear() &&        getMonth() == rhs.getMonth() &&        getDate() == rhs.getDate();}bool Date::operator!=(const Date& rhs) const{    return !(*this == rhs);}std::ostream& operator<<(std::ostream& stream, const Date& rhs){    return stream << rhs.toString();}void Date::addYears(int numberOfYears){    if (isLeapYear() &&        !isLeapYear(getYear() + numberOfYears) &&         date == 29)    {        addDays(1);    }    year += numberOfYears;}void Date::addDays(int numberOfDays){    numberOfDays += (date - 1);    date = 1;    while (numberOfDays < 0)    {        addMonths(-1);        numberOfDays += daysPerMonth();    }    while (numberOfDays >= daysPerMonth())    {        numberOfDays -= daysPerMonth();        addMonths(1);    }    date += numberOfDays;}void Date::addMonths(int numberOfMonths){    month += numberOfMonths;    while (month < 0)    {        addYears(-1);        month += 12;    }    while (month > 11)    {        addYears(1);        month -= 12;    }    if (date > daysPerMonth())    {        // No need to be precise. Just loop to the 1st.        month += 1;        date = 1;    }}size_t Date::daysPerMonth() const{    assert(month >= 0);    assert(month <= 11);    switch (month)    {    case 0:    case 2:    case 4:    case 6:    case 7:    case 9:    case 11:        return 31;    case 3:    case 5:    case 8:        return 30;    default: //February        if (isLeapYear())        {            return 29;        }        return 28;    }}bool Date::isLeapYear(size_t year) const{    return year % 4 == 0;}bool Date::isLeapYear() const{    return isLeapYear(getYear());}
Date class for Budgeting App
c++;datetime;library
DesignMember (private) vs. Non MemberAllways try to keep your Class small. Functions like isLeapYear(size_t year) or getDaysPerMonth() do not really operate on the State of your class. Thus you should consider to make them non-member functions. I would than suggest to only declare and define them in the *.cpp (within a anonymous namespace perhaps) that would lessen the compile dependencies.Same for the variable monthNames.Function namesWhen I read the function name getDate() in a Class Date I would think that it returns something like a copy or different representation of the whole Class. Consider to rename the Function.Coding styleNamed loopsLoops like while (month > 11){    addYears(1);    month -= 12;}take a little time and effort to understand. Consider to move them in seperate named functions like getNumberOfYearsFromAmountOfDays(...). In this way it is much easier to understand the code on first sight.I would make these functions non-member.BugIsLeapYearFrom the comments:The leap year calculation is more complicated than that. Years that are multiples of 100 aren't leap years except multiples of 400 are.  RichNC++11One thing I see you could change with C++11 is the init Function. Because it is now allowed to call one Constructor in the initializer list from another.ExampleDate::Date() :   Date(time(NULL)){   /* empty */}Thats all. Its not much but perhaps it helps a little.