Version: 2.1.0 (using KDE KDE 3.5.5) Installed from: Compiled From Sources Compiler: gcc (GCC) 4.0.2 OS: Linux The calculation of sunrise and sunset does not take into account cases where the weather station is in another timezone, which may cause the day to overlap with midnight local time. In this case the time can become greater than 24.00, which setHMS doesn't like. The determination of night for displaying the icon also doesn't handle the case when the day overlaps with midnight correctly. Patch attached.
Created attachment 18263 [details] Patch that fixes the bug
SVN commit 616456 by mkoller: BUG: 136312 BUG: 129679 BUG: 115920 BUG: 113339 BUG: 87642 Fix the calculation of sunrise/sunset and the calculation of isNight. Patch provided by J.O. Aho M +18 -1 metar_parser.cpp M +26 -4 sun.cpp --- branches/KDE/3.5/kdetoys/kweather/metar_parser.cpp #616455:616456 @@ -411,6 +411,8 @@ { #define E(t) ::pow(10, 7.5*t/(237.7+t)) float fRelHumidity = E(weatherInfo.dewC)/E(weatherInfo.tempC) * 100; + if (fRelHumidity > 100.0) fRelHumidity = 100.0; + weatherInfo.qsRelHumidity.sprintf("%.1f", fRelHumidity); removeTrailingDotZero(weatherInfo.qsRelHumidity); weatherInfo.qsRelHumidity += "%"; @@ -841,7 +843,22 @@ longitude << " " << civilStart << " " << civilEnd << " " << m_localUTCOffset << endl; - return (currently < civilStart || currently > civilEnd); + if (civilStart != civilEnd) + { + if (civilEnd < civilStart) + /* Handle daylight past midnight in local time */ + /* for weather stations located at other timezones */ + return (currently < civilStart && currently > civilEnd); + else + return (currently < civilStart || currently > civilEnd); + } + else + { + // Midnight Sun & Polar Night - In summer, the Sun is always + // over the horizon line ... so use latitude & today date to + // set isNight() value. + return ((m_date.daysInYear() >= 80 || m_date.daysInYear() <= 264) && latitude.contains("S")); + } } } --- branches/KDE/3.5/kdetoys/kweather/sun.cpp #616455:616456 @@ -204,20 +204,42 @@ QTime result; // Example: say time is 17.7543 Then hours = 17 and minutes = 0.7543 * 60 = 45.258 + // We need to convert the time to CORRECT local hours int hours = (int)floor(time); + int localhours = hours + (m_localUTCOffset / 60); + + // We need to convert the time to CORRECT local minutes int minutes = (int)floor((time - hours) * 60); + int localminutes = minutes + (m_localUTCOffset % 60); - int localhours = hours + (m_localUTCOffset / 60); - if (localhours < 0) { localhours += 24; } - if (localhours >= 24) { localhours -= 24; } + // We now have to adjust the time to be within the 60m boundary + if (localminutes < 0) + { + //As minutes is less than 0, we need to + //reduce a hour and add 60m to minutes. + localminutes += 60; + localhours--; + } + if (localminutes >= 60) + { + //As minutes are more than 60, we need to + //add one more hour and reduce the minutes to + //a value between 0 and 59. + localminutes -= 60; + localhours++; + } // Round up or down to nearest second. // Use rint instead of nearbyint because rint is in FreeBSD int seconds = (int)rint( fabs( minutes - ((time - hours) * 60) ) * 60 ); + // We now have to adjust the time to be within the 24h boundary + if (localhours < 0) { localhours += 24; } + if (localhours >= 24) { localhours -= 24; } + // Try to set the hours, minutes and seconds for the local time. // If this doesn't work, then we will return the invalid time. - result.setHMS( localhours, minutes + (m_localUTCOffset % 60), seconds ); + result.setHMS( localhours, localminutes, seconds ); return result; }