• Re: New clock !

    From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++ on Fri Oct 10 03:26:14 2025
    From Newsgroup: comp.lang.c++

    This is the current code to convert a time_point with 100ns-ticks
    since 1.1.1601 00:00:00.0 to a date in Gregorian or Julian calendar.

    template<bool Gregorian>
    void date_1601<Gregorian>::from_time_point( time_point timePoint ) noexcept
    {
    uint64_t tsCalc = timePoint.time_since_epoch().count();
    bool leapYear = false;
    constexpr int64_t Y4S = FOUR_YEARS_W_LY;
    int y400 = 0, y100 = 0, y4, yMod4, patch = 0;
    bool leapQuad = true;
    if constexpr( Gregorian )
    {
    constexpr int64_t Y400S = FOUR_HUNDRED_YEARS;
    if( (int64_t)tsCalc >= -(int64_t)LEAP_YEAR )
    {
    if( (int64_t)(tsCalc + LEAP_YEAR) < (int64_t)tsCalc )
    {
    tsCalc -= FOUR_HUNDRED_YEARS;
    patch = 400;
    }
    tsCalc += LEAP_YEAR;
    y400 += (int)(tsCalc / FOUR_HUNDRED_YEARS);
    }
    else
    {
    tsCalc += LEAP_YEAR;
    if( (int64_t)tsCalc <= -Y400S )
    {
    tsCalc += FOUR_HUNDRED_YEARS;
    patch = -400;
    }
    y400 += (int)((int64_t)(tsCalc - (Y400S - 1)) / Y400S);
    }
    tsCalc -= y400 * Y400S;
    if( tsCalc >= FIRST_CENTURY )
    {
    y100 = (int)((tsCalc - FIRST_CENTURY) / REMAINING_CENUTRIES); // 0 ... 2
    tsCalc -= FIRST_CENTURY + y100++ * REMAINING_CENUTRIES; // -> 1 ... 3
    if( tsCalc >= FOUR_YEARS_WO_LY )
    {
    y4 = (int)((tsCalc - FOUR_YEARS_WO_LY) / FOUR_YEARS_W_LY); // 0 ... 23
    tsCalc -= FOUR_YEARS_WO_LY + y4++ * FOUR_YEARS_W_LY; // -> 1 ... 24
    }
    else
    {
    y4 = 0;
    yMod4 = (int)(tsCalc / NON_LEAP_YEAR);
    tsCalc -= yMod4 * NON_LEAP_YEAR;
    leapQuad = false;
    }
    }
    else
    {
    y100 = 0;
    y4 = (int)(tsCalc / FOUR_YEARS_W_LY);
    tsCalc -= y4 * FOUR_YEARS_W_LY;
    }
    }
    else
    {
    if( (int64_t)tsCalc >= -(int64_t)JULIAN_ZERO_1600 )
    {
    if( (int64_t)(tsCalc + JULIAN_ZERO_1600) < (int64_t)tsCalc )
    {
    tsCalc -= FOUR_YEARS_W_LY;
    patch = 4;
    }
    tsCalc += JULIAN_ZERO_1600;
    y4 = (int)(tsCalc / FOUR_YEARS_W_LY);
    }
    else
    {
    tsCalc += JULIAN_ZERO_1600;
    if( (int64_t)tsCalc <= -Y4S )
    {
    tsCalc += FOUR_YEARS_W_LY;
    patch = -4;
    }
    y4 = (int)((int64_t)(tsCalc - (Y4S - 1)) / Y4S);
    }
    tsCalc -= y4 * Y4S;
    }
    if( leapQuad )
    if( leapYear = tsCalc < LEAP_YEAR; !leapYear )
    {
    tsCalc -= LEAP_YEAR;
    yMod4 = (int)(tsCalc / NON_LEAP_YEAR); // 0 ... 2
    tsCalc -= yMod4++ * NON_LEAP_YEAR; // -> 1 ... 3
    }
    else
    yMod4 = 0;
    year = (int16_t)(1600 + 400 * y400 + 100 * y100 + 4 * y4 + yMod4 + patch);
    {
    uint16_t yDay = (uint16_t)(tsCalc / DAY);
    tsCalc %= DAY;
    span dualDaysAfterYear( g_daysAfterYear );
    span daysAfterYear( dualDaysAfterYear[leapYear] );
    month = 0;
    for( ; yDay >= daysAfterYear[month + 1]; ++month );
    assert(month < 12);
    day = yDay - daysAfterYear[month] + 1;
    ++month;
    }
    hour = (uint8_t)(tsCalc / HOUR);
    tsCalc %= HOUR;
    minute = (uint8_t)(tsCalc / MINUTE);
    tsCalc %= MINUTE;
    second = (uint8_t)((uint32_t)tsCalc / (uint32_t)SECOND);
    ticks = (uint32_t)tsCalc % (uint32_t)SECOND;
    weekday = get_weekday( timePoint );
    }
    --- Synchronet 3.21a-Linux NewsLink 1.2