Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Stroika::Foundation::Time::Date Class Reference

#include <Date.h>

Classes

struct  ReferencePoint
 

Public Types

enum class  NonStandardPrintFormat : uint8_t
 DisplayFormat is a representation which a date can be transformed in and out of. More...
 
using SignedJulianDayNumber = make_signed_t< JulianDayNumber >
 

Public Member Functions

constexpr Date (Date &&src) noexcept=default
 
nonvirtual constexpr JulianDayNumber GetJulianRep () const
 return the Julian Day Number (JDN) - corresponding to this date object (https://en.wikipedia.org/wiki/Julian_day) - days since Monday, January 1, 4713 BC
 
nonvirtual String Format (NonStandardPrintFormat pf=NonStandardPrintFormat::eDEFAULT) const
 
nonvirtual String ToString () const
 
nonvirtual Date Add (int d) const
 
nonvirtual days Difference (const Date &rhs) const
 Returns the difference (*this - rhs) between the two Date records;.
 
nonvirtual Date operator+ (int daysOffset) const
 Syntactic sure for Add (n);.
 
nonvirtual days operator- (const Date &rhs) const
 
template<typename T >
nonvirtual T As () const
 

Static Public Member Functions

static constexpr JulianDayNumber ToJulianRep (month m, day d, year y, DataExchange::ValidationStrategy validationStrategy=DataExchange::ValidationStrategy::eAssertion)
 
static constexpr year_month_day FromJulianRep (JulianDayNumber j, DataExchange::ValidationStrategy validationStrategy=DataExchange::ValidationStrategy::eAssertion)
 
static Date Now () noexcept
 
static Date Parse (const String &rep, const locale &l=locale{})
 
static optional< DateParseQuietly (const String &rep, const String &formatPattern)
 like Parse(), but returns nullopt on parse error, not throwing exception. if locale is missing, and formatPattern is not locale independent, the current locale (locale{}) is used. if rep is empty, this will return nullopt
 
static days Since (Date dStart, Date dEnd)
 

Static Public Attributes

static constexpr ReferencePoint kStartOfJulianCalendar {-4712y / January / 1, 0}
 
static constexpr ReferencePoint kUNIXEpoch {1970y / January / 1, 2440588}
 
static constexpr ReferencePoint kGregorianCalendarEpoch {1752y / September / 14d, 2361222}
 
static constexpr ReferencePoint kMinDateReference = kStartOfJulianCalendar
 
static const JulianDayNumber kMinJulianRep = kMinDateReference.fJulianRep
 
static const JulianDayNumber kMaxJulianRep = Date::ToJulianRep (December, 31d, Year::eLastYear)
 
static constexpr string_view kISO8601Format = "%Y-%m-%d"sv
 Y-M-D format - locale independent, and ISO-8601 date format standard.
 
static constexpr string_view kLocaleStandardFormat = "%x"sv
 
static constexpr string_view kLocaleStandardAlternateFormat = "%Ex"sv
 
static constexpr string_view kMonthDayYearFormat = "%m/%d/%Y"sv
 classic (american) month-day-year format, but unlike D, this uses Y, so the 4-digit form of year
 
static const Traversal::Iterable< StringkDefaultParseFormats
 
static const Date kMin {Date::kMinJulianRep}
 
static const Date kMax {Date::kMaxJulianRep}
 

Detailed Description

Description: The Date class is (originally) based on SmallTalk-80, The Language & Its Implementation, page 108 (apx) - but changed to use Gregorian instead of Julian calendar.

Note
This class integrates neatly with the C++20 chrono date support. You can easily go back and forth (e.g. Date{std::chrono::year_month_day...}} or d.As<year_month_day> ())

The main features of the Stroika Data class (compared to the std c++ date support):

o   Simpler to use/understand (Stroika 'Date' does about the same thing as a bevy of
    different chrono classes)
o   Stroika Date immutable (OK - difference not clearly advantage)
o   Validation (constructor DataExchange::ValidationStrategy)
    (no non-ok () Date objects in Stroika). Nice clear semantics about exceptions
    and assertions.
o   Easier to use formatting
o   ISO8601 formatting
o   Wraps needlessly complicated locale/facet API for formatting dates as Strings, or
    parsing them from strings.
o   Builtin support for Julian calendar (again - maybe this is a difference not advantage?)
Note
o Date stores date's internally as Julian days, and so is valid for any date > January 1, −4713; Also note sizeof (year_month_day) == sizeof (Date) == 4
Miscellaneous references
o According to https://en.wikipedia.org/wiki/Gregorian_calendar Britain and the British Empire (including the eastern part of what is now the United States) adopted the Gregorian calendar in 1752 o https://aa.usno.navy.mil/data/JulianDate Best Julian date calculator I found (bad but best) o Proleptic Gregorian Calendar https://en.wikipedia.org/wiki/Gregorian_calendar#Proleptic_Gregorian_calendar o Julian Day Numer https://en.wikipedia.org/wiki/Julian_day

Class Date knows about some obvious information: -> there are seven days in a week, each day having a symbolic name and an index 1..7 -> there are twelve months in a year, each having a symbolic name and an index 1..12. -> months have 28..31 days and -> a particular year might be a leap year." @iverbatim NB: Date implies NO NOTION of timezone. @endiverbatim \note The entire Date API is immutable - meaning that all methods are const (except constructor and assignment operator) \note Date constructors REQUIRE valid inputs, and any operations which might overflow throw range_error instead of creating invalid values. \note Would like to make Date inherit from Debug::AssertExternallySynchronizedMutex to assure its not accidentially modified, but that's difficult because its sometimes uses as a constexpr \note \em Thread-Safety <a href="Thread-Safety.md#C++-Standard-Thread-Safety">C++-Standard-Thread-Safety</a> \note <a href="Design-Overview.md#Comparisons">Comparisons: static_assert (totally_ordered<Date>);

Definition at line 327 of file Date.h.

Member Typedef Documentation

◆ SignedJulianDayNumber

using Stroika::Foundation::Time::Date::SignedJulianDayNumber = make_signed_t<JulianDayNumber>

Sometimes want a signed type to compute differences.

Definition at line 340 of file Date.h.

Member Enumeration Documentation

◆ NonStandardPrintFormat

DisplayFormat is a representation which a date can be transformed in and out of.

eCurrentLocale_WithZerosStripped eCurrentLocale_WithZerosStripped is locale{}, but with many cases of leading zero's, stripped, so for example, 03/05/2013 becomes 3/5/2013. This only affects the day/month, and not the year.

Note
Common::DefaultNames<> supported

Definition at line 587 of file Date.h.

Constructor & Destructor Documentation

◆ Date()

constexpr Stroika::Foundation::Time::Date::Date ( Date &&  src)
constexprdefaultnoexcept

if DataExchange::ValidationStrategy is NOT specified, or == DataExchange::ValidationStrategy::eAssertion, then

Precondition
kMinJulianRep <= julianRep <= kMaxJulianRep AND Date::kMin <= d <= Date::kMax else if eThrow, then throw when arguments out of range.
Example Usage
Assert (1906y/May/12d == Date{1906y, May, 12d});

Member Function Documentation

◆ ToJulianRep()

constexpr Date::JulianDayNumber Stroika::Foundation::Time::Date::ToJulianRep ( month  m,
day  d,
year  y,
DataExchange::ValidationStrategy  validationStrategy = DataExchange::ValidationStrategy::eAssertion 
)
staticconstexpr

Very hard to figure out how todo this. But this algorithm appears correct at least for dates > Gregorian Calendar era.

Also, web is littered with Julian date converters that are wrong, somewhat wrong, or very wrong (at least all disagreeing). I used https://aa.usno.navy.mil/data/JulianDate as my reference/final arbiter/check (at least for dates past 1800).

Definition at line 140 of file Date.inl.

◆ FromJulianRep()

constexpr year_month_day Stroika::Foundation::Time::Date::FromJulianRep ( JulianDayNumber  j,
DataExchange::ValidationStrategy  validationStrategy = DataExchange::ValidationStrategy::eAssertion 
)
staticconstexpr

Compute the month/day/year associated with a given Julian day number. NOTE, this is only really accurate (as of Stroika v3.0d1) for dates in the Gregorian Calendar epoch (roughly since 1753).

Definition at line 195 of file Date.inl.

◆ Now()

Date Date::Now ( )
staticnoexcept

Return the current Date - shorthand for DateTime::Now ().GetDate () (so uses localtime)

Definition at line 42 of file Date.cpp.

◆ Parse()

Date Stroika::Foundation::Time::Date::Parse ( const String rep,
const locale &  l = locale{} 
)
static

Note that for the consumedCharsInStringUpTo overload, the consumedCharsInStringUpTo is filled in with the position after the last character read (so before the next character to be read).

Note
Parse (... locale) with no formats specified, defaults to parsing with kDefaultParseFormats formats.
if the locale is not specified, its assumed to be the current locale (locale{}))
an empty string produces BadFormat exception.
See also
https://en.cppreference.com/w/cpp/locale/time_get/get for allowed formatPatterns
Note
when calling Parse with a format string and no locale, the default locale is assumed

Definition at line 301 of file Date.inl.

◆ Format()

String Date::Format ( NonStandardPrintFormat  pf = NonStandardPrintFormat::eDEFAULT) const

For formatPattern, see http://en.cppreference.com/w/cpp/locale/time_put/put If only formatPattern specified, and no locale, use default (global) locale.

Definition at line 119 of file Date.cpp.

◆ ToString()

String Stroika::Foundation::Time::Date::ToString ( ) const
See also
Characters::ToString ()

Definition at line 389 of file Date.inl.

◆ Add()

Date Stroika::Foundation::Time::Date::Add ( int  d) const

Returns a new Date object based on this Date, with 'dayCount' days added.

Example Usage
Date d = 1906y/May/12d;
d = d.Add (1); // OR d = d + 1;
Assert (d == 1906y/May/13d);
nonvirtual Date Add(int d) const
Definition Date.inl:393
Note
- a duration is much more precise than a day, so that overload rounds.

Definition at line 393 of file Date.inl.

◆ Since()

days Stroika::Foundation::Time::Date::Since ( Date  dStart,
Date  dEnd 
)
static

returns number of days between a start day and end day: Never less than zero. No argument version computes days between *this and 'now'.

Definition at line 409 of file Date.inl.

◆ Difference()

auto Stroika::Foundation::Time::Date::Difference ( const Date rhs) const

Returns the difference (*this - rhs) between the two Date records;.

Note
Before Stroika v3.0d1, this returned SignedJulianDayNumber.

Definition at line 416 of file Date.inl.

◆ operator+()

Date Stroika::Foundation::Time::Date::operator+ ( int  daysOffset) const

Syntactic sure for Add (n);.

Example Usage
Date d = 1906y/May/12d;
d = d + 1;
Assert (d == 1906y/May/13d);

Definition at line 397 of file Date.inl.

◆ operator-()

auto Stroika::Foundation::Time::Date::operator- ( const Date rhs) const

days operator- (const Date& rhs): Syntactic sugar on Difference() Date operator- (days or int daysOffset) Syntactic sugar on Add(-arg)

Note
subtracting by duration 'd' rounds to days...

Definition at line 420 of file Date.inl.

◆ As()

template<typename T >
nonvirtual T Stroika::Foundation::Time::Date::As ( ) const

Defined for struct tm year_month_day

Generally constexpr where possible.

Member Data Documentation

◆ kStartOfJulianCalendar

constexpr ReferencePoint Stroika::Foundation::Time::Date::kStartOfJulianCalendar {-4712y / January / 1, 0}
staticconstexpr

Start of Julian Calendar (see https://docs.kde.org/trunk5/en/kstars/kstars/ai-julianday.html) JD=0, is January 1, 4713 BC (or -4712 January 1, since there was no year '0').

Definition at line 360 of file Date.h.

◆ kUNIXEpoch

constexpr ReferencePoint Stroika::Foundation::Time::Date::kUNIXEpoch {1970y / January / 1, 2440588}
staticconstexpr

◆ kGregorianCalendarEpoch

constexpr ReferencePoint Stroika::Foundation::Time::Date::kGregorianCalendarEpoch {1752y / September / 14d, 2361222}
staticconstexpr

See https://en.wikipedia.org/wiki/Gregorian_calendar September, 14d, 1752 (even this not sure of, but used this in Stroika v2.1)

"Algorithm 199 from Communications of the ACM, Volume 6, No. 8, (Aug. 1963), p. 444. Gregorian calendar started on Sep. 14, 1752"

Definition at line 376 of file Date.h.

◆ kMinDateReference

constexpr ReferencePoint Stroika::Foundation::Time::Date::kMinDateReference = kStartOfJulianCalendar
staticconstexpr

The Stroika Date class works with any date after this date (apx 4000 BC), but mostly just very accurate post Gregorian Calendar era (1753 apx).

Definition at line 383 of file Date.h.

◆ kMinJulianRep

const JulianDayNumber Stroika::Foundation::Time::Date::kMinJulianRep = kMinDateReference.fJulianRep
static

kMinJulianRep is defined (later) constexpr.

Note
In Stroika v2.1, 2361222, aka Date::ToJulianRep (September, 14d, year{1752}) but now its around 4000BC (see kMinDateReference)

Definition at line 413 of file Date.h.

◆ kMaxJulianRep

constexpr Date::JulianDayNumber Stroika::Foundation::Time::Date::kMaxJulianRep = Date::ToJulianRep (December, 31d, Year::eLastYear)
staticconstexpr

kMaxJulianRep is defined (later) constexpr.

Definition at line 419 of file Date.h.

◆ kISO8601Format

constexpr string_view Stroika::Foundation::Time::Date::kISO8601Format = "%Y-%m-%d"sv
staticconstexpr

Y-M-D format - locale independent, and ISO-8601 date format standard.

Note
sometimes represented as F (see https://en.cppreference.com/w/cpp/chrono/c/wcsftime), but that's not supported in https://en.cppreference.com/w/cpp/locale/time_get/get. so equivalent to Y-m-d
this is LOCALE-INDEPENDENT
See also
kMonthDayYearFormat
Note
also used for XML

Definition at line 465 of file Date.h.

◆ kLocaleStandardFormat

constexpr string_view Stroika::Foundation::Time::Date::kLocaleStandardFormat = "%x"sv
staticconstexpr

◆ kLocaleStandardAlternateFormat

constexpr string_view Stroika::Foundation::Time::Date::kLocaleStandardAlternateFormat = "%Ex"sv
staticconstexpr

◆ kMonthDayYearFormat

constexpr string_view Stroika::Foundation::Time::Date::kMonthDayYearFormat = "%m/%d/%Y"sv
staticconstexpr

classic (american) month-day-year format, but unlike D, this uses Y, so the 4-digit form of year

Note
https://en.cppreference.com/w/cpp/locale/time_get/get
This format is LOCALE INDEPENDENT (according to https://en.cppreference.com/w/cpp/locale/time_get/get)
See also
kISO8601Format

Definition at line 487 of file Date.h.

◆ kDefaultParseFormats

const Traversal::Iterable< String > Stroika::Foundation::Time::Date::kDefaultParseFormats
static
Initial value:
{
}
static constexpr string_view kISO8601Format
Y-M-D format - locale independent, and ISO-8601 date format standard.
Definition Date.h:465
static constexpr string_view kLocaleStandardAlternateFormat
Definition Date.h:477
static constexpr string_view kMonthDayYearFormat
classic (american) month-day-year format, but unlike D, this uses Y, so the 4-digit form of year
Definition Date.h:487
static constexpr string_view kLocaleStandardFormat
Definition Date.h:471

Default formats used by Date::Parse () to parse time strings. The first of these - kLocaleStandardFormat, is the locale-specific date format.

Definition at line 494 of file Date.h.

◆ kMin

constexpr Date Stroika::Foundation::Time::Date::kMin {Date::kMinJulianRep}
staticconstexpr

Date::kMin is the first date this Date class supports representing.

Definition at line 542 of file Date.h.

◆ kMax

constexpr Date Stroika::Foundation::Time::Date::kMax {Date::kMaxJulianRep}
staticconstexpr

Date::kMax is the last date this Date class supports representing.

Definition at line 548 of file Date.h.


The documentation for this class was generated from the following files: