##Standard approach:
Standard approach:
###output std::time_point
:
output std::time_point
:
####Necessary links:
Necessary links:
##Some thoughts:
Some thoughts:
Conclusion:
##Conclusion: InIn this kind of problem, it is very dangerous try to implement by hand, since there are lots of edge cases. As a result, the problem given was rather a test of knowledge of standard library.
##Standard approach:
###output std::time_point
:
####Necessary links:
##Some thoughts:
##Conclusion: In this kind of problem, it is very dangerous try to implement by hand, since there are lots of edge cases. As a result, the problem given was rather a test of knowledge of standard library.
Standard approach:
output std::time_point
:
Necessary links:
Some thoughts:
Conclusion:
In this kind of problem, it is very dangerous try to implement by hand, since there are lots of edge cases. As a result, the problem given was rather a test of knowledge of standard library.
Standard approach: ##Standard approach:
Well, not really standard, but in my opinion one should use std::chrono
in this case. Some stuff is done in round abouta roundabout way, but I don't think it is a huge problem. Howard Hinnant havehas written a library for it, but for a sake ofin case the license correctnessisn't acceptable, I'll reimplement some functionality by hand.
output std::time_point: ###output std::time_point
:
The first issue is outputting a std::time_point
. The problem with it is that it doesn't have operator<<
overload for streams. The only way possible to deal with this is to implement our own:
Necessary####Necessary links:
std::chrono::system_clock::to_time_t()
std::chrono::system_clock::to_time_t()
(system clock is just example).
The only ways to print time isare either std::ctime()
orand std::put_time()
(lets omit implementingnot counting the "implement by handhand" approach). So let's follow the thread and find it'sits end and test it:
Since we can manipulate std::chrono::time_point
, and std::chrono::duration
, let's use everything it gotwe have:
Converts local calendar time to a time since epoch as a time_t
time_t
object. time->tm_wdaytime->tm_wday
and time->tm_ydaytime->tm_yday
are ignored. The values in timetime
are permitted to be outside their normal ranges.
Now the easy stuff, add the given number of days:
Some thoughts: ##Some thoughts:
using namespace std;
rarely buys anything, but opens a chance for errors.using namespace std;
rarely buys anything, but opens a chance for errors.standard library has a solution most of the time
standard library has a solution most of the timemodularity is important. Breaking functions into logical pieces makes it very easy to quickly prototype, adjust, mix'n'match.
modularity is important. Breaking functions into logical pieces makes it very easy to quickly prototype, adjust, mix'n'match.
Conclusion:
In##Conclusion: In this kind of problemsproblem, it is very dangerous trying implementingtry to implement by hand, since there are lots of edge cases. As a result, the problem given was rather a test of knowledge of standard library.
Standard approach:
Well, not really standard, but in my opinion one should use std::chrono
in this case. Some stuff is done in round about way, but I don't think it is a huge problem. Howard Hinnant have written a library for it, but for a sake of license correctness I'll reimplement some functionality by hand.
output std::time_point:
The first issue is outputting a std::time_point
. The problem with it is that it doesn't have operator<<
overload for streams. The only way possible to deal with this is to implement own:
Necessary links:
std::chrono::system_clock::to_time_t() (system clock is just example).
The only ways to print time is either std::ctime()
or std::put_time()
(lets omit implementing by hand approach). So let's follow the thread and find it's end and test it:
Since we can manipulate std::chrono::time_point
, and std::chrono::duration
, let's use everything it got:
Converts local calendar time to a time since epoch as a time_t object. time->tm_wday and time->tm_yday are ignored. The values in time are permitted to be outside their normal ranges.
Now the easy stuff, add given days:
Some thoughts:
using namespace std;
rarely buys anything, but opens a chance for errors.standard library has a solution most of the time
modularity is important. Breaking functions into logical pieces makes it very easy to quickly prototype, adjust, mix'n'match.
Conclusion:
In this kind of problems it is very dangerous trying implementing by hand, since there are lots of edge cases. As a result, the problem given was rather a test of knowledge of standard library.
##Standard approach:
Well, not really standard, but in my opinion one should use std::chrono
in this case. Some stuff is done in a roundabout way, but I don't think it is a huge problem. Howard Hinnant has written a library for it, but in case the license isn't acceptable, I'll reimplement some functionality by hand.
###output std::time_point
:
The first issue is outputting a std::time_point
. The problem with it is that it doesn't have operator<<
overload for streams. The only way possible to deal with this is to implement our own:
####Necessary links:
std::chrono::system_clock::to_time_t()
(system clock is just example).
The only ways to print time are either std::ctime()
and std::put_time()
(not counting the "implement by hand" approach). So let's follow the thread and find its end and test it:
Since we can manipulate std::chrono::time_point
, and std::chrono::duration
, let's use everything we have:
Converts local calendar time to a time since epoch as a
time_t
object.time->tm_wday
andtime->tm_yday
are ignored. The values intime
are permitted to be outside their normal ranges.
Now the easy stuff, add the given number of days:
##Some thoughts:
using namespace std;
rarely buys anything, but opens a chance for errors.- standard library has a solution most of the time
- modularity is important. Breaking functions into logical pieces makes it very easy to quickly prototype, adjust, mix'n'match.
##Conclusion: In this kind of problem, it is very dangerous try to implement by hand, since there are lots of edge cases. As a result, the problem given was rather a test of knowledge of standard library.
This is quite tricky problem to get right. As Loki said, we need to convert it to seconds after epoch. But doing so is not trivial...
Standard approach:
Well, not really standard, but in my opinion one should use std::chrono
in this case. Some stuff is done in round about way, but I don't think it is a huge problem. Howard Hinnant have written a library for it, but for a sake of license correctness I'll reimplement some functionality by hand.
output std::time_point:
The first issue is outputting a std::time_point
. The problem with it is that it doesn't have operator<<
overload for streams. The only way possible to deal with this is to implement own:
Necessary links:
std::chrono::system_clock::to_time_t() (system clock is just example).
The only ways to print time is either std::ctime()
or std::put_time()
(lets omit implementing by hand approach). So let's follow the thread and find it's end and test it:
#include <iostream>
#include <chrono>
#include <iomanip>
template <typename Clock, typename Duration>
std::ostream& operator<<(std::ostream& os, const std::chrono::time_point<Clock, Duration>& timep)
{
auto converted_timep = Clock::to_time_t(timep);
os << std::put_time(std::localtime(&converted_timep), "%Y %b %d %H:%M:%S");
return os;
}
int main()
{
auto now = std::chrono::system_clock::now();
std::cout << now;
return 0;
}
Output: 2017 Jun 04 12:07:48
.
The only problem with implementation is that it can't be used from multiple threads, since std::localtime()
returns pointer to static variable. The format could be mutable by some function, but I wouldn't care about it at this point.
Since we can manipulate std::chrono::time_point
, and std::chrono::duration
, let's use everything it got:
convert given date to std::chrono::time_point<system_clock>
:
A good news, at last! From std::mktime()
:
Converts local calendar time to a time since epoch as a time_t object. time->tm_wday and time->tm_yday are ignored. The values in time are permitted to be outside their normal ranges.
Hooray! So we can just fill in the std::tm
structure with year, month, and day since January 1 and we are done!
#include <iostream>
#include <chrono>
#include <iomanip>
template <typename Clock, typename Duration>
std::ostream& operator<<(std::ostream& os, const std::chrono::time_point<Clock, Duration>& timep)
{
auto converted_timep = Clock::to_time_t(timep);
os << std::put_time(std::localtime(&converted_timep), "%Y %b %d %H:%M:%S");
return os;
}
auto convert_to_timepoint(int years, int months, int days)
{
//perform checks, do division, modulus and stuff...
years -= 1900; //epoch
std::tm date = {};
date.tm_year = years;
date.tm_mon = months;
date.tm_mday = days;
return std::chrono::system_clock::from_time_t(std::mktime(&date));
}
int main()
{
auto now = std::chrono::system_clock::now();
std::cout << now << '\n';
std::cout << "calling convert_to_timepoint:\n";
auto date = convert_to_timepoint(1991, 0, 23);
std::cout << date;
return 0;
}
Output:
2017 Jun 04 13:08:49
calling convert_to_timepoint:
1991 Jan 23 00:00:00
Now the easy stuff, add given days:
#include <iostream>
#include <chrono>
#include <iomanip>
template <typename Clock, typename Duration>
std::ostream& operator<<(std::ostream& os, const std::chrono::time_point<Clock, Duration>& timep)
{
auto converted_timep = Clock::to_time_t(timep);
os << std::put_time(std::localtime(&converted_timep), "%Y %b %d %H:%M:%S");
return os;
}
auto convert_to_timepoint(int years, int months, int days)
{
years -= 1900; //epoch
std::tm date = {};
date.tm_year = years;
date.tm_mon = months;
date.tm_mday = days;
return std::chrono::system_clock::from_time_t(std::mktime(&date));
}
template <typename Clock, typename Duration>
auto add_days(const std::chrono::time_point<Clock, Duration>& timepoint, int days_to_add)
{
constexpr std::time_t seconds_in_day = 60 * 60 * 24;
// mm hh dd
std::time_t days = seconds_in_day * days_to_add;
auto date = Clock::to_time_t(timepoint);
return Clock::from_time_t(date + days);
}
int main()
{
auto now = std::chrono::system_clock::now();
std::cout << now << '\n';
std::cout << "calling convert_to_timepoint with 1991 0 23 (1991 Jan 23):\n";
auto date = convert_to_timepoint(1991, 0, 23);
std::cout << date << '\n';
std::cout << "10 day later (1991 Feb 02):\n" << add_days(date, 10);
return 0;
}
Output:
2017 Jun 04 13:21:29
calling convert_to_timepoint with 1991 0 23 (1991 Jan 23):
1991 Jan 23 00:00:00
10 day later (1991 Feb 02):
1991 Feb 02 00:00:00
I left the convert_to_timepoint()
so that it would be reusable on its own, but if needed it can be fused with add_days()
.
Some thoughts:
using namespace std;
rarely buys anything, but opens a chance for errors.standard library has a solution most of the time
modularity is important. Breaking functions into logical pieces makes it very easy to quickly prototype, adjust, mix'n'match.
Conclusion:
In this kind of problems it is very dangerous trying implementing by hand, since there are lots of edge cases. As a result, the problem given was rather a test of knowledge of standard library.