Reputation: 81
I am trying to find out the number of seconds of week to date and i tried following way please correct me if i am wrong:
//tp is time precision and dp is day precision.
auto tp = floor<seconds>(system_clock::now());
auto dp = floor<days>(tp);
dp -= weekday{dp} - Monday;
int WeekSeconds=tp - dp;
and error i am getting below:
jdoodle.cpp: In function ‘int main()’:
jdoodle.cpp:6:28: error: ‘floor’ is not a member of ‘std::chrono’
6 | auto tp = std::chrono::floor<seconds>(std::chrono::system_clock::now());
| ^~~~~
jdoodle.cpp:6:34: error: ‘seconds’ was not declared in this scope; did you mean ‘std::chrono::seconds’?
6 | auto tp = std::chrono::floor<seconds>(std::chrono::system_clock::now());
| ^~~~~~~
| std::chrono::seconds
In file included from jdoodle.cpp:2:
/usr/include/c++/9.2.0/chrono:614:53: note: ‘std::chrono::seconds’ declared here
614 | typedef duration<_GLIBCXX_CHRONO_INT64_T> seconds;
| ^~~~~~~
jdoodle.cpp:7:15: error: ‘floor’ was not declared in this scope
7 | auto dp = floor<days>(tp);
| ^~~~~
jdoodle.cpp:7:21: error: ‘days’ was not declared in this scope
7 | auto dp = floor<days>(tp);
| ^~~~
jdoodle.cpp:8:11: error: ‘weekday’ was not declared in this scope
8 | dp -= weekday{dp} - Monday;
| ^~~~~~~
jdoodle.cpp:8:25: error: ‘Monday’ was not declared in this scope
8 | dp -= weekday{dp} - Monday;
| ^~~~~~
jdoodle.cpp:9:12: error: ‘thisWeekSeconds’ was not declared in this scope
9 | return thisWeekSeconds=tp - dp;
Upvotes: 1
Views: 590
Reputation: 218750
Your code is almost correct, but a little ahead of its time. :-)
You are using new C++20 facilities that are not yet shipping. But there exists a free, open-source preview of the new C++20 chrono library which works with C++11/14/17.
#include "date/date.h"
#include <chrono>
#include <iostream>
int
main()
{
using namespace date;
using namespace std;
using namespace std::chrono;
auto tp = floor<seconds>(system_clock::now());
auto dp = floor<days>(tp);
dp -= weekday{dp} - Monday;
auto WeekSeconds=tp - dp;
cout << WeekSeconds << '\n';
}
WeekSeconds
has type std::chrono::seconds
, as opposed to int
.
Note that this defines the beginning of the week as Monday 00:00:00 UTC.
If you want to define the beginning of the week in some other time zone, such as your local time zone, this would look more like:
#include "date/tz.h"
#include <chrono>
#include <iostream>
int
main()
{
using namespace date;
using namespace std;
using namespace std::chrono;
auto tp = floor<seconds>(system_clock::now());
zoned_seconds dp{current_zone(), tp};
auto lt = floor<days>(dp.get_local_time());
lt -= weekday{lt} - Monday;
dp = lt;
auto WeekSeconds = tp - dp.get_sys_time();
cout << WeekSeconds << '\n';
}
Above I convert to the "local time" using current_zone()
and storing that in a "zoned time". I then extract the local time and do the computation to find the beginning of the week as before. Then store that back into the "zoned time".
Finally I subtract the computed beginning of the week in UTC from the current time. This gives the number of physical seconds since the beginning of the local week.
This brings up an interesting point: What if there was a "Fall back" daylight saving shift between the beginning of the local week and now? Do you want to count the number of physical seconds, which means that this week is 1h short of a normal week of 604800s (7*86400s), or do you want to count calendrical seconds, effectively skipping over the 3600s that were erased by the UTC shift? This latter computation makes every week look 604800s long. It is just that some of the seconds never existed, or that in a "Spring Forward" some will be counted twice.
If the latter computation is what you desire, this can be done by altering the above computation by doing the subtraction in local time instead of in UTC:
auto tp = floor<seconds>(system_clock::now());
zoned_seconds dp{current_zone(), tp};
auto lt = floor<days>(dp.get_local_time());
lt -= weekday{lt} - Monday;
auto WeekSeconds = dp.get_local_time() - lt;
cout << WeekSeconds << '\n';
One final caveat: None of the above computations includes the possibility of a leap second being inserted between now and the beginning of the week. However that too is possible to take into account using utc_clock
-based time_point
s. I'd show an example but such an example will depend on the issues illustrated above such as counting UTC or local time.
Upvotes: 1
Reputation:
As far as I understood you want to get number of seconds in a week, so here is my take:
#include <chrono>
#include <iostream>
#include <ratio>
int main() {
using namespace std;
using namespace std::chrono;
using days = duration<int, ratio_multiply<ratio<24>, chrono::hours::period>>;
using weeks = duration<int, ratio_multiply<ratio<7>, days::period>>;
seconds s = weeks{1};
cout << s.count();
}
Note that the duration days and week is not landed on most compilers because it's in C++20 standard. Not a big deal though, you can easily define yourself, as above.
Upvotes: 1