@@ -1448,9 +1448,95 @@ void KeQuerySystemTime(be<uint64_t>* time)
14481448 *time = currentTime100ns;
14491449}
14501450
1451- void RtlTimeToTimeFields ()
1451+ struct TIME_FIELDS {
1452+ be<uint16_t > Year;
1453+ be<uint16_t > Month;
1454+ be<uint16_t > Day;
1455+ be<uint16_t > Hour;
1456+ be<uint16_t > Minute;
1457+ be<uint16_t > Second;
1458+ be<uint16_t > Milliseconds;
1459+ be<uint16_t > Weekday;
1460+ };
1461+
1462+ void RtlTimeToTimeFields (const be<uint64_t >* time, TIME_FIELDS * timeFields)
14521463{
1453- LOG_UTILITY (" !!! STUB !!!" );
1464+ constexpr uint64_t TICKS_PER_MILLISECOND = 10000 ;
1465+ constexpr uint64_t TICKS_PER_SECOND = 10000000 ;
1466+ constexpr uint64_t TICKS_PER_MINUTE = 600000000 ;
1467+ constexpr uint64_t TICKS_PER_HOUR = 36000000000 ;
1468+ constexpr uint64_t TICKS_PER_DAY = 864000000000 ;
1469+
1470+ static const int DaysInMonth[2 ][12 ] = {
1471+ {31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 }, // Non-leap
1472+ {31 , 29 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 } // Leap
1473+ };
1474+
1475+ // Calculate total days since January 1, 1601
1476+ uint64_t days = *time / TICKS_PER_DAY ;
1477+ uint64_t remainingTicks = *time % TICKS_PER_DAY ;
1478+
1479+ timeFields->Hour = static_cast <uint16_t >(remainingTicks / TICKS_PER_HOUR );
1480+ remainingTicks %= TICKS_PER_HOUR ;
1481+
1482+ timeFields->Minute = static_cast <uint16_t >(remainingTicks / TICKS_PER_MINUTE );
1483+ remainingTicks %= TICKS_PER_MINUTE ;
1484+
1485+ timeFields->Second = static_cast <uint16_t >(remainingTicks / TICKS_PER_SECOND );
1486+ remainingTicks %= TICKS_PER_SECOND ;
1487+
1488+ timeFields->Milliseconds = static_cast <uint16_t >(remainingTicks / TICKS_PER_MILLISECOND );
1489+
1490+ // Calculate day of week (January 1, 1601 was a Monday = 1)
1491+ timeFields->Weekday = static_cast <uint16_t >((days + 1 ) % 7 );
1492+
1493+ // Calculate year
1494+ uint32_t year = 1601 ;
1495+
1496+ // Each 400-year cycle has 146097 days
1497+ uint32_t cycles400 = static_cast <uint32_t >(days / 146097 );
1498+ days %= 146097 ;
1499+ year += cycles400 * 400 ;
1500+
1501+ // Handle 100-year cycles (24 leap years + 76 normal years = 36524 days)
1502+ // Except the 4th century which has 36525 days
1503+ uint32_t cycles100 = static_cast <uint32_t >(days / 36524 );
1504+ if (cycles100 == 4 ) cycles100 = 3 ; // Last day of 400-year cycle
1505+ days -= cycles100 * 36524 ;
1506+ year += cycles100 * 100 ;
1507+
1508+ // Handle 4-year cycles (1 leap year + 3 normal years = 1461 days)
1509+ uint32_t cycles4 = static_cast <uint32_t >(days / 1461 );
1510+ days %= 1461 ;
1511+ year += cycles4 * 4 ;
1512+
1513+ // Handle individual years within 4-year cycle
1514+ uint32_t yearInCycle = static_cast <uint32_t >(days / 365 );
1515+ if (yearInCycle == 4 ) yearInCycle = 3 ; // Last day of leap cycle
1516+ days -= yearInCycle * 365 ;
1517+ if (yearInCycle > 0 ) {
1518+ // Account for leap days in previous years of this cycle
1519+ days -= (yearInCycle - 1 ) / 4 ;
1520+ }
1521+ year += yearInCycle;
1522+
1523+ timeFields->Year = static_cast <uint16_t >(year);
1524+
1525+ // Determine if current year is a leap year
1526+ bool isLeapYear = ((year % 4 == 0 ) && (year % 100 != 0 )) || (year % 400 == 0 );
1527+
1528+ // Calculate month and day
1529+ const int * monthDays = DaysInMonth[isLeapYear ? 1 : 0 ];
1530+ uint32_t dayOfYear = static_cast <uint32_t >(days) + 1 ; // Convert to 1-based
1531+
1532+ uint16_t month = 1 ;
1533+ while (dayOfYear > static_cast <uint32_t >(monthDays[month - 1 ])) {
1534+ dayOfYear -= monthDays[month - 1 ];
1535+ month++;
1536+ }
1537+
1538+ timeFields->Month = month;
1539+ timeFields->Day = static_cast <uint16_t >(dayOfYear);
14541540}
14551541
14561542void RtlFreeAnsiString ()
0 commit comments