Repository: SerenityOS/serenity
File: AK/Time.h (C/C++)

Code before:
    constexpr u32 era_month_offset = 2;

    // Shift the epoch from 1970-01-01 to 0000-03-01.
    VERIFY(days <= NumericLimits<T>::max() - 719468);
    days += 719468;

    T era = (days >= 0 ? days : days - last_day_of_era) / era_days;
    u32 day_of_era = days - era * era_days;
    u32 year_of_era = (day_of_era - day_of_era / last_day_of_year_three + day_of_era / days_in_first_hundred_era_years - day_of_era / last_day_of_era) / 365;
    // The latter part of this comes from accounting for leap years (the year 400 need not be accounted for, because an era only has 400 years in total).
    u32 day_of_year_of_era = day_of_era - (365 * year_of_era + year_of_era / 4 - year_of_era / 100);
    // Starting from March 1st, not January 1st.
    u32 month_of_era = (5 * day_of_year_of_era + 2) / 153;
    u32 day = day_of_year_of_era - (153 * month_of_era + 2) / 5 + 1;
    u32 month = month_of_era < 10 ? month_of_era + 3 : month_of_era - 9;
    T year = (static_cast<T>(year_of_era) + era * 400) + (month <= era_month_offset);

    return { year, month, day };
}

template<typename T>
constexpr Tuple<T, u8, u8> seconds_since_epoch_to_date(T seconds)
{
    constexpr auto seconds_per_day = 60 * 60 * 24;
    T day_offset_to_epoch = seconds >= 0 ? seconds / seconds_per_day : floor_div(seconds, seconds_per_day);
    return days_since_epoch_to_date(day_offset_to_epoch);
}

// Represents a duration in a "safe" way.
// Minimum: -(2**63) seconds, 0 nanoseconds
// Maximum: 2**63-1 seconds, 999'999'999 nanoseconds
// If any operation (e.g. 'from_timeval' or operator-) would over- or underflow, the closest legal value is returned instead.
// Inputs (e.g. to 'from_timespec') are allowed to be in non-normal form (e.g. "1 second, 2'012'345'678 nanoseconds" or "1 second, -2 microseconds").
// Outputs (e.g. from 'to_timeval') are always in normal form.
//
// NOTE: This class is naive. It may represent either absolute offsets or relative durations. It does not have a reference point in itself,
//       and therefore comparing multiple instances of this class is only sensible if you are sure that their reference point is identical.
//       You should not be using this class directly to represent absolute time.
class Duration {
public:
    constexpr Duration() = default;
    constexpr Duration(Duration const&) = default;
    constexpr Duration& operator=(Duration const&) = default;

    constexpr Duration(Duration&& other)
        : m_seconds(exchange(other.m_seconds, 0))
        , m_nanoseconds(exchange(other.m_nanoseconds, 0))
    {
    }
    constexpr Duration& operator=(Duration&& other)
    {

Review comment (suggestion):
It seems like you're never using the other results, why not keeping `seconds_since_epoch_to_year` and returning `return days_since_epoch_to_date(day_offset_to_epoch)[0];` here?
That should make this commit a bit less invasive.

Code after:
    constexpr u32 era_month_offset = 2;

    // Shift the epoch from 1970-01-01 to 0000-03-01.
    VERIFY(days <= NumericLimits<T>::max() - 719468);
    days += 719468;

    T era = (days >= 0 ? days : days - last_day_of_era) / era_days;
    u32 day_of_era = days - era * era_days;
    u32 year_of_era = (day_of_era - day_of_era / last_day_of_year_three + day_of_era / days_in_first_hundred_era_years - day_of_era / last_day_of_era) / 365;
    // The latter part of this comes from accounting for leap years (the year 400 need not be accounted for, because an era only has 400 years in total).
    u32 day_of_year_of_era = day_of_era - (365 * year_of_era + year_of_era / 4 - year_of_era / 100);
    // Starting from March 1st, not January 1st.
    u32 month_of_era = (5 * day_of_year_of_era + 2) / 153;
    u32 day = day_of_year_of_era - (153 * month_of_era + 2) / 5 + 1;
    u32 month = month_of_era < 10 ? month_of_era + 3 : month_of_era - 9;
    T year = (static_cast<T>(year_of_era) + era * 400) + (month <= era_month_offset);

    return { year, month, day };
}

constexpr i64 seconds_since_epoch_to_year(i64 seconds)
{
    constexpr auto seconds_per_day = 60 * 60 * 24;
    i64 day_offset_to_epoch = seconds >= 0 ? seconds / seconds_per_day : floor_div(seconds, seconds_per_day);
    auto [year, month, day] = days_since_epoch_to_date(day_offset_to_epoch);
    return year;
}

// Represents a duration in a "safe" way.
// Minimum: -(2**63) seconds, 0 nanoseconds
// Maximum: 2**63-1 seconds, 999'999'999 nanoseconds
// If any operation (e.g. 'from_timeval' or operator-) would over- or underflow, the closest legal value is returned instead.
// Inputs (e.g. to 'from_timespec') are allowed to be in non-normal form (e.g. "1 second, 2'012'345'678 nanoseconds" or "1 second, -2 microseconds").
// Outputs (e.g. from 'to_timeval') are always in normal form.
//
// NOTE: This class is naive. It may represent either absolute offsets or relative durations. It does not have a reference point in itself,
//       and therefore comparing multiple instances of this class is only sensible if you are sure that their reference point is identical.
//       You should not be using this class directly to represent absolute time.
class Duration {
public:
    constexpr Duration() = default;
    constexpr Duration(Duration const&) = default;
    constexpr Duration& operator=(Duration const&) = default;

    constexpr Duration(Duration&& other)
        : m_seconds(exchange(other.m_seconds, 0))
        , m_nanoseconds(exchange(other.m_nanoseconds, 0))
    {
    }
    constexpr Duration& operator=(Duration&& other)
    {