Version: 2.1.0 (using KDE KDE 3.4.0) Installed from: SuSE RPMs Compiler: gcc-3.3.5 OS: Linux I first noticed this bug in kdetoys-3.4 package of Suse 9.3 but even if there is a lot of topics in this forum stated that this bug is fixed, I don't this so. Today, I compiled from sources kdetoys-3.4.2 using the KDE-3.4-devel files because KDE 3.4 is running on my box. Sunset et sunrise times of some cities in the UK are ... London,UK : SR=06:00 SS=19:00 Paris,FR : SR=06:00 SS=19:00 (strange) Glasgow,UK : SR=15:41 SS=19:00 (pretty dark over there) Edinburgh,UK : SR=15:36 SS=19:00 (not better than Glasgow) Where are live, times returned are better but not very accurate ... Adelaide,AU : SR=6:59 SS=19:00 According to weather.com the correct times should be ... London, UK : SR=6:53 SS=18:49 Paris, FR : SR=7:43 SS=19:38 Edinburgh, UK : SR=7:06 SS=19:01 Glasgow, UK : SR=7:11 SS=19:06 Adelaide, AU : SR=05:30 SS=17:45 This bug leads also to a mess up in icons displayed by the applet ...
Looks like your timezone setting is wrong.
Not logical because times displayed by Clock applet are all right. Local TimeZone : 2005/09/26 @ 16:22 America/Montreal : 2005/09/26 @ 02:52 Europe/London : 2005/09/26 @ 07:53 and belgix@edinburgh:~> date Mon Sep 26 16:26:13 CST 2005 Never mind, it really weird to have a sunset time difference of more than 9 hrs for 2 cities located 400 km apart (London vs Scotland). The only unusual thing for Linux system is ... I set the local time instead of UTC time on my laptop because I'm also running W2K in a virtual machine.
Problem found & it happens when the user's timezone is not divisible by 60 (i.e Adelaide, AU GMT+10.5 amd/or St-John, Newfoundland, CA GMT-4.5). In such case MyString.setHMS(hours, minutes, seconds) return an error if hours and/or minutes value(s) is invalid. How is it possible ? Case 1. Set UTC at 15:45. For Adelaide, we must add 10:30 to UTC time to get local time. Buzz. MyString.setHMS(25, 75, 0) return invalid value. Case 2. Set UTC at 12:00. For St-John, we must substract 4:30 to UTC time to get local time. Buzz again. MyString.setHMS(8, -30, 0) return invalid value too. I submitted a patch to Novell to fix this issue. More explanation take a look at https://bugzilla.novell.com/show_bug.cgi?id=160808 Please apply the patch submitted to SuSE to fix this issue for all distros.
Sorry for a stupid mistake with MetarParser::isNight() logic for Midnight Sun / Polar Night ... Take this patches instead. --- sun.cpp 2006-03-26 15:30:00.000000000 +0930 +++ kdetoys-3.5.1/kweather/sun.cpp 2006-03-26 08:39:39.000000000 +0930 @@ -12,6 +12,8 @@ Released to the public domain by Paul Schlyter, December 1992 Portions Modified to SUNDOWN.NLM by Cliff Haas 98-05-22 Converted to C++ and modified by John Ratke + Bugfix: Sun::convertDoubleToLocalTime() returning invalid values when + m_localUTCOffset is not divisible by 60 - Francois Chenier 06-03-25 ***************************************************************************/ @@ -199,10 +201,15 @@ } -QTime Sun::convertDoubleToLocalTime( const double time ) +QTime Sun::convertDoubleToLocalTime( const double UTCtime ) { QTime result; + // Converting to LocalTime after time is set in HMS format will lead to + // invalid time results when m_localUTCOffset is not divisible by 60. + double time = UTCtime + m_localUTCOffset / 60; + time += (time < 0) ? 24.0 : (time > 24) ? -24.0 : 0.0; + // Example: say time is 17.7543 Then hours = 17 and minutes = 0.7543 * 60 = 45.258 int hours = (int)floor(time); int minutes = (int)floor((time - hours) * 60); @@ -211,10 +218,8 @@ // Use rint instead of nearbyint because rint is in FreeBSD int seconds = (int)rint( fabs( minutes - ((time - hours) * 60) ) * 60 ); - // 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( hours + (m_localUTCOffset / 60), minutes + (m_localUTCOffset % 60), seconds ); - + // Invalid time should never happens now! + result.setHMS( hours, minutes, seconds ); return result; } --- metar_parser.cpp 2006-03-26 15:45:42.000000000 +0930 +++ kdetoys-3.5.1/kweather/metar_parser.cpp 2006-03-26 12:51:11.000000000 +0930 @@ -7,6 +7,11 @@ : (C) 2002-2004 Nadeem Hasan <nhasan@kde.org> : (C) 2002-2004 Ian Geiser <geiseri@kde.org> email : jratke@comcast.net +fixes : Relative humidity > than 100% <belgix@kern.com.au> + : IsNight() returning a wrong value when civilStart is + greater than civilEnd <belgix@kern.com.au> + : IsNight() returning a wrong value for people living + inside the polar circle area <belgix@kern.com.au> ***************************************************************************/ /*************************************************************************** @@ -411,6 +416,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 += "%"; @@ -830,18 +837,29 @@ else { Sun theSun( latitude, longitude , m_date, m_localUTCOffset ); QTime currently = m_time; QTime civilStart = theSun.computeCivilTwilightStart(); QTime civilEnd = theSun.computeCivilTwilightEnd(); kdDebug (12006) << "station, current, lat, lon, start, end, offset: " << upperStationID << " " << currently << " " << latitude << " " << longitude << " " << civilStart << " " << civilEnd << " " << m_localUTCOffset << endl; - return (currently < civilStart || currently > civilEnd); + if (civilStart != civilEnd) + if (civilStart < civilEnd) + // For people who lives on the eastern side of the Earth. + return (currently < civilStart || currently > civilEnd); + else + // For people who lives on the western side of the Earth. + 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")); } }
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; }