#include "Chrono.hpp" #include #include #include Chrono::Chrono(QObject* parent): QObject(parent) { QObject::connect(&this->timer, &QTimer::timeout, this, &Chrono::onTimeout); this->update(); } bool Chrono::enabled() const { return this->mEnabled; } void Chrono::setEnabled(bool enabled) { if (enabled == this->mEnabled) return; this->mEnabled = enabled; emit this->enabledChanged(); this->update(); } Chrono::Precision Chrono::precision() const { return this->mPrecision; } void Chrono::setPrecision(Chrono::Precision precision) { if (precision == this->mPrecision) return; this->mPrecision = precision; emit this->precisionChanged(); this->update(); } void Chrono::onTimeout() { this->setTime(this->targetTime); this->schedule(this->targetTime); } void Chrono::update() { if (this->mEnabled) { this->setTime(std::chrono::time_point()); this->schedule(std::chrono::time_point()); } else { this->timer.stop(); } } void Chrono::setTime(const std::chrono::time_point& targetTime) { auto currentTime = std::chrono::system_clock::now(); auto offset = std::chrono::duration_cast(targetTime - currentTime); this->currentTime = abs(offset.count()) < 500 ? targetTime : currentTime; switch (this->mPrecision) { case Chrono::Hours: this->currentTime = std::chrono::time_point_cast(this->currentTime); case Chrono::Minutes: this->currentTime = std::chrono::time_point_cast(this->currentTime); case Chrono::Seconds: this->currentTime = std::chrono::time_point_cast(this->currentTime); } emit this->dateChanged(); } void Chrono::schedule(const std::chrono::time_point& targetTime) { auto currentTime = std::chrono::system_clock::now(); auto offset = std::chrono::duration_cast(targetTime - currentTime); auto nextTime = abs(offset.count()) < 500 ? targetTime : currentTime; { using namespace std::chrono_literals; switch (this->mPrecision) { case Chrono::Hours: nextTime = std::chrono::time_point_cast(nextTime) + 1h; case Chrono::Minutes: nextTime = std::chrono::time_point_cast(nextTime) + 1min; case Chrono::Seconds: nextTime = std::chrono::time_point_cast(nextTime) + 1s; } } this->targetTime = nextTime; auto delay = std::chrono::duration_cast(nextTime - currentTime); this->timer.start(delay); } QString Chrono::format() const { return this->mFormat; } void Chrono::setFormat(QString format) { if (format == this->mFormat) return; this->mFormat = format; emit this->formatChanged(); this->update(); } QString Chrono::date() const { return QString::fromStdString(std::format(std::runtime_format(this->mFormat.toStdString()), std::chrono::zoned_time(std::chrono::current_zone(), std::chrono::time_point_cast(this->currentTime)))); }