GnuCash  4.901-15-g732a005710
Recurrence.h
1 /* Recurrence.h:
2  *
3  * A Recurrence represents the periodic occurrence of dates, with a
4  * beginning point. For example, "Every Friday, beginning April 15,
5  * 2005" or "The 1st of every 3rd month, beginning April 1, 2001."
6  *
7  * Technically, a Recurrence can also represent certain useful
8  * "almost periodic" date sequences. For example, "The last day of
9  * every month, beginning Feb. 28, 2005."
10  *
11  * The main operation you can perform on a Recurrence is to find the
12  * earliest date in the sequence of occurrences that is after some
13  * specified date (often the "previous" occurrence).
14  *
15  * In addition, you can use a GList of Recurrences to represent a
16  * sequence containing all the dates in each Recurrence in the list,
17  * and perform the same "next instance" computation for this
18  * sequence.
19  *
20  * Copyright (C) 2005, Chris Shoemaker <c.shoemaker@cox.net>
21  *
22  * This program is free software; you can redistribute it and/or
23  * modify it under the terms of the GNU General Public License as
24  * published by the Free Software Foundation; either version 2 of
25  * the License, or (at your option) any later version.
26  *
27  * This program is distributed in the hope that it will be useful,
28  * but WITHOUT ANY WARRANTY; without even the implied warranty of
29  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30  * GNU General Public License for more details.
31  *
32  * You should have received a copy of the GNU General Public License
33  * along with this program; if not, contact:
34  *
35  * Free Software Foundation Voice: +1-617-542-5942
36  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
37  * Boston, MA 02110-1301, USA gnu@gnu.org
38  */
39 
40 #ifndef RECURRENCE_H
41 #define RECURRENCE_H
42 
43 #include <glib.h>
44 #include "Account.h"
45 #include "gnc-numeric.h"
46 
47 #ifdef __cplusplus
48 extern "C" {
49 #endif
50 
51 typedef enum
52 {
53  PERIOD_ONCE, /* Not a true period at all, but convenient here. */
54  PERIOD_DAY,
55  PERIOD_WEEK,
56  PERIOD_MONTH,
57  PERIOD_END_OF_MONTH, /* This is actually a period plus a phase. */
58  PERIOD_NTH_WEEKDAY, /* Also a phase, e.g. Second Tueday. */
59  PERIOD_LAST_WEEKDAY, /* Also a phase. */
60  PERIOD_YEAR,
61  NUM_PERIOD_TYPES,
62  PERIOD_INVALID = -1,
63 } PeriodType;
64 
65 typedef enum
66 {
67  WEEKEND_ADJ_NONE,
68  WEEKEND_ADJ_BACK, /* Previous weekday */
69  WEEKEND_ADJ_FORWARD, /* Next weekday */
70  NUM_WEEKEND_ADJS,
71  WEEKEND_ADJ_INVALID = -1,
72 } WeekendAdjust;
73 
74 /* Recurrences represent both the phase and period of a recurring event. */
75 
76 typedef struct
77 {
78  GDate start; /* First date in the recurrence; specifies phase. */
79  PeriodType ptype; /* see PeriodType enum */
80  guint16 mult; /* a period multiplier */
81  WeekendAdjust wadj; /* see WeekendAdjust enum */
82 } Recurrence;
83 
84 
85 /* recurrenceSet() will enforce internal consistency by overriding
86  inconsistent inputs so that 'r' will _always_ end up being a valid
87  recurrence.
88 
89  - if the period type is invalid, PERIOD_MONTH is used.
90 
91  - if the period type is PERIOD_ONCE, then mult is ignored,
92  otherwise, if mult is zero, then mult of 1 is used.
93 
94  - if the date is invalid, the current date is used.
95 
96  - if the period type specifies phase, the date is made to agree
97  with that phase:
98 
99  - for PERIOD_END_OF_MONTH, the last day of date's month is used.
100 
101  - for PERIOD_NTH_WEEKDAY, a fifth weekday converts to a
102  PERIOD_LAST_WEEKDAY
103 
104  - for PERIOD_LAST_WEEKDAY, the last day in date's month with
105  date's day-of-week is used.
106 
107 */
108 void recurrenceSet(Recurrence *r, guint16 mult, PeriodType pt,
109  const GDate *date, WeekendAdjust wadj);
110 
111 /* get the fields */
112 PeriodType recurrenceGetPeriodType(const Recurrence *r);
113 guint recurrenceGetMultiplier(const Recurrence *r);
114 GDate recurrenceGetDate(const Recurrence *r);
115 time64 recurrenceGetTime(const Recurrence *r);
116 WeekendAdjust recurrenceGetWeekendAdjust(const Recurrence *r);
117 
118 /* Get the occurrence immediately after refDate.
119  *
120  * This function has strict and precise post-conditions:
121  *
122  * Given a valid recurrence and a valid 'refDate', 'nextDate' will be
123  * *IN*valid IFF the period_type is PERIOD_ONCE, and 'refDate' is
124  * later-than or equal to the single occurrence (start_date).
125  *
126  * A valid 'nextDate' will _always_ be:
127  * - strictly later than the 'refDate', AND
128  * - later than or equal to the start date of the recurrence, AND
129  * - exactly an integral number of periods away from the start date
130  *
131  * Furthermore, there will be no date _earlier_ than 'nextDate' for
132  * which the three things above are true.
133  *
134  */
135 void recurrenceNextInstance(const Recurrence *r, const GDate *refDate,
136  GDate *nextDate);
137 
138 /* Zero-based. n == 1 gets the instance after the start date. */
139 void recurrenceNthInstance(const Recurrence *r, guint n, GDate *date);
140 
141 /* Get a time corresponding to the beginning (or end if 'end' is true)
142  of the nth instance of the recurrence. Also zero-based. */
143 time64 recurrenceGetPeriodTime(const Recurrence *r, guint n, gboolean end);
144 
150 gnc_numeric recurrenceGetAccountPeriodValue(const Recurrence *r,
151  Account *acct, guint n);
152 
154 void recurrenceListNextInstance(const GList *r, const GDate *refDate,
155  GDate *nextDate);
156 
157 /* These four functions are only for xml storage, not user presentation. */
158 gchar *recurrencePeriodTypeToString(PeriodType pt);
159 PeriodType recurrencePeriodTypeFromString(const gchar *str);
160 gchar *recurrenceWeekendAdjustToString(WeekendAdjust wadj);
161 WeekendAdjust recurrenceWeekendAdjustFromString(const gchar *str);
162 
163 /* For debugging. Caller owns the returned string. Not intl. */
164 gchar *recurrenceToString(const Recurrence *r);
165 gchar *recurrenceListToString(const GList *rlist);
166 
168 gboolean recurrenceListIsSemiMonthly(GList *recurrences);
170 gboolean recurrenceListIsWeeklyMultiple(const GList *recurrences);
171 
184 gchar *recurrenceListToCompactString(GList *recurrence_list);
185 
187 int recurrenceCmp(Recurrence *a, Recurrence *b);
188 int recurrenceListCmp(GList *a, GList *b);
189 
190 void recurrenceListFree(GList **recurrence);
191 
192 #ifdef __cplusplus
193 }
194 #endif
195 
196 #endif /* RECURRENCE_H */
An exact-rational-number library for gnucash.
Account handling public routines.
gint64 time64
Many systems, including Microsoft Windows and BSD-derived Unixes like Darwin, are retaining the int-3...
Definition: gnc-date.h:87