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