140 lines
6.0 KiB
C++
140 lines
6.0 KiB
C++
/***
|
|
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: TM.hpp
|
|
Date: 2022-1-24
|
|
Author: Reece
|
|
***/
|
|
#pragma once
|
|
|
|
namespace Aurora::Time
|
|
{
|
|
// This type is intended for interoperability with ANSI c, the Aurora Epoch, and planned calendar APIs
|
|
struct tm
|
|
{
|
|
int year {}; // The absolute gregorian-calendar year
|
|
int mon {}; // Months since January
|
|
|
|
int mday {}; // Days since last month
|
|
AuOptional<int> wday {}; // Days since Monday [usually ignored]
|
|
AuOptional<int> yday {}; // Days since January [usually ignored]
|
|
|
|
int hour {}; // Hours since yesterday
|
|
int min {}; // Minutes since the hour
|
|
int sec {}; // Seconds since the minute
|
|
|
|
AuOptionalEx<bool> isdst {};
|
|
AuOptionalEx<int> knownMinutesWest {}; // Known minutes west - this is the opposite of Linux's minutes east.
|
|
// RESERVED FOR FUTURE CALENDAR API
|
|
|
|
template<typename Dest_t>
|
|
void CopyTo(Dest_t &out) const
|
|
{
|
|
out.tm_sec = sec;
|
|
out.tm_min = min;
|
|
out.tm_hour = hour;
|
|
out.tm_mday = mday + 1;
|
|
out.tm_mon = mon;
|
|
|
|
#if 0
|
|
if (year < 1900)
|
|
{
|
|
out.tm_year = 0;
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
out.tm_year = year - 1900;
|
|
}
|
|
|
|
if (wday)
|
|
{
|
|
auto cur = wday.value();
|
|
if (cur == 6) // ^1
|
|
{
|
|
out.tm_wday = 0;
|
|
}
|
|
else
|
|
{
|
|
out.tm_wday = cur + 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
out.tm_wday = -1;
|
|
}
|
|
|
|
out.tm_yday = yday.value_or(-1);
|
|
|
|
if (!isdst.HasValue())
|
|
{
|
|
out.tm_isdst = -1;
|
|
}
|
|
else
|
|
{
|
|
out.tm_isdst = isdst.value();
|
|
}
|
|
}
|
|
|
|
template<typename In_t>
|
|
void CopyFrom(const In_t &in)
|
|
{
|
|
sec = in.tm_sec;
|
|
min = in.tm_min;
|
|
hour = in.tm_hour;
|
|
mday = in.tm_mday - 1;
|
|
mon = in.tm_mon;
|
|
year = in.tm_year + 1900;
|
|
|
|
if (in.tm_wday == 0) // ^1
|
|
{
|
|
wday = 6;
|
|
}
|
|
else
|
|
{
|
|
wday = in.tm_wday - 1;
|
|
}
|
|
|
|
if (sec > 59) // ^2
|
|
{
|
|
sec = 59;
|
|
}
|
|
|
|
yday = in.tm_yday;
|
|
isdst = in.tm_isdst; // (dont normalize -1. it's a quirk of most modern CRTs we can exploit to easily solve the [user-input + how do i guess DST] issue)
|
|
// (stupid c programs shouldn't be exploiting this anyway. assume all std::tm, ::tm, and similar types calling into us follow boolean logic)
|
|
}
|
|
|
|
inline void Update()
|
|
{ /* no-op for now. */ }
|
|
|
|
private:
|
|
friend struct TMIntlAccessor;
|
|
AuUInt64 localization_[2] {};
|
|
// reserved for uncommitted and experimental calendar APIs
|
|
// currently defined as:
|
|
// u64 uKnownAuroraEpoch
|
|
// u64 optCalendarType
|
|
//
|
|
// Where calendar types are used to convert day orders of magnitude via the JDN offset by -12 hours, and then the remaining hours added back onto the day
|
|
// If !optCalendarType && isdst.value() == true, optCalendarType = gregorian / must be normalized
|
|
// If !optCalendarType && isdst.value() == false, optCalendarType = gregorian
|
|
// optCalendarType = ECalendarType, with gregorian being 0, NULL, and default initialized
|
|
// With uKnownAuroraEpoch leaking in from relevant internal AuTime APIs, it should be possible to create perfect time-zone and duration add/substract APIs on top of this
|
|
// We just need a means to go from uKnownAuroraEpoch to mday/yday/mon/year given the days in year, days in month, and week specific attributes of the calendar
|
|
// Further locale specific detail can be provided by the instance of a generic abstract calendar
|
|
};
|
|
}
|
|
|
|
|
|
|
|
// Malding about the ANSI c defintion of ::tm
|
|
// Note (1): We don't give a single solitary fuck about what ISO 8601 says nor the intentions of braindead boomers who thought there were 61 seconds to an hour (^2)...
|
|
// Sunday is not a weekday; it's apart of the week-END. No English speaker will disagree with this once we get past the obvious gaslighting attempts from NGOs and indoctrination institutions.
|
|
// In my estimation, it's every English speaker ever born after the Stuarts (17xxs+) versus a handful of CIA boys and the International Organization for Standardization.
|
|
// In my tradition of upholding da norf, we're sticking by the 19th century industrialized understanding of time.
|
|
// [tm_]wday is now the day offset since Monday, not days since last week.
|
|
// [tm_]mday is now the day offset since the beginning of the month, not the calendar number - that's to say we deviate from other impls by asserting these members are all offsets, not whatever some CIA fuckbuddies at ANSI said it is.
|
|
// (^2): there isn't such a concept in *CIVIL* time; leap seconds are only in the concept of "academic/astronomy circlejerk time" that no sane person, language runtime, or physical clock has ever cared about, nevermind implemented properly.
|
|
// they are wholly irrelevant to the conversion between calendar systems, and there isn't any legitimate use for polling wall-time with leap-second precision. unless you are looking for an API to build your GPS transponder or an NTP library, leap seconds aren't a factor in anything.
|
|
// this is a c++ library, not a live feed to the bullshit ad-hoc announcements of the international earth rotation and reference service.
|