File indexing completed on 2024-04-21 16:17:50

0001 /*
0002     KSysGuard, the KDE System Guard
0003 
0004     SPDX-FileCopyrightText: 2014 Gregor Mi <codestruct@posteo.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 
0008 */
0009 
0010 #ifndef TIMEUTIL_H
0011 #define TIMEUTIL_H
0012 
0013 #include <cmath> // floor
0014 
0015 #ifdef Q_OS_OSX
0016 #include <mach/clock.h>
0017 #include <mach/mach.h>
0018 #else
0019 #include <time.h>
0020 #endif
0021 
0022 #include <QDateTime>
0023 
0024 #include <klocalizedstring.h> // KF5::I18n
0025 
0026 class TimeUtil
0027 {
0028 public:
0029     /**
0030      * @Returns the amount of seconds passed since the system was booted
0031      */
0032     static long systemUptimeSeconds()
0033     {
0034 #ifdef Q_OS_OSX
0035         clock_serv_t cclock;
0036         mach_timespec_t tp;
0037 
0038         host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
0039         clock_get_time(cclock, &tp);
0040         mach_port_deallocate(mach_task_self(), cclock);
0041 #else
0042         timespec tp;
0043 #ifdef Q_OS_LINUX
0044         int isSuccess = clock_gettime(CLOCK_BOOTTIME, &tp);
0045         // _MONOTONIC doesn't increase while the system is suspended,
0046         // resulting in process start times in the future
0047 #else
0048         int isSuccess =
0049             clock_gettime(CLOCK_MONOTONIC, &tp); // see https://stackoverflow.com/questions/8357073/get-uptime-in-seconds-or-miliseconds-on-unix-like-systems
0050 #endif
0051         Q_ASSERT(isSuccess == 0);
0052 #endif
0053         return tp.tv_sec;
0054     }
0055 
0056     /**
0057      * @Returns the point in time when the system was booted
0058      */
0059     static QDateTime systemUptimeAbsolute()
0060     {
0061         auto now = QDateTime::currentDateTime();
0062         return now.addSecs(-systemUptimeSeconds());
0063     }
0064 
0065     /**
0066      * Converts the given @param seconds into a human readable string.
0067      * It represents an elapsed time span, e.g. "3m 50s ago".
0068      */
0069     static QString secondsToHumanElapsedString(long seconds)
0070     {
0071         const int s_abs = seconds;
0072         const int m_abs = floor(seconds / 60.0);
0073         const int h_abs = floor(seconds / 60.0 / 60.0);
0074         const int d_abs = floor(seconds / 60.0 / 60.0 / 24.0);
0075 
0076         if (m_abs == 0) {
0077             return i18nc("contains a abbreviated time unit: (s)econds", "%1s ago", s_abs);
0078         } else if (h_abs == 0) {
0079             const int s = s_abs - m_abs * 60;
0080             return i18nc("contains abbreviated time units: (m)inutes and (s)econds", "%1m %2s ago", m_abs, s);
0081         } else if (d_abs == 0) {
0082             const int s = s_abs - m_abs * 60;
0083             const int m = m_abs - h_abs * 60;
0084             return i18nc("contains abbreviated time units: (h)ours, (m)inutes and (s)econds)", "%1h %2m %3s ago", h_abs, m, s);
0085         } else { // d_abs > 0
0086             const int m = m_abs - h_abs * 60;
0087             const int h = h_abs - d_abs * 24;
0088             return i18ncp("contains also abbreviated time units: (h)ours and (m)inutes", "%1 day %2h %3m ago", "%1 days %2h %3m ago", d_abs, h, m);
0089         }
0090     }
0091 };
0092 
0093 #endif