5namespace Stroika::Foundation::Time {
7 enum class [[deprecated (
"Since Stroika v3.0d1, unused and use std::chrono")]] DayOfYear : uint16_t {
126 [[deprecated (
"Since Stroika v3.0d1, use year{}.is_leap ()")]]
inline bool IsLeapYear (Year y)
130 [[deprecated (
"Since Stroika v3.0d1, use year{}.is_leap ()")]]
inline bool IsLeapYear (
int y)
132 return Year{y}.is_leap ();
143 if (not m.ok () or not d.ok () or not y.ok () or y / m / d <
kMinDateReference.fYMD) {
147 Require (y.ok () and m.ok () and d.ok ());
152 JulianDayNumber result = [&] ()
noexcept -> JulianDayNumber {
154 return static_cast<JulianDayNumber
> ((chrono::sys_days{y / m / d} - chrono::sys_days{
kGregorianCalendarEpoch.fYMD}).count ()) +
157 return static_cast<JulianDayNumber
> ((chrono::sys_days{y / m / d} - chrono::sys_days{
kStartOfJulianCalendar.fYMD}).count ()) +
161 if (not is_constant_evaluated ()) {
162 [[maybe_unused]] JulianDayNumber stroikav21Algorithm = [&] ()
noexcept -> JulianDayNumber {
183 Date::JulianDayNumber c = yy / 100;
184 Date::JulianDayNumber ya = yy - 100 * c;
185 return ((146097 * c) >> 2) + ((1461 * ya) >> 2) + (153 * mm + 2) / 5 + dd + 1721119;
193 return ToJulianRep (ymd.month (), ymd.day (), ymd.year (), validationStrategy);
205 year_month_day result = [&] ()
noexcept -> year_month_day {
212 if (not is_constant_evaluated ()) {
213 [[maybe_unused]] year_month_day legacyValue = [&] () {
229 JulianDayNumber j = jr - 1721119;
230 y = (((j << 2) - 1) / 146097);
231 j = (j << 2) - 1 - 146097 * y;
233 j = ((d << 2) + 3) / 1461;
234 d = ((d << 2) + 3 - 1461 * j);
236 m = (5 * d - 3) / 153;
237 d = 5 * d - 3 - 153 * m;
257 : fRep_{FromJulianRep (julianRep, validationStrategy)}
266 : Date{year_month_day{y, m, d}, validationStrategy}
270 constexpr year_month_day
Date::As ()
const
278 tm.tm_year =
static_cast<int> (GetYear ()) - kTM_Year_RelativeToYear_;
279 tm.tm_mon =
static_cast<unsigned int> (GetMonth ()) - 1;
280 tm.tm_mday =
static_cast<unsigned int> (GetDayOfMonth ());
287 inline constexpr year Date::GetYear ()
const
289 return fRep_.year ();
291 inline constexpr month Date::GetMonth ()
const
293 Ensure (January <= fRep_.month () and fRep_.month () <= December);
294 return fRep_.month ();
296 inline constexpr day Date::GetDayOfMonth ()
const
298 Ensure (1d <= fRep_.day () and fRep_.day () <= 31d);
307 return Date::Parse_ (rep, l, formatPatterns,
nullptr);
312 return Date::Parse_ (rep, l, formatPatterns, consumedCharsInStringUpTo);
314 inline Date
Date::Parse (
const String& rep,
const locale& l,
size_t* consumedCharsInStringUpTo)
319 inline Date
Date::Parse (
const String& rep,
const locale& l,
const String& formatPattern)
324 wstring wRep = rep.As<wstring> ();
325 const time_get<wchar_t>& tmget = use_facet<time_get<wchar_t>> (l);
326 if (
auto r = ParseQuietly_ (wRep, tmget, formatPattern,
nullptr)) {
331 inline Date
Date::Parse (
const String& rep,
const locale& l,
const String& formatPattern,
size_t* consumedCharsInStringUpTo)
337 wstring wRep = rep.As<wstring> ();
338 const time_get<wchar_t>& tmget = use_facet<time_get<wchar_t>> (l);
339 if (
auto r = ParseQuietly_ (wRep, tmget, formatPattern, consumedCharsInStringUpTo)) {
344 inline Date
Date::Parse (
const String& rep,
const Traversal::Iterable<String>& formatPatterns)
346 return Date::Parse_ (rep, locale::classic (), formatPatterns,
nullptr);
348 inline Date
Date::Parse (
const String& rep,
const Traversal::Iterable<String>& formatPatterns,
size_t* consumedCharsInStringUpTo)
351 return Date::Parse_ (rep, locale::classic (), formatPatterns, consumedCharsInStringUpTo);
353 inline Date
Date::Parse (
const String& rep,
const String& formatPattern)
358 wstring wRep = rep.As<wstring> ();
359 const time_get<wchar_t>& tmget = use_facet<time_get<wchar_t>> (locale::classic ());
360 if (
auto r = ParseQuietly_ (wRep, tmget, formatPattern,
nullptr)) {
365 inline Date
Date::Parse (
const String& rep,
const String& formatPattern,
size_t* consumedCharsInStringUpTo)
371 wstring wRep = rep.As<wstring> ();
372 const time_get<wchar_t>& tmget = use_facet<time_get<wchar_t>> (locale::classic ());
373 if (
auto r = ParseQuietly_ (wRep, tmget, formatPattern, consumedCharsInStringUpTo)) {
380 return ParseQuietly (rep, locale::classic (), formatPattern);
387 return ParseQuietly_ (rep.
As<wstring> (), use_facet<time_get<wchar_t>> (l), formatPattern,
nullptr);
395 return Add (days{dayCount});
399 return this->
Add (daysOffset);
403 return this->
Add (daysOffset);
407 return this->
Add (d);
412 return dEnd - dStart;
418 return chrono::sys_days{fRep_} - chrono::sys_days{rhs.fRep_};
422 return Difference (rhs);
426 return Add (-daysOffset);
430 return Add (-daysOffset);
439 constexpr EnumNames<Stroika::Foundation::Time::Date::NonStandardPrintFormat> DefaultNames<Stroika::Foundation::Time::Date::NonStandardPrintFormat>::k{{{
440 {Stroika::Foundation::Time::Date::NonStandardPrintFormat::eCurrentLocale_WithZerosStripped, L
"Current-Locale-With-Zeros-Stripped"},
446 inline constexpr Time::Date Default<Time::Date>::kLowerBound{
Time::Date::kMin};
447 inline constexpr Time::Date Default<Time::Date>::kUpperBound{
Time::Date::kMax};
450 inline Time::Date Default<Time::Date>::GetNext (Time::Date n)
454 inline Time::Date Default<Time::Date>::GetPrevious (Time::Date n)
#define RequireNotNull(p)
#define Stroika_Define_Enum_Bounds(FIRST_ITEM, LAST_ITEM)
String is like std::u32string, except it is much easier to use, often much more space efficient,...
nonvirtual days Difference(const Date &rhs) const
Returns the difference (*this - rhs) between the two Date records;.
nonvirtual String Format(NonStandardPrintFormat pf=NonStandardPrintFormat::eDEFAULT) const
nonvirtual days operator-(const Date &rhs) const
nonvirtual Date operator+(int daysOffset) const
Syntactic sure for Add (n);.
static constexpr ReferencePoint kGregorianCalendarEpoch
static optional< Date > ParseQuietly(const String &rep, const String &formatPattern)
like Parse(), but returns nullopt on parse error, not throwing exception. if locale is missing,...
static const JulianDayNumber kMinJulianRep
static const JulianDayNumber kMaxJulianRep
static constexpr ReferencePoint kMinDateReference
static Date Parse(const String &rep, const locale &l=locale{})
nonvirtual String ToString() const
static constexpr JulianDayNumber ToJulianRep(month m, day d, year y, DataExchange::ValidationStrategy validationStrategy=DataExchange::ValidationStrategy::eAssertion)
static constexpr ReferencePoint kStartOfJulianCalendar
static constexpr year_month_day FromJulianRep(JulianDayNumber j, DataExchange::ValidationStrategy validationStrategy=DataExchange::ValidationStrategy::eAssertion)
nonvirtual constexpr JulianDayNumber GetJulianRep() const
return the Julian Day Number (JDN) - corresponding to this date object (https://en....
constexpr Date(Date &&src) noexcept=default
static const Traversal::Iterable< String > kDefaultParseFormats
nonvirtual Date Add(int d) const
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
void Throw(T &&e2Throw)
identical to builtin C++ 'throw' except that it does helpful, type dependent DbgTrace() messages firs...
Simple wrapper on std::chrono::day, with some helpful validation properties (assures constructed 'ok'...
constexpr DayOfMonth(day d, DataExchange::ValidationStrategy validationStrategy=DataExchange::ValidationStrategy::eAssertion)
constexpr DayOfWeek(weekday w, DataExchange::ValidationStrategy validationStrategy=DataExchange::ValidationStrategy::eAssertion)
Simple wrapper on std::chrono::month, with some helpful validation properties (assures constructed 'o...
constexpr MonthOfYear(month m, DataExchange::ValidationStrategy validationStrategy=DataExchange::ValidationStrategy::eAssertion)
Simple wrapper on std::chrono::year, with some helpful validation properties (assures constructed 'ok...
static constexpr year eLastYear