diff options
Added files from project 1 (mirror)
2 files changed, 233 insertions, 0 deletions
| -rw-r--r-- | Year 1/Object-oriented Programming/Project 1/src/Generic/Date/Date.cpp | 174 | ||||
| -rw-r--r-- | Year 1/Object-oriented Programming/Project 1/src/Generic/Date/Date.h | 59 |
diff --git a/Year 1/Object-oriented Programming/Project 1/src/Generic/Date/Date.cpp b/Year 1/Object-oriented Programming/Project 1/src/Generic/Date/Date.cpp new file mode 100644 index 0000000..7c8f4d9 --- /dev/null +++ b/Year 1/Object-oriented Programming/Project 1/src/Generic/Date/Date.cpp @@ -0,0 +1,174 @@ +#include "Date.h" +#include <cstring> + +/* Private */ + +bool Date::isLeapYear() { + // Implements https://en.wikipedia.org/wiki/Leap_year#Gregorian_calendar + return year % 400 == 0 || year % 100 != 0 || year % 4 == 0; +} + +unsigned short Date::daysInMonth() { + if (month == 2) + return 28 + isLeapYear(); + if (month <= 7) + return 30 + month % 2; + return 31 - month % 2; +} + +/* Public */ + +Date::Date() : Date(01, 05, 2022) {} + +/*! \param str C-style string + * + * Values are initialized with zeroes. Then it parses the string: + * + * Skips spaces, saves day with atoi, skips two characters, + * skips spaces, saves month with atoi, skips two characters, + * skips spaces, saves year with atoi. + * + * Values are validated with setters. + * You should always have spaces between day, month and year and no non-numeric characters between them. + * + * \remark If there are non-numeric characters, as per atoi() spec, the appropriate property is zero. + */ +Date::Date(const char* str) : Date(0, 0, 0) { + while (*str == ' ' && *str != '\0') str++; + set_day(atoi(str)); + str += 2; + while (*str == ' ' && *str != '\0') str++; + set_month(atoi(str)); + str += 2; + while (*str == ' ' && *str != '\0') str++; + set_year(atoi(str)); +} + +/*! + * Initializes values with zeroes and then uses setters to save the function arguments. + */ +Date::Date(unsigned short day, unsigned short month, unsigned short year) { + this->day = this->month = this->year = 0; + set_day(day); + set_month(month); + set_year(year); +} + +unsigned short Date::get_day() const { + return day; +} + +/*! \return Whether newDay was saved or not + * + * If newDay is equal to 0, or is more than the appropriate days in the month, the day isn't set. + */ +bool Date::set_day(unsigned short newDay) { + if (newDay == 0 || newDay > daysInMonth()) + return false; + day = newDay; + return true; +} + +unsigned short Date::get_month() const { + return month; +} + +/*! \return Whether newMonth was saved or not + * + * If newMonth is equal to 0 or is more than 12, the month isn't set. + */ +bool Date::set_month(unsigned short newMonth) { + if (newMonth == 0 || newMonth > 12) + return false; + month = newMonth; + return true; +} + +unsigned short Date::get_year() const { + return year; +} + +/*! \return Whether year was saved or not + * + * Year isn't set when newYear is zero + */ +bool Date::set_year(unsigned short newYear) { + if (newYear == 0) + return false; + year = newYear; + return true; +} + +int digitToChar(unsigned digit) { + if (digit <= 9) + return '0' + digit; + return ' '; +} + +/*! \return String object in the format "day.month.year" + * + * \note Currently there isn't any way to change the formatting + */ +String Date::createString() const { + String out; + return ((((out += day) += ".") += month) += ".") += year; +} + +/*! \param istr An input stream + * + * Directly reads bytes from stream (calls read() function). + * + * \remark Doesn't alter the stream in any other way. + * \note Best used with binary ifstream + */ +void Date::read(std::istream& istr) { + istr.read((char*)&day, sizeof(day)); + istr.read((char*)&month, sizeof(month)); + istr.read((char*)&year, sizeof(year)); +} + +/*! \param ostr An output stream + * + * Directly writes bytes to stream (calls write() function). + * + * \remark Doesn't alter the stream in any other way. + * \note Best used with binary ofstream + */ +void Date::write(std::ostream& ostr) { + ostr.write((char*)&day, sizeof(day)); + ostr.write((char*)&month, sizeof(month)); + ostr.write((char*)&year, sizeof(year)); +} + +/*! \returns -1 if this < other, 1 if this > other, 0 if this == other + */ +int Date::compare(const Date& other) const { + if (year < other.year || month < other.month || day < other.day) + return -1; + return year > other.year || month > other.month || day > other.day; +} + + +/* Outside of class */ + +/*! + * Uses the stream's >> operator to read and parse the day, month and year. + * + * \note Best used with std::cin or text std::ifstream + */ +std::istream& operator>>(std::istream& istr, Date& dt) { + unsigned short d, M, y; + istr >> d >> M >> y; + dt = Date(d, M, y); + return istr; +} + +/*! + * Uses the stream's << operator to write the date in the format "day.month.year" + * + * \note Best used with std::cout or text std::ofstream + */ +std::ostream& operator<<(std::ostream& ostr, const Date& dt) { + ostr << dt.get_day() << "." << dt.get_month() << "." << dt.get_year(); + return ostr; +} diff --git a/Year 1/Object-oriented Programming/Project 1/src/Generic/Date/Date.h b/Year 1/Object-oriented Programming/Project 1/src/Generic/Date/Date.h new file mode 100644 index 0000000..89cc89c --- /dev/null +++ b/Year 1/Object-oriented Programming/Project 1/src/Generic/Date/Date.h @@ -0,0 +1,59 @@ +#ifndef HEADER_DATE +#define HEADER_DATE + +/*! \file Date.h + * \brief Stores the declaration of class Date + */ + +#include <istream> +#include <ostream> +#include "../String/String.h" + +/*! \brief Stores a day, month and year + */ +class Date { + unsigned short day; + unsigned short month; + unsigned short year; + + bool isLeapYear(); + unsigned short daysInMonth(); + +public: + //! Sets date as 01 May 2022 + Date(); + //! Parses string + Date(const char* str); + //! Sets day, month and year + Date(unsigned short day, unsigned short month, unsigned short year); + + //! Returns the day + unsigned short get_day() const; + //! Sets the day + bool set_day(unsigned short day); + //! Returns the month + unsigned short get_month() const; + //! Sets the month + bool set_month(unsigned short month); + //! Returns the year + unsigned short get_year() const; + //! Sets the year + bool set_year(unsigned short year); + + //! Returns the date as a String object + String createString() const; + + //! Reads date from stream + void read(std::istream& istr); + //! Writes date to stream + void write(std::ostream& ostr); + //! Compares two dates + int compare(const Date& other) const; +}; + +//! Reads date from stream with >> operator +std::istream& operator>>(std::istream& istr, Date& dt); +//! Writes date to stream with << operator +std::ostream& operator<<(std::ostream& ostr, const Date& dt); + +#endif |
