| Summary: | Sunset & sunrise times are crazy in UK | ||
|---|---|---|---|
| Product: | [Unmaintained] kweather-kde3 | Reporter: | Francois C. <belgix_oz> |
| Component: | general | Assignee: | geiseri |
| Status: | RESOLVED FIXED | ||
| Severity: | normal | ||
| Priority: | NOR | ||
| Version First Reported In: | unspecified | ||
| Target Milestone: | --- | ||
| Platform: | openSUSE | ||
| OS: | Linux | ||
| Latest Commit: | Version Fixed/Implemented In: | ||
| Sentry Crash Report: | |||
|
Description
Francois C.
2005-09-26 06:54:40 UTC
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;
}
|