/*** 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 wday {}; // Days since Monday [usually ignored] AuOptional yday {}; // Days since January [usually ignored] int hour {}; // Hours since yesterday int min {}; // Minutes since the hour int sec {}; // Seconds since the minute AuOptionalEx isdst {}; AuOptionalEx knownMinutesWest {}; // Known minutes west - this is the opposite of Linux's minutes east. // RESERVED FOR FUTURE CALENDAR API template 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 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.