Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

Date.cpp

Go to the documentation of this file.
00001 //  ======================================================================== //
00002 //                                                                           //
00003 //    File      : Date.cpp                                                   //
00004 //    Purpose   :                                                            //
00005 //    Time-stamp: <Wed Dec/26/2001 14:04 MET Coder@ReallySoft.de>            //
00006 //                                                                           //
00007 //    (C) December 2001 by Ralf Westram                                      //
00008 //                                                                           //
00009 //    Permission to use, copy, modify, distribute and sell this software     //
00010 //    and its documentation for any purpose is hereby granted without fee,   //
00011 //    provided that the above copyright notice appear in all copies and      //
00012 //    that both that copyright notice and this permission notice appear      //
00013 //    in supporting documentation.                                           //
00014 //                                                                           //
00015 //    Ralf Westram makes no representations about the suitability of this    //
00016 //    software for any purpose.  It is provided "as is" without express or   //
00017 //    implied warranty.                                                      //
00018 //                                                                           //
00019 //  ======================================================================== //
00020 
00021 #ifndef CMEMORY
00022 #include <cstring>
00023 #endif
00024 #ifndef CSTDIO
00025 #include <cstdio>
00026 #endif
00027 #ifndef ERR_H
00028 #include <Err.h>
00029 #endif
00030 
00031 #include "Date.h"
00032 
00033 using namespace std;
00034 using namespace rs;
00035 using namespace rs::date;
00036 using namespace rs::err;
00037 
00038 // start of implementation of class Date:
00039 
00040 
00041 // --------------------------------------------------
00042 //      void Date::init(const std::time_t& time_)
00043 // --------------------------------------------------
00044 void Date::init(const std::time_t& time_)
00045 {
00046     valid = false;
00047     time  = time_;
00048     if (time != -1) {
00049         date = *localtime(&time);
00050         init(date);
00051     }
00052 }
00053 
00054 // ----------------------------------------------
00055 //      void Date::init(const std::tm& date_)
00056 // ----------------------------------------------
00057 void Date::init(const std::tm& date_)
00058 {
00059     date  = date_;
00060     time  = mktime(&date);
00061     if (time != -1) {
00062         date = *localtime(&time);
00063         if (date_.tm_mday == date.tm_mday &&
00064             date_.tm_mon  == date.tm_mon &&
00065             date_.tm_year == date.tm_year)
00066         {
00067             valid = true;
00068         }
00069     }
00070 }
00071 // -----------------------------
00072 //      void Date::correct()
00073 // -----------------------------
00074 void Date::correct()
00075 {
00076     struct tm tmp = date;
00077     init(tmp);
00078 }
00079 
00080 // ---------------------------------------------------------
00081 //      void Date::init(int day_, int month_, int year_)
00082 // ---------------------------------------------------------
00083 void Date::init(int day_, int month_, int year_)
00084 {
00085     struct tm tmp;
00086     memset(&tmp, 0, sizeof(tmp));
00087 
00088     tmp.tm_mday = day_;
00089     tmp.tm_mon  = month_-1;
00090     tmp.tm_year = year_-1900;
00091 
00092     init(tmp);
00093 }
00094 
00095 // -------------------------
00096 //      struct Feiertag
00097 // -------------------------
00098 struct Feiertag {
00099     int         day, month;
00100     const char *name;
00101     bool        catholic; // catholic Feiertag (phone is not cheaper)
00102     bool        half;
00103 };
00104 
00105 // ----------------------------
00106 //      enum FeiertagIndex
00107 // ----------------------------
00108 enum FeiertagIndex {
00109     NO_FEIERTAG        = 0,
00110     FIRST              = 1,
00111     TAG_DER_DT_EINHEIT = 5,
00112     HL_ABEND           = 7,
00113     LAST_FIXED         = 10,
00114     OSTERSONNTAG,
00115     OSTERMONTAG,
00116     WEISSER_SONNTAG,
00117     CHRISTI_HIMMELFAHRT,
00118     PFINGSTSONNTAG,
00119     PFINGSTMONTAG,
00120     FRONLEICHNAM,
00121     KARFREITAG,
00122     PALMSONNTAG,
00123     BUSS_UND_BETTAG,
00124     ADVENT_1,
00125     ADVENT_2,
00126     ADVENT_3,
00127     ADVENT_4,
00128     LAST               = ADVENT_4
00129 };
00130 
00131 static int year_calculated_for = -1;
00132 
00133 // --------------------------------------
00134 //      static Feiertag feiertag[] =
00135 // --------------------------------------
00136 static Feiertag feiertag[] = {
00137     { 0,  0, "", false, false},
00138     { 1,  1, "Neujahr", false, false},
00139     { 6,  1, "Heilige drei Könige", true, false},
00140     { 1,  5, "Tag der Arbeit", false, false},
00141     {15,  8, "Maria Himmelfahrt", true, false},
00142     { 3, 10, "Tag der deutschen Einheit", false, false}, // (17.6 before 1990)
00143     { 1, 11, "Allerheiligen", false, false},
00144     {24, 12, "Heiliger Abend", false, true},
00145     {25, 12, "1. Weihnachtsfeiertag", false, false},
00146     {26, 12, "1. Weihnachtsfeiertag", false, false},
00147     {31, 12, "Silvester", false, true},
00148 
00149     // the following have variing dates:
00150 
00151     {0, 0, "Ostersonntag", false, false},
00152     {0, 0, "Ostermontag", false, false},
00153     {0, 0, "Weisser Sonntag", false, false},
00154     {0, 0, "Christi Himmelfahrt", false, false},
00155     {0, 0, "Pfingstsonntag", false, false},
00156     {0, 0, "Pfingstmontag", false, false},
00157     {0, 0, "Fronleichnam", false, false},
00158     {0, 0, "Karfreitag", false, false},
00159     {0, 0, "Palmsonntag", false, false},
00160     {0, 0, "Buß- und Bettag", false, false},
00161     {0, 0, "1. Advent", false, false},
00162     {0, 0, "2. Advent", false, false},
00163     {0, 0, "3. Advent", false, false},
00164     {0, 0, "4. Advent", false, false}
00165 };
00166 
00167 // --------------------------------------------------------------
00168 //      inline bool matches(int feiertag_idx, const Date& d)
00169 // --------------------------------------------------------------
00170 inline bool matches(int feiertag_idx, const Date& d) {
00171     assert(feiertag_idx >= FIRST && feiertag_idx <= LAST);
00172     const struct tm& date  = d.get_Date();
00173     return
00174         date.tm_mday      == feiertag[feiertag_idx].day &&
00175         (date.tm_mon+1)   == feiertag[feiertag_idx].month;
00176 }
00177 
00178 // ------------------------------------------------------------
00179 //      inline void store(const Date& d, int feiertag_idx)
00180 // ------------------------------------------------------------
00181 inline void store(const Date& d, int feiertag_idx) {
00182     assert(feiertag_idx > LAST_FIXED && feiertag_idx <= LAST);
00183     const struct tm& date = d.get_Date();
00184 
00185     feiertag[feiertag_idx].day = date.tm_mday;
00186     feiertag[feiertag_idx].month = date.tm_mon+1;
00187 }
00188 
00189 // -----------------------------------------------------
00190 //      static void calculateFeiertageFor(int year)
00191 // -----------------------------------------------------
00192 static void calculateFeiertageFor(int year) {
00193     assert(year_calculated_for != year);
00194     year_calculated_for = year;
00195 
00196 //     year -= 1900;
00197 
00198     int a = year%19;
00199     int b = year/100;
00200     int c = year%100;
00201     int d = b/4;
00202     int e = b%4;
00203     int f = (b+8)/25;
00204     int g = (b-f+1)/3;
00205     int h = (19*a+b-d-g+15)%30;
00206     int i = c/4;
00207     int k = c%4;
00208     int l = (32+2*e+2*i-h-k)%7;
00209     int m = (a+11*h+22*l)/451;
00210 
00211     int Easter = h+l-7*m+22;
00212 
00213 //     year += 1900;
00214 
00215     feiertag[OSTERSONNTAG].month = Easter>31 ? 4 : 3;
00216     feiertag[OSTERSONNTAG].day   = Easter>31 ? Easter-31 : Easter;
00217 
00218     Date d1(feiertag[OSTERSONNTAG].day, feiertag[OSTERSONNTAG].month, year);
00219     Date d2(d1);
00220 
00221     d1.inc(); store(d1, OSTERMONTAG);
00222     d1.inc(6); store(d1, WEISSER_SONNTAG);
00223     d1.inc(32); store(d1, CHRISTI_HIMMELFAHRT);
00224     d1.inc(10); store(d1, PFINGSTSONNTAG);
00225     d1.inc(1); store(d1, PFINGSTMONTAG);
00226     d1.inc(10); store(d1, FRONLEICHNAM);
00227 
00228     d2.dec(2); store(d2, KARFREITAG);
00229     d2.dec(5); store(d2, PALMSONNTAG);
00230 
00231     Date d3(feiertag[HL_ABEND].day, feiertag[HL_ABEND].month, year);
00232     d3.dec(d3.dayOfWeek()); // last sunday before or at HL_ABEND
00233 
00234     store(d3, ADVENT_4);
00235     d3.dec(7); store(d3, ADVENT_3);
00236     d3.dec(7); store(d3, ADVENT_2);
00237     d3.dec(7); store(d3, ADVENT_1);
00238     d3.dec(11); store(d3, BUSS_UND_BETTAG);
00239 
00240     printf("year=%i\n", year);
00241 
00242     if (year<1990) {
00243         feiertag[TAG_DER_DT_EINHEIT].day   = 17;
00244         feiertag[TAG_DER_DT_EINHEIT].month = 6;
00245     }
00246     else {
00247         feiertag[TAG_DER_DT_EINHEIT].day   = 3;
00248         feiertag[TAG_DER_DT_EINHEIT].month = 10;
00249     }
00250 }
00251 
00252 // --------------------------------------
00253 //      int Date::is_Feiertag() const
00254 // --------------------------------------
00255 int Date::is_Feiertag() const
00256 {
00257     if (year_calculated_for != year()) {
00258         calculateFeiertageFor(year());
00259     }
00260 
00261     for (int idx = FIRST; idx <= LAST; ++idx) {
00262         if (matches(idx, *this)) return idx;
00263     }
00264     return NO_FEIERTAG;
00265 }
00266 
00267 
00268 // -end- of implementation of class Date.
00269 
00270 // ------------------------------------------------------
00271 //      static void testValidIndex(int feiertag_idx)
00272 // ------------------------------------------------------
00273 static void testValidIndex(int feiertag_idx) {
00274     if (feiertag_idx<FIRST || feiertag_idx>LAST) {
00275         throw Error("Illegal 'Feiertag' index");
00276     }
00277 }
00278 
00279 namespace rs {
00280     namespace date {
00281         // --------------------------------------------------------
00282         //      const char *name_of_Feiertag(int feiertag_idx)
00283         // --------------------------------------------------------
00284         const char *name_of_Feiertag(int feiertag_idx) {
00285             testValidIndex(feiertag_idx);
00286             return feiertag[feiertag_idx].name;
00287         }
00288 
00289         // --------------------------------------------
00290         //      bool is_catholic(int feiertag_idx)
00291         // --------------------------------------------
00292         bool is_catholic(int feiertag_idx) {
00293             testValidIndex(feiertag_idx);
00294             return feiertag[feiertag_idx].catholic;
00295         }
00296     };
00297 };

Contact me in case of errors or questions.
This documentation is powered by Doxygen.
(C) 2000-2002 Doxygen