Mailing List archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[vdr] Re: this weekend must be daylight savings in the US
I made a patch to handle the dst -> standard time magic hour the best
possible way. Patch is at the end of this message, and I try to see what
each case listed in Oliver's email does with this patch. The algorithm in
the patch to find a good guess on the correct utc time from local time is
somewhat tested, but I have not yet tested the full patch. I hope people
create many funny timers for next sunday and see if this works.. :-) Note
that the magic hour is 03:00 - 03:59 in TZ=Europe/Helsinki, 02:00 - 02:59
in TZ=Europe/Berlin and 01:00 - 01:59 in TZ=Europe/London.
The patch makes two guesses of the correct utc time and then chooses the
first one if it is a timer start time, and later one if it is the end
moment. This way always at least enough is recorded.
Patch also available at http://www.iki.fi/hyvatti/dvb/ .
On Tue, 21 Oct 2003, Oliver Endriss wrote:
> You might experience some strange effects if a timer spans this hour.
> 1st example:
> - timer start 02:45 CEST
> - timer stop 03:15 CET
>
> You'd like to have a 90 min recording, but you will get a 45 min
> partial recording with a *gap* from 02:00 CET to 02:45 CET.
> vdr does the following:
> - starts recording at 02:45 CEST
> - stops recording at 02:00 CET
> - starts recording at 02:45 CET
> - stops recording at 03:15 CET
> This happens because the local clock jumps back
> from 02:59 CEST to 02:00 CET.
This should result in 90 minutes, as 02:45 is a timer start time, and it
is resolved to either 00:45 UTC or 01:45 UTC, and the former is selected,
and 03:15 is resolved to 02:15 UTC.
> Last year I posted a patch which will prevent a started timer from
> stopping before the stop time has been reached.
> But this would only fix this kind of problem.
>
> 2nd example:
> - timer start 02:15 CEST
> - timer stop 02:45 CET
>
> You'd like to have a 90 min recording, but you will get only the first
> 30 minutes:
> - vdr starts recording at 02:15 CEST
> - vdr stops recording at 02:45 CEST
This should result in 90 minutes also, as as 02:15 is a timer start
time, and it is resolved to either 00:15 UTC or 01:15 UTC, the former is
selected, and for 02:45 the alternatives are 00:45 and 01:45, and the
later is selected.
--- old/vdr-1.2.6pre2/timers.c Sun Oct 12 13:33:09 2003
+++ vdr-1.2.6pre2/timers.c Wed Oct 22 14:38:41 2003
@@ -270,15 +270,46 @@
return mktime(&tm); // calculate final result
}
-time_t cTimer::SetTime(time_t t, int SecondsFromMidnight)
+time_t cTimer::SetTime(time_t t, int SecondsFromMidnight, bool chooselater)
{
- struct tm tm_r;
+ struct tm tm_r, t2;
+ time_t res1, res2;
tm tm = *localtime_r(&t, &tm_r);
tm.tm_hour = SecondsFromMidnight / 3600;
tm.tm_min = (SecondsFromMidnight % 3600) / 60;
tm.tm_sec = SecondsFromMidnight % 60;
tm.tm_isdst = -1; // makes sure mktime() will determine the correct DST setting
- return mktime(&tm);
+ res1 = mktime(&tm);
+
+ // We have the first guess for utc time for this localtime in res1
+ // now. If we are at the magic hour at the end of October when
+ // local time clocks are turned one hour backwards to end the
+ // daylight saving time, we might have alternative interpretation
+ // for that local time.
+
+ t2 = tm_r;
+ t2.tm_isdst = 1 - t2.tm_isdst;
+ res2 = mktime(&t2);
+
+ // That was the alternate utc time candidate, now see what is it in
+ // local time.
+
+ localtime_r (&res2, &t2);
+
+ // Are the local times identical, but with different isdst?
+ // If yes, check which utc timestamp needs to be returned
+ // - earlier or later timestamp.
+
+ if (tm_r.tm_sec == t2.tm_sec
+ && tm_r.tm_min == t2.tm_min
+ && tm_r.tm_hour == t2.tm_hour
+ && tm_r.tm_mday == t2.tm_mday
+ && tm_r.tm_mon == t2.tm_mon
+ && tm_r.tm_year == t2.tm_year
+ && (chooselater && res2 > res1
+ || !chooselater && res2 < res1))
+ return res2;
+ return res1;
}
char *cTimer::SetFile(const char *File)
@@ -295,16 +326,16 @@
t = time(NULL);
int begin = TimeToInt(start); // seconds from midnight
- int length = TimeToInt(stop) - begin;
- if (length < 0)
- length += SECSINDAY;
+ int end = TimeToInt(stop);
int DaysToCheck = IsSingleEvent() ? 61 : 7; // 61 to handle months with 31/30/31
for (int i = -1; i <= DaysToCheck; i++) {
time_t t0 = IncDay(t, i);
if (DayMatches(t0)) {
- time_t a = SetTime(t0, begin);
- time_t b = a + length;
+ time_t a = SetTime(t0, begin, false);
+ time_t b = SetTime(t0, end, true);
+ if (b < a)
+ b = SetTime(t0, end + SECSINDAY, true);
if ((!firstday || a >= firstday) && t <= b) {
startTime = a;
stopTime = b;
@@ -351,7 +382,7 @@
void cTimer::Skip(void)
{
- firstday = IncDay(SetTime(StartTime(), 0), 1);
+ firstday = IncDay(SetTime(StartTime(), 0, false), 1);
}
void cTimer::OnOff(void)
--- old/vdr-1.2.6pre2/menu.c Fri Oct 3 17:36:20 2003
+++ vdr-1.2.6pre2/menu.c Wed Oct 22 14:36:38 2003
@@ -255,7 +255,7 @@
}
else if (NORMALKEY(Key) == kRight) {
if (!*value)
- *value = cTimer::SetTime(time(NULL), 0);
+ *value = cTimer::SetTime(time(NULL), 0, false);
*value += SECSINDAY;
}
else
--
Foreca Ltd Jaakko.Hyvatti@foreca.com
Pursimiehenkatu 29-31 B, FIN-00150 Helsinki, Finland http://www.foreca.com
--
Info:
To unsubscribe send a mail to ecartis@linuxtv.org with "unsubscribe vdr" as subject.
Home |
Main Index |
Thread Index