aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFrederic Culot <calcurse@culot.org>2010-03-08 08:44:28 +0000
committerFrederic Culot <calcurse@culot.org>2010-03-08 08:44:28 +0000
commitb2321a7567340ff285cfcde5f9b4c7e60be7374d (patch)
tree877e48dbe6742358cf17f6037e127aa8563237ca /src
parent2ec8ab17accd8c34c180ccea34b9242f6b171d44 (diff)
downloadcalcurse-b2321a7567340ff285cfcde5f9b4c7e60be7374d.tar.gz
calcurse-b2321a7567340ff285cfcde5f9b4c7e60be7374d.zip
Patch to correct the wrong calculation of recurrent items' dates after a
turn of year (submitted by Lukas Fleischer, thanks!).
Diffstat (limited to 'src')
-rwxr-xr-xsrc/calendar.c5
-rwxr-xr-xsrc/calendar.h12
-rwxr-xr-xsrc/recur.c81
-rwxr-xr-xsrc/vars.h9
4 files changed, 88 insertions, 19 deletions
diff --git a/src/calendar.c b/src/calendar.c
index 2c6c781..2be7c62 100755
--- a/src/calendar.c
+++ b/src/calendar.c
@@ -1,9 +1,9 @@
-/* $calcurse: calendar.c,v 1.31 2010/03/01 18:55:45 culot Exp $ */
+/* $calcurse: calendar.c,v 1.32 2010/03/08 08:44:44 culot Exp $ */
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2009 Frederic Culot <frederic@culot.org>
+ * Copyright (c) 2004-2010 Frederic Culot <frederic@culot.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -64,7 +64,6 @@
#define lzero 318.351648 /* lunar mean long at EPOCH */
#define Pzero 36.340410 /* lunar mean long of perigee at EPOCH */
#define Nzero 318.510107 /* lunar mean long of node at EPOCH */
-#define TM_YEAR_BASE 1900
#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
diff --git a/src/calendar.h b/src/calendar.h
index 60499a7..e900bcd 100755
--- a/src/calendar.h
+++ b/src/calendar.h
@@ -1,9 +1,9 @@
-/* $calcurse: calendar.h,v 1.18 2009/10/28 15:15:43 culot Exp $ */
+/* $calcurse: calendar.h,v 1.19 2010/03/08 08:44:44 culot Exp $ */
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2009 Frederic Culot <frederic@culot.org>
+ * Copyright (c) 2004-2010 Frederic Culot <frederic@culot.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -60,6 +60,14 @@
#define CALHEIGHT 12
#define CALWIDTH 30
+#define DAYINSEC 86400
+#define HOURINSEC 3600
+#define MININSEC 60
+#define YEARINDAYS 365
+#define YEARINMONTHS 12
+#define WEEKINDAYS 7
+#define TM_YEAR_BASE 1900
+
typedef enum
{ /* days of week */
SUNDAY,
diff --git a/src/recur.c b/src/recur.c
index e21bf0c..5d06726 100755
--- a/src/recur.c
+++ b/src/recur.c
@@ -1,9 +1,9 @@
-/* $calcurse: recur.c,v 1.52 2009/07/19 08:20:01 culot Exp $ */
+/* $calcurse: recur.c,v 1.53 2010/03/08 08:44:44 culot Exp $ */
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2009 Frederic Culot <frederic@culot.org>
+ * Copyright (c) 2004-2010 Frederic Culot <frederic@culot.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -55,6 +55,7 @@ struct recur_event_s *recur_elist;
static struct recur_event_s bkp_cut_recur_event;
static recur_apoint_llist_node_t bkp_cut_recur_apoint;
+
static void
free_exc (struct days_s *exc)
{
@@ -589,11 +590,78 @@ recur_save_data (FILE *f)
pthread_mutex_unlock (&(recur_alist_p->mutex));
}
+
+/*
+ * The two following defines together with the diff_days, diff_weeks,
+ * diff_months and diff_years functions were provided by Lukas Fleischer to
+ * correct the wrong calculation of recurrent dates after a turn of year.
+ */
+#define bc(start, end, bs) \
+ (((end) - (start) + ((start) % bs) - ((end) % bs)) / bs \
+ + ((((start) % bs) == 0) ? 1 : 0))
+
+#define leapcount(start, end) \
+ (bc(start, end, 4) - bc(start, end, 100) + bc(start, end, 400))
+
+
+/* Calculate the difference in days between two dates. */
+static long
+diff_days (struct tm lt_start, struct tm lt_end)
+{
+ long diff;
+
+ if (lt_end.tm_year < lt_start.tm_year)
+ return 0;
+
+ diff = lt_end.tm_yday - lt_start.tm_yday;
+
+ if (lt_end.tm_year > lt_start.tm_year)
+ {
+ diff += (lt_end.tm_year - lt_start.tm_year) * YEARINDAYS;
+ diff += leapcount (lt_start.tm_year + TM_YEAR_BASE,
+ lt_end.tm_year + TM_YEAR_BASE - 1);
+ }
+
+ return diff;
+}
+
+/* Calculate the difference in weeks between two dates. */
+static long
+diff_weeks (struct tm lt_start, struct tm lt_end)
+{
+ return diff_days (lt_start, lt_end) / WEEKINDAYS;
+}
+
+/* Calculate the difference in months between two dates. */
+static long
+diff_months (struct tm lt_start, struct tm lt_end)
+{
+ long diff;
+
+ if (lt_end.tm_year < lt_start.tm_year)
+ return 0;
+
+ diff = lt_end.tm_mon - lt_start.tm_mon;
+ diff += (lt_end.tm_year - lt_start.tm_year) * YEARINMONTHS;
+
+ return diff;
+}
+
+/* Calculate the difference in years between two dates. */
+static long
+diff_years (struct tm lt_start, struct tm lt_end)
+{
+ return lt_end.tm_year - lt_start.tm_year;
+}
+
/*
* Check if the recurrent item belongs to the selected day,
* and if yes, return the real start time.
+ *
* This function was improved thanks to Tony's patch.
* Thanks also to youshe for reporting daylight saving time related problems.
+ * And finally thanks to Lukas for providing a patch to correct the wrong
+ * calculation of recurrent dates after a turn of years.
*/
unsigned
recur_item_inday (long item_start, struct days_s *item_exc, int rpt_type,
@@ -625,7 +693,7 @@ recur_item_inday (long item_start, struct days_s *item_exc, int rpt_type,
switch (rpt_type)
{
case RECUR_DAILY:
- diff = lt_day.tm_yday - lt_item.tm_yday;
+ diff = diff_days (lt_item, lt_day);
if (diff % rpt_freq != 0)
return (0);
lt_item.tm_mday = lt_day.tm_mday;
@@ -637,7 +705,7 @@ recur_item_inday (long item_start, struct days_s *item_exc, int rpt_type,
return (0);
else
{
- diff = ((lt_day.tm_yday - lt_item.tm_yday) / WEEKINDAYS);
+ diff = diff_weeks (lt_item, lt_day);
if (diff % rpt_freq != 0)
return (0);
}
@@ -646,15 +714,14 @@ recur_item_inday (long item_start, struct days_s *item_exc, int rpt_type,
lt_item.tm_year = lt_day.tm_year;
break;
case RECUR_MONTHLY:
- diff = (((lt_day.tm_year - lt_item.tm_year) * 12)
- + (lt_day.tm_mon - lt_item.tm_mon));
+ diff = diff_months (lt_item, lt_day);
if (diff % rpt_freq != 0)
return (0);
lt_item.tm_mon = lt_day.tm_mon;
lt_item.tm_year = lt_day.tm_year;
break;
case RECUR_YEARLY:
- diff = lt_day.tm_year - lt_item.tm_year;
+ diff = diff_years (lt_item, lt_day);
if (diff % rpt_freq != 0)
return (0);
lt_item.tm_year = lt_day.tm_year;
diff --git a/src/vars.h b/src/vars.h
index 7f45c98..fbb88c1 100755
--- a/src/vars.h
+++ b/src/vars.h
@@ -1,9 +1,9 @@
-/* $calcurse: vars.h,v 1.37 2009/08/01 13:31:21 culot Exp $ */
+/* $calcurse: vars.h,v 1.38 2010/03/08 08:44:44 culot Exp $ */
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2009 Frederic Culot <frederic@culot.org>
+ * Copyright (c) 2004-2010 Frederic Culot <frederic@culot.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -82,11 +82,6 @@
#define ATTR_HIGH 5
#define ATTR_HIGHEST 6
-#define DAYINSEC 86400
-#define HOURINSEC 3600
-#define MININSEC 60
-#define WEEKINDAYS 7
-
#define STATUSHEIGHT 2
#define NOTESIZ 6