userver: /data/code/userver/libraries/proto-structs/src/proto-structs/date.cpp Source File
Loading...
Searching...
No Matches
date.cpp
1#include <userver/proto-structs/date.hpp>
2
3#include <fmt/format.h>
4
5#include <userver/proto-structs/exceptions.hpp>
6#include <userver/utils/impl/internal_tag.hpp>
7
8USERVER_NAMESPACE_BEGIN
9
10namespace proto_structs {
11
12Date::Date(utils::impl::InternalTag, std::int32_t year, std::int32_t month, std::int32_t day) {
13 if (!IsValid(utils::impl::InternalTag{}, year, month, day)) {
14 ThrowError(year, month, day, "invalid or out of range");
15 }
16
17 if (year != 0) {
18 year_.emplace(year);
19 }
20
21 if (month != 0) {
22 month_.emplace(static_cast<unsigned>(month));
23 }
24
25 if (day != 0) {
26 day_.emplace(static_cast<unsigned>(day));
27 }
28}
29
30bool Date::IsValid(utils::impl::InternalTag, std::int32_t year_num, std::int32_t month_num, std::int32_t day_num)
31 noexcept {
32 std::optional<std::chrono::year> year;
33 std::optional<std::chrono::month> month;
34 std::optional<std::chrono::day> day;
35
36 if (year_num != 0) {
37 year.emplace(year_num);
38 }
39
40 if (month_num != 0) {
41 if (month_num > 0 && month_num <= 12) {
42 month.emplace(static_cast<unsigned>(month_num));
43 } else {
44 return false;
45 }
46 }
47
48 if (day_num != 0) {
49 if (day_num > 0 && day_num <= 31) {
50 day.emplace(static_cast<unsigned>(day_num));
51 } else {
52 return false;
53 }
54 }
55
56 return IsValid(year, month, day);
57}
58
59void Date::ThrowError(std::int32_t year, std::int32_t month, std::int32_t day, const char* reason) {
60 throw ValueError(fmt::format("Date '{}y/{}m/{}d' error: {}", year, month, day, reason));
61}
62} // namespace proto_structs
63
64USERVER_NAMESPACE_END