Open CKD4XXH opened 4 years ago
Yes, but there all alternatives you may prefer. I'll intersperse them below:
auto z = make_zoned(current_zone(), system_clock::now());
auto l = z.get_local_time();
auto mill = floor<milliseconds>(l);
auto day = floor<days>(mill);
or:
auto day = floor<days>(l);
Either works as well as the other.
year_month_day ymd{day};
hh_mm_ss<milliseconds> hmsms{mill - day}; // Or "make_time(mill - day)"?
Yes. In C++17 and higher you can simply say hh_mm_ss hmsms{mill - day};
. This is because the language feature CTAD will deduce the <milliseconds>
template parameter. And for this reason, make_time
, though it still exists, is considered deprecated and was purposefully not put into C++20.
std::cout << "year month day:\n";
std::cout << (ymd.year() - 0_y).count() << '\n';
std::cout << (ymd.month() - December).count() << '\n'; // 1-based. 1==January
std::cout << (ymd.day() - 0_d).count() << '\n'; // Or "static_cast<int>(ymd.day())" ?
The above could also look like:
std::cout << int{ymd.year()} << '\n';
std::cout << unsigned{ymd.month()} << '\n'; // 1-based. 1==January
std::cout << unsigned{ymd.day()} << '\n'; // Or "static_cast<int>(ymd.day())" ? Yes, this too.
Also each of the above can be streamed out directly:
std::cout << ymd.year() << '\n';
std::cout << ymd.month() << '\n';
std::cout << ymd.day() << '\n';
which outputs:
2020
Mar
04
std::cout << "hours minutes seconds weekday:\n";
std::cout << hmsms.hours().count() << '\n';
std::cout << hmsms.minutes().count() << '\n';
std::cout << hmsms.seconds().count() << '\n';
The above can also be streamed out direclty:
std::cout << hmsms.hours() << '\n';
std::cout << hmsms.minutes() << '\n';
std::cout << hmsms.seconds() << '\n';
resulting in:
12h
22min
42s
std::cout << (weekday{day} - Sunday).count() << '\n'; // 1==Monday
This can also be done with:
std::cout << weekday{day}.c_encoding() << '\n'; // 1==Monday
And there is also an .iso_encoding()
which maps Sunday to 7.
std::cout << "isdst:\n";
std::cout << std::boolalpha << (z.get_info().save != minutes{0}) << '\n';
In C++14 and later you can use 0min
in place of minutes{0}
.
std::cout << "subseconds:\n";
std::cout << hmsms.subseconds().count() << '\n';
Without the .count()
above:
std::cout << hmsms.subseconds() << '\n';
Then you also get the units:
410ms
A sub-question:
How to qualify things like 0min
or 0_y
?
std::chrono::minutes{0}
works.
std::chrono::0min
does not work. ("expected unqualified-id before numeric constant")
I don't know of a way to qualify user defined literals. For this reason they are often put in namespaces that only define literals so that you can have a using directive that doesn't pull that much into scope.
For example _y
lives in namespace date::literals
. You can access it with either using namespace date
(which pulls in a lot), or using namespace date::literals
(which only pulls in other date literals.
For min
the most limited scope is namespace std::chrono_literals
. The next largest scope is namespace std::literals
(which pulls in all std literals, not just the chrono ones). And you also get them with the huge scope of namespace std
.
If you're in a context where you really don't want a using
(such as namespace scope in a header), then std::chrono::minutes{0}
and date::year{0}
is the way to go.
What is the type of date::make_zoned
?
How to pass, for example, a zoned time to a funtion (as parameter)?
In my current environment
date::zoned_time<std::common_type_t<std::chrono::nanoseconds, std::chrono::seconds>> now = date::make_zoned(date::current_zone(), std::chrono::system_clock::now());
seems working, but I am afraid that in other environment, where system_clock has other resolution than nanoseconds, it will fail.
(This question may be independent of date library. I apologize for that.)
No need to apologize. I'm happy to help.
date::make_zoned
should be considered deprecated. It's only function is to deduce the template arguments for zoned_time<Duration>
, which is what make_zoned
returns. In C++17 and later, the constructor arguments to zoned_time
can be automatically reduced.
For example:
auto zt = make_zoned(current_zone(), system_clock::now());
zoned_time<system_clock::duration> zt{current_zone(), system_clock::now()};
zoned_time zt{current_zone(), system_clock::now()};
All three lines above are equivalent. The third one requires C++17 or higher.
And that was a long-winded way of saying that zoned_time<system_clock::duration>
is the type you're looking for. The type of system_clock::duration
will vary with platform:
microseconds
.nanoseconds
.Thank you.
(Issue can be closed.)
By trial and error, i figured out something, but please verify. Is this the proper way to break down a time point? Extract fields, especially the milliseconds (subseconds). Into plain old integer numbers.