mirror of
https://github.com/Redot-Engine/redot-engine.git
synced 2025-12-06 15:21:56 -05:00
Merge pull request #106759 from aaronp64/time_year_calc
Update `time.cpp` year/unix time conversions to be constant time
This commit is contained in:
@@ -37,6 +37,33 @@
|
|||||||
#define IS_LEAP_YEAR(year) (!((year) % 4) && (((year) % 100) || !((year) % 400)))
|
#define IS_LEAP_YEAR(year) (!((year) % 4) && (((year) % 100) || !((year) % 400)))
|
||||||
#define YEAR_SIZE(year) (IS_LEAP_YEAR(year) ? 366 : 365)
|
#define YEAR_SIZE(year) (IS_LEAP_YEAR(year) ? 366 : 365)
|
||||||
|
|
||||||
|
static constexpr int64_t total_leap_days(int64_t p_year) {
|
||||||
|
if (p_year > 0) {
|
||||||
|
--p_year;
|
||||||
|
return 1 + (p_year / 4 - p_year / 100 + p_year / 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
return p_year / 4 - p_year / 100 + p_year / 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr int64_t year_to_days(int64_t p_year) {
|
||||||
|
return p_year * 365 + total_leap_days(p_year);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr int64_t days_to_year(int64_t p_days) {
|
||||||
|
int64_t year = 400 * p_days / year_to_days(400);
|
||||||
|
if (year < 0) {
|
||||||
|
--year;
|
||||||
|
}
|
||||||
|
if (year_to_days(year) > p_days) {
|
||||||
|
--year;
|
||||||
|
}
|
||||||
|
if (year_to_days(year + 1) <= p_days) {
|
||||||
|
++year;
|
||||||
|
}
|
||||||
|
return year;
|
||||||
|
}
|
||||||
|
|
||||||
#define YEAR_KEY "year"
|
#define YEAR_KEY "year"
|
||||||
#define MONTH_KEY "month"
|
#define MONTH_KEY "month"
|
||||||
#define DAY_KEY "day"
|
#define DAY_KEY "day"
|
||||||
@@ -72,16 +99,10 @@ static const uint8_t MONTH_DAYS_TABLE[2][12] = {
|
|||||||
int64_t day_number = Math::floor(p_unix_time_val / (double)SECONDS_PER_DAY); \
|
int64_t day_number = Math::floor(p_unix_time_val / (double)SECONDS_PER_DAY); \
|
||||||
{ \
|
{ \
|
||||||
int64_t day_number_copy = day_number; \
|
int64_t day_number_copy = day_number; \
|
||||||
year = UNIX_EPOCH_YEAR_AD; \
|
day_number_copy += year_to_days(UNIX_EPOCH_YEAR_AD); \
|
||||||
|
year = days_to_year(day_number_copy); \
|
||||||
|
day_number_copy -= year_to_days(year); \
|
||||||
uint8_t month_zero_index = 0; \
|
uint8_t month_zero_index = 0; \
|
||||||
while (day_number_copy >= YEAR_SIZE(year)) { \
|
|
||||||
day_number_copy -= YEAR_SIZE(year); \
|
|
||||||
year++; \
|
|
||||||
} \
|
|
||||||
while (day_number_copy < 0) { \
|
|
||||||
year--; \
|
|
||||||
day_number_copy += YEAR_SIZE(year); \
|
|
||||||
} \
|
|
||||||
/* After the above, day_number now represents the day of the year (0-index). */ \
|
/* After the above, day_number now represents the day of the year (0-index). */ \
|
||||||
while (day_number_copy >= MONTH_DAYS_TABLE[IS_LEAP_YEAR(year)][month_zero_index]) { \
|
while (day_number_copy >= MONTH_DAYS_TABLE[IS_LEAP_YEAR(year)][month_zero_index]) { \
|
||||||
day_number_copy -= MONTH_DAYS_TABLE[IS_LEAP_YEAR(year)][month_zero_index]; \
|
day_number_copy -= MONTH_DAYS_TABLE[IS_LEAP_YEAR(year)][month_zero_index]; \
|
||||||
@@ -116,15 +137,8 @@ static const uint8_t MONTH_DAYS_TABLE[2][12] = {
|
|||||||
day_number += MONTH_DAYS_TABLE[IS_LEAP_YEAR(year)][i]; \
|
day_number += MONTH_DAYS_TABLE[IS_LEAP_YEAR(year)][i]; \
|
||||||
} \
|
} \
|
||||||
/* Add the days in the years to day_number. */ \
|
/* Add the days in the years to day_number. */ \
|
||||||
if (year >= UNIX_EPOCH_YEAR_AD) { \
|
day_number += year_to_days(year); \
|
||||||
for (int64_t iyear = UNIX_EPOCH_YEAR_AD; iyear < year; iyear++) { \
|
day_number -= year_to_days(UNIX_EPOCH_YEAR_AD);
|
||||||
day_number += YEAR_SIZE(iyear); \
|
|
||||||
} \
|
|
||||||
} else { \
|
|
||||||
for (int64_t iyear = UNIX_EPOCH_YEAR_AD - 1; iyear >= year; iyear--) { \
|
|
||||||
day_number -= YEAR_SIZE(iyear); \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define PARSE_ISO8601_STRING(ret) \
|
#define PARSE_ISO8601_STRING(ret) \
|
||||||
int64_t year = UNIX_EPOCH_YEAR_AD; \
|
int64_t year = UNIX_EPOCH_YEAR_AD; \
|
||||||
|
|||||||
Reference in New Issue
Block a user