DST fix: daylength v. DAYINSEC

The number of seconds in a day and daylength in seconds differ when
Daylight Saving Time is in effect on two days of the year. The day when DST
takes effect is 23 hours long, and the day when DST ends is 25 hours long.

In the latter case the date changing thread wóuld enter a loop in the last hour
before midnight (in the former it would set the date an hour too late).
The next midnight is calculated through mktime(), invoked by date2sec().

Wrong daylength prevented appointments from being stored in the day vector and
caused them to be displayed wrongly in the appts panel.

Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
This commit is contained in:
Lars Henriksen 2018-10-30 19:53:55 +01:00 committed by Lukas Fleischer
parent 4263a28504
commit e6cffdc6bd
4 changed files with 9 additions and 3 deletions

View File

@ -137,7 +137,7 @@ void apoint_sec2str(struct apoint *o, long day, char *start, char *end)
snprintf(start, HRMIN_SIZE, "%02u:%02u", lt.tm_hour, snprintf(start, HRMIN_SIZE, "%02u:%02u", lt.tm_hour,
lt.tm_min); lt.tm_min);
} }
if (o->start + o->dur > day + DAYINSEC) { if (o->start + o->dur > day + DAYLEN(day)) {
strncpy(end, "..:..", 6); strncpy(end, "..:..", 6);
} else { } else {
t = o->start + o->dur; t = o->start + o->dur;

View File

@ -144,7 +144,13 @@
#define WEEKINMIN (WEEKINHOURS * HOURINMIN) #define WEEKINMIN (WEEKINHOURS * HOURINMIN)
#define WEEKINSEC (WEEKINMIN * MININSEC) #define WEEKINSEC (WEEKINMIN * MININSEC)
#define DAYINMIN (DAYINHOURS * HOURINMIN) #define DAYINMIN (DAYINHOURS * HOURINMIN)
/*
* Note the difference between the number of seconds in a day and daylength
* in seconds. The two may differ when DST is in effect (daylength is either
* 23, 24 or 25 hours. The argument to DAYLEN is of type time_t.
*/
#define DAYINSEC (DAYINMIN * MININSEC) #define DAYINSEC (DAYINMIN * MININSEC)
#define DAYLEN(date) (date_sec_change((date), 0, 1) - (date))
#define HOURINSEC (HOURINMIN * MININSEC) #define HOURINSEC (HOURINMIN * MININSEC)
#define MAXDAYSPERMONTH 31 #define MAXDAYSPERMONTH 31

View File

@ -294,7 +294,7 @@ static int day_store_apoints(long date)
p.apt = apt; p.apt = apt;
if (apt->start >= date + DAYINSEC) if (apt->start >= date + DAYLEN(date))
break; break;
day_add_item(APPT, apt->start, p); day_add_item(APPT, apt->start, p);

View File

@ -97,7 +97,7 @@ static void *ui_calendar_date_thread(void *arg)
time_t actual, tomorrow; time_t actual, tomorrow;
for (;;) { for (;;) {
tomorrow = (time_t) (get_today() + DAYINSEC); tomorrow = date2sec(today, 24, 0);
while ((actual = time(NULL)) < tomorrow) while ((actual = time(NULL)) < tomorrow)
sleep(tomorrow - actual); sleep(tomorrow - actual);