gnc-gdate-utils.c

00001 /*
00002  * gnc-gdate-utils.c -- utility functions for manipulating
00003  *              GDate data structures from GLib
00004  * Copyright (C) 2005 David Hampton <hampton@employees.org>
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License as
00008  * published by the Free Software Foundation; either version 2 of
00009  * the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, contact:
00018  *
00019  * Free Software Foundation           Voice:  +1-617-542-5942
00020  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
00021  * Boston, MA  02110-1301,  USA       gnu@gnu.org
00022  */
00023 
00024 #include "config.h"
00025 #include <glib.h>
00026 #include <time.h>
00027 
00028 #include "gnc-gdate-utils.h"
00029 
00030 
00031 gboolean
00032 gnc_gdate_equal(gconstpointer gda, gconstpointer gdb)
00033 {
00034   return (g_date_compare( (GDate*)gda, (GDate*)gdb ) == 0 ? TRUE : FALSE);
00035 }
00036 
00037 guint
00038 gnc_gdate_hash( gconstpointer gd )
00039 {
00040   gint val = (g_date_get_year( (GDate*)gd ) * 10000)
00041     + (g_date_get_month( (GDate*)gd ) * 100)
00042     + g_date_get_day( (GDate*)gd );
00043   return g_int_hash( &val );
00044 }
00045 
00046 
00047 time_t
00048 gnc_timet_get_day_start_gdate (GDate *date)
00049 {
00050   struct tm stm;
00051   time_t secs;
00052 
00053   /* First convert to a 'struct tm' */
00054   g_date_to_struct_tm(date, &stm);
00055 
00056   /* Then convert to number of seconds */
00057   secs = mktime (&stm);
00058   return secs;
00059 }
00060 
00061 time_t
00062 gnc_timet_get_day_end_gdate (GDate *date)
00063 {
00064   struct tm stm;
00065   time_t secs;
00066 
00067   /* First convert to a 'struct tm' */
00068   g_date_to_struct_tm(date, &stm);
00069 
00070   /* Force to th last second of the day */
00071   stm.tm_hour = 23;
00072   stm.tm_min = 59;
00073   stm.tm_sec = 59;
00074   stm.tm_isdst = -1;
00075 
00076   /* Then convert to number of seconds */
00077   secs = mktime (&stm);
00078   return secs;
00079 }
00080 
00081 
00082 void
00083 gnc_gdate_set_month_start (GDate *date)
00084 {
00085   g_date_set_day(date, 1);
00086 }
00087 
00088 
00096 void
00097 gnc_gdate_set_month_end (GDate *date)
00098 {
00099   /* First set the start of next month. */
00100   g_date_set_day(date, 1);
00101   g_date_add_months(date, 1);
00102 
00103   /* Then back up one day */
00104   g_date_subtract_days(date, 1);
00105 }
00106 
00107 
00115 void
00116 gnc_gdate_set_prev_month_start (GDate *date)
00117 {
00118   g_date_set_day(date, 1);
00119   g_date_subtract_months(date, 1);
00120 }
00121 
00122 
00130 void
00131 gnc_gdate_set_prev_month_end (GDate *date)
00132 {
00133   /* This will correctly handle the varying month lengths */
00134   g_date_set_day(date, 1);
00135   g_date_subtract_days(date, 1);
00136 }
00137 
00138 /* ========== */
00139 
00140 void
00141 gnc_gdate_set_quarter_start (GDate *date)
00142 {
00143   gint months;
00144 
00145   /* Set the date to the first day of the specified month. */
00146   g_date_set_day(date, 1);
00147 
00148   /* Back up 0-2 months */ 
00149   months = (g_date_get_month(date) - G_DATE_JANUARY) % 3;
00150   g_date_subtract_months(date, months);
00151 }
00152 
00153 
00154 void
00155 gnc_gdate_set_quarter_end (GDate *date)
00156 {
00157   gint months;
00158 
00159   /* Set the date to the first day of the specified month. */
00160   g_date_set_day(date, 1);
00161 
00162   /* Add 1-3 months to get the first day of the next quarter.*/
00163   months = (g_date_get_month(date) - G_DATE_JANUARY) % 3;
00164   g_date_add_months(date, 3 - months);
00165 
00166   /* Now back up one day */
00167   g_date_subtract_days(date, 1);
00168 }
00169 
00170 
00171 void
00172 gnc_gdate_set_prev_quarter_start (GDate *date)
00173 {
00174   gnc_gdate_set_quarter_start(date);
00175   g_date_subtract_months(date, 3);
00176 }
00177 
00178 
00179 void
00180 gnc_gdate_set_prev_quarter_end (GDate *date)
00181 {
00182   gnc_gdate_set_quarter_end(date);
00183   g_date_subtract_months(date, 3);
00184 }
00185 
00186 /* ========== */
00187 
00188 void
00189 gnc_gdate_set_year_start (GDate *date)
00190 {
00191   g_date_set_month(date, G_DATE_JANUARY);
00192   g_date_set_day(date, 1);
00193 }
00194 
00195 
00196 void
00197 gnc_gdate_set_year_end (GDate *date)
00198 {
00199   g_date_set_month(date, G_DATE_DECEMBER);
00200   g_date_set_day(date, 31);
00201 }
00202 
00203 
00204 void
00205 gnc_gdate_set_prev_year_start (GDate *date)
00206 {
00207   gnc_gdate_set_year_start(date);
00208   g_date_subtract_years(date, 1);
00209 }
00210 
00211 
00212 void
00213 gnc_gdate_set_prev_year_end (GDate *date)
00214 {
00215   gnc_gdate_set_year_end(date);
00216   g_date_subtract_years(date, 1);
00217 }
00218 
00219 /* ========== */
00220 
00221 void
00222 gnc_gdate_set_fiscal_year_start (GDate *date,
00223                                 const GDate *fy_end)
00224 {
00225   GDate temp;
00226   gboolean new_fy;
00227 
00228   g_return_if_fail(date);
00229   g_return_if_fail(fy_end);
00230 
00231   /* Compute the FY end that occurred this CY */
00232   temp = *fy_end;
00233   g_date_set_year(&temp, g_date_get_year(date));
00234 
00235   /* Has it already passed? */
00236   new_fy = (g_date_compare(date, &temp) > 0);
00237 
00238   /* Set start date */
00239   *date = temp;
00240   g_date_add_days(date, 1);
00241   if (!new_fy)
00242     g_date_subtract_years(date, 1);
00243 }
00244 
00245 void
00246 gnc_gdate_set_fiscal_year_end (GDate *date,
00247                               const GDate *fy_end)
00248 {
00249   GDate temp;
00250   gboolean new_fy;
00251 
00252   g_return_if_fail(date);
00253   g_return_if_fail(fy_end);
00254 
00255   /* Compute the FY end that occurred this CY */
00256   temp = *fy_end;
00257   g_date_set_year(&temp, g_date_get_year(date));
00258 
00259   /* Has it already passed? */
00260   new_fy = (g_date_compare(date, &temp) > 0);
00261 
00262   /* Set end date */
00263   *date = temp;
00264   if (new_fy)
00265     g_date_add_years(date, 1);
00266 }
00267 
00268 void
00269 gnc_gdate_set_prev_fiscal_year_start (GDate *date,
00270                                      const GDate *fy_end)
00271 {
00272   g_return_if_fail(date);
00273   g_return_if_fail(fy_end);
00274 
00275   gnc_gdate_set_fiscal_year_start(date, fy_end);
00276   g_date_subtract_years(date, 1);
00277 }
00278 
00279 void
00280 gnc_gdate_set_prev_fiscal_year_end (GDate *date,
00281                                    const GDate *fy_end)
00282 {
00283   g_return_if_fail(date);
00284   g_return_if_fail(fy_end);
00285 
00286   gnc_gdate_set_fiscal_year_end(date, fy_end);
00287   g_date_subtract_years(date, 1);
00288 }

Generated on Sun Sep 7 05:07:15 2008 for GnuCash by  doxygen 1.5.2