|
GnuCash 2.4.99
|
00001 /* Recurrence.h: 00002 * 00003 * A Recurrence represents the periodic occurrence of dates, with a 00004 * beginning point. For example, "Every Friday, beginning April 15, 00005 * 2005" or "The 1st of every 3rd month, beginning April 1, 2001." 00006 * 00007 * Technically, a Recurrence can also represent certain useful 00008 * "almost periodic" date sequences. For example, "The last day of 00009 * every month, beginning Feb. 28, 2005." 00010 * 00011 * The main operation you can perform on a Recurrence is to find the 00012 * earliest date in the sequence of occurrences that is after some 00013 * specified date (often the "previous" occurrence). 00014 * 00015 * In addition, you can use a GList of Recurrences to represent a 00016 * sequence containing all the dates in each Recurrence in the list, 00017 * and perform the same "next instance" computation for this 00018 * sequence. 00019 * 00020 * Copyright (C) 2005, Chris Shoemaker <c.shoemaker@cox.net> 00021 * 00022 * This program is free software; you can redistribute it and/or 00023 * modify it under the terms of the GNU General Public License as 00024 * published by the Free Software Foundation; either version 2 of 00025 * the License, or (at your option) any later version. 00026 * 00027 * This program is distributed in the hope that it will be useful, 00028 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00029 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00030 * GNU General Public License for more details. 00031 * 00032 * You should have received a copy of the GNU General Public License 00033 * along with this program; if not, contact: 00034 * 00035 * Free Software Foundation Voice: +1-617-542-5942 00036 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 00037 * Boston, MA 02110-1301, USA gnu@gnu.org 00038 */ 00039 00040 #ifndef RECURRENCE_H 00041 #define RECURRENCE_H 00042 00043 #include <glib.h> 00044 #include "Account.h" 00045 #include "gnc-numeric.h" 00046 00047 typedef enum 00048 { 00049 PERIOD_ONCE, /* Not a true period at all, but convenient here. */ 00050 PERIOD_DAY, 00051 PERIOD_WEEK, 00052 PERIOD_MONTH, 00053 PERIOD_END_OF_MONTH, /* This is actually a period plus a phase. */ 00054 PERIOD_NTH_WEEKDAY, /* Also a phase, e.g. Second Tueday. */ 00055 PERIOD_LAST_WEEKDAY, /* Also a phase. */ 00056 PERIOD_YEAR, 00057 NUM_PERIOD_TYPES, 00058 PERIOD_INVALID = -1, 00059 } PeriodType; 00060 00061 typedef enum 00062 { 00063 WEEKEND_ADJ_NONE, 00064 WEEKEND_ADJ_BACK, /* Previous weekday */ 00065 WEEKEND_ADJ_FORWARD, /* Next weekday */ 00066 NUM_WEEKEND_ADJS, 00067 WEEKEND_ADJ_INVALID = -1, 00068 } WeekendAdjust; 00069 00070 /* Recurrences represent both the phase and period of a recurring event. */ 00071 00072 typedef struct 00073 { 00074 GDate start; /* First date in the recurrence; specifies phase. */ 00075 PeriodType ptype; /* see PeriodType enum */ 00076 guint16 mult; /* a period multiplier */ 00077 WeekendAdjust wadj; /* see WeekendAdjust enum */ 00078 } Recurrence; 00079 00080 00081 /* recurrenceSet() will enforce internal consistency by overriding 00082 inconsistent inputs so that 'r' will _always_ end up being a valid 00083 recurrence. 00084 00085 - if the period type is invalid, PERIOD_MONTH is used. 00086 00087 - if the period type is PERIOD_ONCE, then mult is ignored, 00088 otherwise, if mult is zero, then mult of 1 is used. 00089 00090 - if the date is invalid, the current date is used. 00091 00092 - if the period type specifies phase, the date is made to agree 00093 with that phase: 00094 00095 - for PERIOD_END_OF_MONTH, the last day of date's month is used. 00096 00097 - for PERIOD_NTH_WEEKDAY, a fifth weekday converts to a 00098 PERIOD_LAST_WEEKDAY 00099 00100 - for PERIOD_LAST_WEEKDAY, the last day in date's month with 00101 date's day-of-week is used. 00102 00103 */ 00104 void recurrenceSet(Recurrence *r, guint16 mult, PeriodType pt, 00105 const GDate *date, WeekendAdjust wadj); 00106 00107 /* get the fields */ 00108 PeriodType recurrenceGetPeriodType(const Recurrence *r); 00109 guint recurrenceGetMultiplier(const Recurrence *r); 00110 GDate recurrenceGetDate(const Recurrence *r); 00111 WeekendAdjust recurrenceGetWeekendAdjust(const Recurrence *r); 00112 00113 /* Get the occurence immediately after refDate. 00114 * 00115 * This function has strict and precise post-conditions: 00116 * 00117 * Given a valid recurrence and a valid 'refDate', 'nextDate' will be 00118 * *IN*valid IFF the period_type is PERIOD_ONCE, and 'refDate' is 00119 * later-than or equal to the single occurrence (start_date). 00120 * 00121 * A valid 'nextDate' will _always_ be: 00122 * - strictly later than the 'refDate', AND 00123 * - later than or equal to the start date of the recurrence, AND 00124 * - exactly an integral number of periods away from the start date 00125 * 00126 * Furthermore, there will be no date _earlier_ than 'nextDate' for 00127 * which the three things above are true. 00128 * 00129 */ 00130 void recurrenceNextInstance(const Recurrence *r, const GDate *refDate, 00131 GDate *nextDate); 00132 00133 /* Zero-based. n == 1 gets the instance after the start date. */ 00134 void recurrenceNthInstance(const Recurrence *r, guint n, GDate *date); 00135 00136 /* Get a time coresponding to the beginning (or end if 'end' is true) 00137 of the nth instance of the recurrence. Also zero-based. */ 00138 time_t recurrenceGetPeriodTime(const Recurrence *r, guint n, gboolean end); 00139 00144 gnc_numeric recurrenceGetAccountPeriodValue(const Recurrence *r, 00145 Account *acct, guint n); 00146 00148 void recurrenceListNextInstance(const GList *r, const GDate *refDate, 00149 GDate *nextDate); 00150 00151 /* These four functions are only for xml storage, not user presentation. */ 00152 gchar *recurrencePeriodTypeToString(PeriodType pt); 00153 PeriodType recurrencePeriodTypeFromString(const gchar *str); 00154 gchar *recurrenceWeekendAdjustToString(WeekendAdjust wadj); 00155 WeekendAdjust recurrenceWeekendAdjustFromString(const gchar *str); 00156 00157 /* For debugging. Caller owns the returned string. Not intl. */ 00158 gchar *recurrenceToString(const Recurrence *r); 00159 gchar *recurrenceListToString(const GList *rlist); 00160 00162 gboolean recurrenceListIsSemiMonthly(GList *recurrences); 00164 gboolean recurrenceListIsWeeklyMultiple(const GList *recurrences); 00165 00178 gchar *recurrenceListToCompactString(GList *recurrence_list); 00179 00181 int recurrenceCmp(Recurrence *a, Recurrence *b); 00182 int recurrenceListCmp(GList *a, GList *b); 00183 00184 void recurrenceListFree(GList **recurrence); 00185 00186 #endif /* RECURRENCE_H */
1.7.4