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}
269 template <
typename T>
271 requires (Common::IAnyOf<::tm, tm, year_month_day> or Common::ITimePoint<T>)
273 if constexpr (same_as<T, ::tm>) {
275 tm.tm_year =
static_cast<int> (GetYear ()) - kTM_Year_RelativeToYear_;
276 tm.tm_mon =
static_cast<unsigned int> (GetMonth ()) - 1;
277 tm.tm_mday =
static_cast<unsigned int> (GetDayOfMonth ());
280 else if constexpr (same_as<T, year_month_day>) {
283 else if constexpr (Common::ITimePoint<T>) {
285 using CLOCK_T =
typename T::clock;
286 using DURATION_T =
typename T::duration;
287 ::tm asTM = this->As<::tm> ();
288 time_t thisTimeT = mktime (&asTM);
289 auto t = Time::clock_cast<CLOCK_T> (chrono::system_clock::from_time_t (thisTimeT));
290 if constexpr (same_as<DURATION_T, chrono::system_clock::duration>) {
294 return chrono::time_point_cast<DURATION_T> (t);
302 inline constexpr year Date::GetYear ()
const
304 return fRep_.year ();
306 inline constexpr month Date::GetMonth ()
const
308 Ensure (January <= fRep_.month () and fRep_.month () <= December);
309 return fRep_.month ();
311 inline constexpr day Date::GetDayOfMonth ()
const
313 Ensure (1d <= fRep_.day () and fRep_.day () <= 31d);
322 return Date::Parse_ (rep, l, formatPatterns,
nullptr);
327 return Date::Parse_ (rep, l, formatPatterns, consumedCharsInStringUpTo);
329 inline Date
Date::Parse (
const String& rep,
const locale& l,
size_t* consumedCharsInStringUpTo)
334 inline Date
Date::Parse (
const String& rep,
const locale& l,
const String& formatPattern)
339 wstring wRep = rep.As<wstring> ();
340 const time_get<wchar_t>& tmget = use_facet<time_get<wchar_t>> (l);
341 if (
auto r = ParseQuietly_ (wRep, tmget, formatPattern,
nullptr)) {
346 inline Date
Date::Parse (
const String& rep,
const locale& l,
const String& formatPattern,
size_t* consumedCharsInStringUpTo)
352 wstring wRep = rep.As<wstring> ();
353 const time_get<wchar_t>& tmget = use_facet<time_get<wchar_t>> (l);
354 if (
auto r = ParseQuietly_ (wRep, tmget, formatPattern, consumedCharsInStringUpTo)) {
359 inline Date
Date::Parse (
const String& rep,
const Traversal::Iterable<String>& formatPatterns)
361 return Date::Parse_ (rep, locale::classic (), formatPatterns,
nullptr);
363 inline Date
Date::Parse (
const String& rep,
const Traversal::Iterable<String>& formatPatterns,
size_t* consumedCharsInStringUpTo)
366 return Date::Parse_ (rep, locale::classic (), formatPatterns, consumedCharsInStringUpTo);
368 inline Date
Date::Parse (
const String& rep,
const String& formatPattern)
373 wstring wRep = rep.As<wstring> ();
374 const time_get<wchar_t>& tmget = use_facet<time_get<wchar_t>> (locale::classic ());
375 if (
auto r = ParseQuietly_ (wRep, tmget, formatPattern,
nullptr)) {
380 inline Date
Date::Parse (
const String& rep,
const String& formatPattern,
size_t* consumedCharsInStringUpTo)
386 wstring wRep = rep.As<wstring> ();
387 const time_get<wchar_t>& tmget = use_facet<time_get<wchar_t>> (locale::classic ());
388 if (
auto r = ParseQuietly_ (wRep, tmget, formatPattern, consumedCharsInStringUpTo)) {
395 return ParseQuietly (rep, locale::classic (), formatPattern);
402 return ParseQuietly_ (rep.
As<wstring> (), use_facet<time_get<wchar_t>> (l), formatPattern,
nullptr);
410 return Add (days{dayCount});
414 return this->
Add (daysOffset);
418 return this->
Add (daysOffset);
422 return this->
Add (d);
427 return dEnd - dStart;
433 return chrono::sys_days{fRep_} - chrono::sys_days{rhs.fRep_};
437 return Difference (rhs);
441 return Add (-daysOffset);
445 return Add (-daysOffset);
454 constexpr EnumNames<Stroika::Foundation::Time::Date::NonStandardPrintFormat> DefaultNames<Stroika::Foundation::Time::Date::NonStandardPrintFormat>::k{{{
455 {Stroika::Foundation::Time::Date::NonStandardPrintFormat::eCurrentLocale_WithZerosStripped, L
"Current-Locale-With-Zeros-Stripped"},
461 inline constexpr Time::Date Default<Time::Date>::kLowerBound{
Time::Date::kMin};
462 inline constexpr Time::Date Default<Time::Date>::kUpperBound{
Time::Date::kMax};
465 inline Time::Date Default<Time::Date>::GetNext (Time::Date n)
469 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