app/core/ProcessTimeZone.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <QByteArray> | ||
| 4 | #include <QObject> | ||
| 5 | #include <QString> | ||
| 6 | #include <QTimer> | ||
| 7 | #include <functional> | ||
| 8 | |||
| 9 | // Sprint 93 G9 (CAL-PERF-YEAR): local-time conversions without TZ. | ||
| 10 | // | ||
| 11 | // With TZ unset, glibc re-reads /etc/localtime on every local-time | ||
| 12 | // conversion; Qt converts through it for every floating appointment, mail | ||
| 13 | // date and display time. Measured on a Fedora desktop (Europe/Berlin) the | ||
| 14 | // calendar period load takes 2–2.8x as long as with TZ set (year 10k: | ||
| 15 | // 101.6 → 41.2 ms median). pin() therefore sets TZ to the system zone's | ||
| 16 | // IANA id at start when the user has not set TZ. Because a pinned TZ no | ||
| 17 | // longer follows a system zone change (travel, timedatectl), the watcher | ||
| 18 | // compares the /etc/localtime link every minute and re-pins on a change. | ||
| 19 | namespace ProcessTimeZone { | ||
| 20 | |||
| 21 | // The IANA id /etc/localtime (or `linkTarget`) points to; "" when it is no | ||
| 22 | // link into a zoneinfo directory. | ||
| 23 | QByteArray zoneIdFromLink(const QString &linkTarget); | ||
| 24 | QByteArray systemZoneIdFromLink(); | ||
| 25 | // Call first in main(), before any time conversion. Returns whether TZ was | ||
| 26 | // pinned (false: TZ already set by the user, or no usable zone id). | ||
| 27 | bool pin(); | ||
| 28 | // Writes what pin() did; call after the log rules are applied (F100-26). | ||
| 29 | void logPinResult(); | ||
| 30 | // True when pin() set TZ (the watcher then keeps it current). | ||
| 31 | bool pinned(); | ||
| 32 | |||
| 33 | } // namespace ProcessTimeZone | ||
| 34 | |||
| 35 | class ProcessTimeZoneWatcher final : public QObject { | ||
| 36 | Q_OBJECT | ||
| 37 | public: | ||
| 38 | explicit ProcessTimeZoneWatcher(QObject *parent = nullptr); | ||
| 39 | // For tests: the link target read instead of /etc/localtime. | ||
| 40 | 1 | void setLinkReader(std::function<QString()> reader) { m_reader = std::move(reader); } | |
| 41 | // Re-reads the link; re-pins TZ and emits changed() when the zone moved. | ||
| 42 | void check(); | ||
| 43 | |||
| 44 | signals: | ||
| 45 | void changed(const QByteArray &zoneId); | ||
| 46 | |||
| 47 | private: | ||
| 48 | QTimer m_timer; | ||
| 49 | QByteArray m_zone; | ||
| 50 | std::function<QString()> m_reader; | ||
| 51 | }; | ||
| 52 |