@@ -31,20 +31,25 @@ void SystemClock::setPrecision(SystemClock::Enum precision) {
3131}
3232
3333void SystemClock::onTimeout () {
34- this ->setTime (this ->nextTime );
35- this ->schedule (this ->nextTime );
34+ this ->setTime (this ->targetTime );
35+ this ->schedule (this ->targetTime );
3636}
3737
3838void SystemClock::update () {
3939 if (this ->mEnabled ) {
40- this ->setTime (QTime::currentTime ( ));
41- this ->schedule (QTime::currentTime ( ));
40+ this ->setTime (QDateTime::fromMSecsSinceEpoch ( 0 ));
41+ this ->schedule (QDateTime::fromMSecsSinceEpoch ( 0 ));
4242 } else {
4343 this ->timer .stop ();
4444 }
4545}
4646
47- void SystemClock::setTime (QTime time) {
47+ void SystemClock::setTime (const QDateTime& targetTime) {
48+ auto currentTime = QDateTime::currentDateTime ();
49+ auto offset = currentTime.msecsTo (targetTime);
50+ auto dtime = offset > -500 && offset < 500 ? targetTime : currentTime;
51+ auto time = dtime.time ();
52+
4853 auto secondPrecision = this ->mPrecision >= SystemClock::Seconds;
4954 auto secondChanged = this ->setSeconds (secondPrecision ? time.second () : 0 );
5055
@@ -57,34 +62,33 @@ void SystemClock::setTime(QTime time) {
5762 DropEmitter::call (secondChanged, minuteChanged, hourChanged);
5863}
5964
60- void SystemClock::schedule (QTime floor ) {
65+ void SystemClock::schedule (const QDateTime& targetTime ) {
6166 auto secondPrecision = this ->mPrecision >= SystemClock::Seconds;
6267 auto minutePrecision = this ->mPrecision >= SystemClock::Minutes;
6368 auto hourPrecision = this ->mPrecision >= SystemClock::Hours;
6469
65- setnext:
66- auto nextTime = QTime (
67- hourPrecision ? floor.hour () : 0 ,
68- minutePrecision ? floor.minute () : 0 ,
69- secondPrecision ? floor.second () : 0
70+ auto currentTime = QDateTime::currentDateTime ();
71+
72+ auto offset = currentTime.msecsTo (targetTime);
73+
74+ // timer skew
75+ auto nextTime = offset > 0 && offset < 500 ? targetTime : currentTime;
76+
77+ auto baseTimeT = nextTime.time ();
78+ nextTime.setTime (
79+ {hourPrecision ? baseTimeT.hour () : 0 ,
80+ minutePrecision ? baseTimeT.minute () : 0 ,
81+ secondPrecision ? baseTimeT.second () : 0 }
7082 );
7183
7284 if (secondPrecision) nextTime = nextTime.addSecs (1 );
7385 else if (minutePrecision) nextTime = nextTime.addSecs (60 );
7486 else if (hourPrecision) nextTime = nextTime.addSecs (3600 );
7587
76- auto delay = QTime::currentTime ().msecsTo (nextTime);
77-
78- // If off by more than 2 hours we likely wrapped around midnight.
79- if (delay < -7200000 ) delay += 86400000 ;
80- else if (delay < 0 ) {
81- // Otherwise its just the timer being unstable.
82- floor = QTime::currentTime ();
83- goto setnext;
84- }
88+ auto delay = currentTime.msecsTo (nextTime);
8589
86- this ->timer .start (delay);
87- this ->nextTime = nextTime;
90+ this ->timer .start (static_cast <qint32>( delay) );
91+ this ->targetTime = nextTime;
8892}
8993
9094DEFINE_MEMBER_GETSET (SystemClock, hours, setHours);
0 commit comments