patterncppMinor
DateTime-like class implementation in modern C++
Viewed 0 times
likeimplementationclassmoderndatetime
Problem
In modern C++, there is no class like
#include
#include
#include
#include
#include
#include
#include
#include
// Month Enum which starts with 1.
enum Month
{
Jan = 1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
};
// Datastructure for string to num conversion in month(.i.e."Mar" Month to 3)
std::array, 12> monthinfo = {
std::make_pair(std::string("Jan"), Month::Jan),
std::make_pair(std::string("Feb"), Month::Feb),
std::make_pair(std::string("Mar"), Month::Mar),
std::make_pair(std::string("Apr"), Month::Apr),
std::make_pair(std::string("May"), Month::May),
std::make_pair(std::string("Jun"), Month::Jun),
std::make_pair(std::string("Jul"), Month::Jul),
std::make_pair(std::string("Aug"), Month::Aug),
std::make_pair(std::string("Sep"), Month::Sep),
std::make_pair(std::string("Oct"), Month::Oct),
std::make_pair(std::string("Nov"), Month::Nov),
std::make_pair(std::string("Dec"), Month::Dec),
};
// concrete daytime structure to store the data
template
struct DayTime
{
T1 day = T1();
T1 month = T1();
T1 year = T1();
T1 hour = T1();
T1 min = T1();
T1 second = T1();
T2 daystr = T2();
T2 dtstring = T2();
};
// main class which would fetech/parse the current time and provide to the client
class CurrentDateTime
{
public:
CurrentDateTime();
~CurrentDateTime() = default;
int GetDay() const { return dt.day; }
int GetMonth() const { return dt.month; }
int GetYear() const { return dt.year; }
int GetHour() const { return dt.hour; }
int GetMin() const { return dt.min; }
int GetSecond() const { return dt.second; }
std::string GetDayStr() const { return dt.daystr; }
private
datetime in the standard which can be used in the program. However, with additional of modules like ` and , we can write the general purpose class like datetime.
Here is my current implementation for this:
``#include
#include
#include
#include
#include
#include
#include
#include
// Month Enum which starts with 1.
enum Month
{
Jan = 1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
};
// Datastructure for string to num conversion in month(.i.e."Mar" Month to 3)
std::array, 12> monthinfo = {
std::make_pair(std::string("Jan"), Month::Jan),
std::make_pair(std::string("Feb"), Month::Feb),
std::make_pair(std::string("Mar"), Month::Mar),
std::make_pair(std::string("Apr"), Month::Apr),
std::make_pair(std::string("May"), Month::May),
std::make_pair(std::string("Jun"), Month::Jun),
std::make_pair(std::string("Jul"), Month::Jul),
std::make_pair(std::string("Aug"), Month::Aug),
std::make_pair(std::string("Sep"), Month::Sep),
std::make_pair(std::string("Oct"), Month::Oct),
std::make_pair(std::string("Nov"), Month::Nov),
std::make_pair(std::string("Dec"), Month::Dec),
};
// concrete daytime structure to store the data
template
struct DayTime
{
T1 day = T1();
T1 month = T1();
T1 year = T1();
T1 hour = T1();
T1 min = T1();
T1 second = T1();
T2 daystr = T2();
T2 dtstring = T2();
};
// main class which would fetech/parse the current time and provide to the client
class CurrentDateTime
{
public:
CurrentDateTime();
~CurrentDateTime() = default;
int GetDay() const { return dt.day; }
int GetMonth() const { return dt.month; }
int GetYear() const { return dt.year; }
int GetHour() const { return dt.hour; }
int GetMin() const { return dt.min; }
int GetSecond() const { return dt.second; }
std::string GetDayStr() const { return dt.daystr; }
private
Solution
Some feedback (not a full list):
Design
Your class is not a datetime class but a "current date time" class (i.e. "how would I represent 18.feb.2028 using your code?")
You should instead create a
or (as - I believe - .NET libraries do):
Your class should:
-
be a regular type, by implementing having an identity (
-
support initialization with other dates and times (than the current one) and validate these values in the init. process.
-
support stream input and output (probably with custom stream formatting adapter) so that you could write code like this:
-
support operations with deltas (for example, "add two days to this date" or "add 10000 seconds to this date").
Implementation
My compiler would say: "warning: not all control paths return a value".
Design
Your class is not a datetime class but a "current date time" class (i.e. "how would I represent 18.feb.2028 using your code?")
You should instead create a
DateTime class (change the name), and add a static or friend function similar to this:DateTime GetCurrent();or (as - I believe - .NET libraries do):
DateTime Now();Your class should:
-
be a regular type, by implementing having an identity (
operator == and operator != should be implemented with expected semantics and a complete sort order (same for operators , =).-
support initialization with other dates and times (than the current one) and validate these values in the init. process.
-
support stream input and output (probably with custom stream formatting adapter) so that you could write code like this:
std::istringstream buffer { "12.feb.2014 12:04" };
DateTime dtm;
buffer >> format("dd.mm.yyyy hh:mm") >> dtm;
// fmt: ^^^^^^^^^^^^^^^^^^^^^^^^^^-
support operations with deltas (for example, "add two days to this date" or "add 10000 seconds to this date").
Implementation
int CurrentDateTime::GetMonth(const std::string& input) {
for (const auto& itr : monthinfo) {
if (itr.first == input) return itr.second;
}
}My compiler would say: "warning: not all control paths return a value".
Code Snippets
DateTime GetCurrent();DateTime Now();std::istringstream buffer { "12.feb.2014 12:04" };
DateTime dtm;
buffer >> format("dd.mm.yyyy hh:mm") >> dtm;
// fmt: ^^^^^^^^^^^^^^^^^^^^^^^^^^int CurrentDateTime::GetMonth(const std::string& input) {
for (const auto& itr : monthinfo) {
if (itr.first == input) return itr.second;
}
}Context
StackExchange Code Review Q#68827, answer score: 6
Revisions (0)
No revisions yet.