Main Page   Class Hierarchy   File List  

ocTypes.h

00001 #ifndef OC_TYPES_H
00002 #define OC_TYPES_H
00003 
00004 #include <cstdlib>
00005 #include <memory.h>
00006 #include <sys/types.h>
00007 #include <locale.h>
00008 #include <time.h>
00009 #include <monetary.h>
00010 #include <math.h>
00011 #include "ocString.h"
00012 using namespace std;
00013 /*
00014   class time_date:
00015   inherits tm:
00016     int tm_sec;    Seconds. [0-60] (1 leap second)
00017     int tm_min;    Minutes. [0-59]
00018     int tm_hour;   Hours. [0-23]
00019     int tm_mday;   Day.  [1-31]
00020     int tm_mon;    Month. [0-11]
00021     int tm_year;   Year - 1900.
00022     int tm_wday;   Day of week. [0-6]
00023     int tm_yday;   Days in year.[0-365]
00024     int tm_isdst;  DST.  [-1/0/1]
00025 */ 
00026 class time_date: public tm
00027 {
00028 public:
00029   time_date & now( void )
00030   {
00031     time_t lt;
00032     time(&lt);
00033     localtime_r(&lt,this);  
00034   }
00035   time_date():tm()
00036   {
00037     now();
00038   }
00039   time_date( const time_date & in )
00040   :tm(dynamic_cast< const tm & >(in))
00041   {;}
00042   time_date( const tm & in )
00043   :tm(dynamic_cast< const tm & >(in))
00044   {;}
00045   time_date & operator = ( const time_date in )
00046   {
00047     dynamic_cast< tm & >( *this ) = dynamic_cast< const tm & >(in);
00048     return * this;
00049   }
00050   time_date & operator = ( const tm & in )
00051   {
00052     dynamic_cast< tm & >( *this ) = in;
00053   }
00054   virtual ~time_date(){;}  
00055  
00056   int addSeconds( int seconds )
00057   {
00058     return (tm_sec+=seconds);
00059   }
00060   int addMinutes( int minutes )
00061   {
00062     return (tm_min+=minutes);
00063   }
00064   int addHours( int hours )
00065   {
00066     return (tm_hour+=hours);
00067   }  
00068   int addDays( int days )
00069   {
00070     return (tm_mday+=days);
00071   }
00072   int addMonths( int months )
00073   {
00074     return (tm_mon+=months);
00075   }
00076   int addYears( int years )
00077   {
00078     return (tm_year+=years)+1900;
00079   }
00080   void normalize( void )
00081   {
00082     mktime(this);
00083   }
00084   /* 
00085     Typical format specifiers:
00086     %m := month[01,12], %M := minute[[00,59]]
00087     %a := abreviated weekday name, %A := full weekday anme
00088     %b := abbreviated month name, %B := full month name.
00089     %c := locale date, %d := day of month[01,31] 
00090     %p := [a.m.,p.m.] 
00091     %H := 24 hour hour[00,23], %I := 12 hour hour[01,12]
00092     %S := seconds[00,61]
00093     %y := 2 digit year, %Y := 4 digit year     
00094   */  
00095   string format( const char *format, size_t max = 256) const
00096   {
00097     char * temp = new char[max+1];
00098     strftime(temp, max, format, this);
00099     string strTemp = temp;
00100     delete [] temp;
00101     return strTemp;
00102   }    
00103   time_date & parse( const char * strTime, const char * strFormat )
00104   {
00105     *this=tm();
00106     strptime(strTime, strFormat, this);
00107     return *this;
00108   }
00109           
00110   // encapsulated get access
00111   int seconds(void)      { return tm_sec; }   //  Zero based Seconds. [0-60] (1 leap second) 
00112   int minutes(void)      { return tm_min; }   //  Zero based Minutes. [0-59]
00113   int hour(void)         { return tm_hour; }  //  Zero based Hour of day. [0-23]
00114   int clock_hour(void)   { return (tm_hour%12==0?12:tm_hour%12); } // hours [1-12]
00115   char clock_period(void) { return tm_hour>11?'P':'A'; } // morning or evening [A,P]
00116   int day_of_month(void) { return tm_mday; }  //  Day of Month.  [1-31]
00117   int month(void)        { return tm_mon+1; } //  Month. [1-12]
00118   int year(void)         { return tm_year+1900; } //  Year.
00119   int day_of_week(void)  { return tm_wday; }  // Day of week. [1-7]
00120   int day_of_year( void ){ return tm_yday; }  //  Days in year.[0-365]
00121   int is_DST(void)       { return tm_isdst; } //  DST.  [-1 == indeterminant/0=no/1=true]   
00122   // encapsulated set access
00123   void seconds(int in)      { tm_sec=in; }   //  Zero based Seconds. [0-60] (1 leap second) 
00124   void minutes(int in)      { tm_min=in; }   //  Zero based Minutes. [0-59]
00125   void hour(int in)         { tm_hour=in; }  //  Zero based Hour of day. [0-23]
00126   void day_of_month(int in) { tm_mday=in; }  //  Day of Month.  [1-31]
00127   void month(int in)        { tm_mon=in-1; } //  Month. [1-12]
00128   void year(int in)         { tm_year=in-1900; }    //  Year.  
00129   void is_DST(int in)       { tm_isdst=in; } //  DST.  [-1 == indeterminant/0=no/1=true]    
00130 };
00131 
00132 // specializations
00133 class oc_date : public time_date
00134 {
00135   string fmt; 
00136 public:
00137   oc_date():time_date(),fmt("%m/%d/%Y"){;}
00138   oc_date( const time_date & in ):time_date(in),fmt("%m/%d/%Y"){;}
00139   oc_date( const tm & in ):time_date(in),fmt("%m/%d/%Y"){;}
00140   oc_date & operator = ( const tm & in )
00141   {
00142     dynamic_cast< tm & >( *this ) = in;
00143     return *this;
00144   }
00145   ~oc_date(){;}
00146   string format ( size_t max = 256) const
00147   {
00148     return time_date::format( fmt.c_str(), max );
00149   }    
00150   oc_date & parse( const char * strDate )
00151   {
00152     ocString newDate = strDate;
00153     time_date::parse( newDate.replaceAll("-","/").c_str(), fmt.c_str() ); 
00154     return *this;
00155   }
00156 };
00157 inline std::ostream& operator << (std::ostream & strm, const oc_date & theDate )
00158 {
00159   strm << theDate.format();
00160   return strm;
00161 }
00162 inline std::ostream& operator << (std::ostream & strm, const time_date & theTimeDate )
00163 {
00164   strm << theTimeDate.format("%m/%d/%Y  %I:%M:%S %p");
00165   return strm;
00166 }
00167 
00168 typedef class money
00169 {
00170  double m_d;
00171   void localeSet( void )
00172   {
00173     localeconv(); //initialize the locale struct
00174     setlocale( LC_MONETARY, "en_US" ); // make sure its set for english US  
00175   }
00176 public:
00177   // double m_d;
00178   money():m_d()
00179   { localeSet(); }
00180   ~money()
00181   { localeSet(); }
00182   money(const money & in):m_d(in.m_d)
00183   { localeSet(); }
00184   money(double in):m_d(in)
00185   { localeSet(); }
00186   money & operator = (const money & in)
00187   {
00188     m_d = in.m_d;
00189   }
00190   money & operator = (const double & in)
00191   {
00192     m_d = in;
00193   }
00194   /*
00195     Format specifiers: expression preceded by %
00196     =f  := specify fill character 'f' 
00197     ^   := no monetary grouping
00198     w   := justified field width
00199     #n  := whole precision
00200     .p  := fractional precision
00201     n   := default format for locale   
00202     !   := suppress currency symbol
00203     -   := left align
00204     
00205   */  
00206   string format ( const char * spec, size_t max = 256 ) const
00207   {    
00208     char * temp = new char[max+1];
00209     strfmon(temp, max, spec, m_d);
00210     string strTemp = temp;
00211     delete [] temp;
00212     return strTemp;  
00213   }
00214   long whole( void )
00215   {
00216     long l = long();
00217     double w;
00218     double f = modf(m_d, &w);
00219     if( !isnan(w)) l = static_cast<long>(w);
00220     return l;
00221   }  
00222   long fractional( void )
00223   {
00224     long l = long();
00225     double w;
00226     double f = modf(m_d, &w);
00227     if( !isnan(f)) 
00228     {
00229       // this has a math lib bug, commented out till fsf fixes it
00230       // l = static_cast<long>(f*100.00);
00231       
00232       // a workaround...
00233       char buf[8];
00234       f*=100;
00235       sprintf(buf,"%.2f",fabs(f));
00236       l = atol(buf);      
00237     }
00238     return l;    
00239   }
00240   double & amount(void) { return m_d; }
00241 };
00242 inline std::ostream& operator << (std::ostream & strm, const money & mony )
00243 {
00244   strm << mony.format("%n");
00245   return strm;
00246 }
00247 #endif
00248 #ifdef IN_T2_TESTHARNESS
00249 /* test harness */  
00250   time_date td;
00251   cout << "NOW" << endl;
00252   cout << td << endl;
00253   
00254   td.addDays(300);
00255   td.normalize();
00256   cout << "NORMALIZED NOW + 300 DAYS" << endl;
00257   cout << td << endl;
00258   td.addMonths(15);
00259   td.normalize();
00260   cout << "NORMALIZED NOW + 15 MONTHS, 300 DAYS" << endl;
00261   cout << td << endl;  
00262   tm t = tm();  // zeroed struct
00263   td = t;
00264   cout << "TIME ZERO: " << endl;
00265   cout << td << endl;    
00266   td.year(2007);
00267   td.normalize();
00268   cout << "NORMALIZED TIME Y2007: " << endl;
00269   cout << td << endl;
00270   td.addDays(-3);
00271   td.normalize();
00272   cout << td << endl;
00273   td.addMonths(2);
00274   td.normalize();
00275   cout << td << endl;
00276   td.addDays(1);
00277   td.normalize();
00278   cout << td << endl;
00279   td.addDays(-1);
00280   td.normalize();
00281   td.addYears(1);
00282   td.normalize();
00283   cout << td << endl;
00284   td.addDays(1);
00285   td.normalize();
00286   cout << td << endl;
00287   td.addDays(-1);
00288   td.normalize();
00289   cout << td << endl;
00290   td.addYears(1);
00291   td.normalize();
00292   cout << td << endl;
00293   td.addYears(1);
00294   td.normalize();
00295   cout << td << endl;
00296   td.addDays(1);
00297   td.normalize();
00298   cout << td << endl;
00299   td.addDays(-1);
00300   
00301   td.addYears(1);
00302   td.normalize();
00303   cout << td << endl;
00304   td.addDays(1);
00305   td.normalize();
00306   cout << td << endl;
00307   td.addSeconds(-12);
00308   td.normalize();
00309   cout << "LAST TIME -12 seconds : " << endl;
00310   cout << "Time: " << td.hour() << ":" << td.minutes() << ":" << td.seconds() << endl;
00311   cout << "Date: " << td.year() << "-" << td.month() << "-" << td.day_of_month() << endl;
00312   cout << "Clock Time: " << td.clock_hour() << ":" << td.minutes() << " " 
00313        << td.clock_period() << "M." << endl;  
00314   td.addHours(7);
00315   td.normalize();
00316   cout << "LAST TIME +7 hours : " << endl;
00317   cout << "Time: " << td.hour() << ":" << td.minutes() << ":" << td.seconds() << endl;
00318   cout << "Date: " << td.year() << "-" << td.month() << "-" << td.day_of_month() << endl;
00319   cout << "Clock Time: " << td.clock_hour() << ":" << td.minutes() << " " 
00320        << td.clock_period() << "M." << endl;    
00321   td.addHours(7);
00322   td.normalize();
00323   cout << "LAST TIME +7 hours : " << endl;
00324   cout << "Time: " << td.hour() << ":" << td.minutes() << ":" << td.seconds() << endl;
00325   cout << "Date: " << td.year() << "-" << td.month() << "-" << td.day_of_month() << endl;
00326   cout << "Clock Time: " << td.clock_hour() << ":" << td.minutes() << " " 
00327        << td.clock_period() << "M." << endl;   
00328   td.addHours(7);
00329   td.normalize();
00330   cout << "LAST TIME +7 hours : " << endl;
00331   cout << "Time: " << td.hour() << ":" << td.minutes() << ":" << td.seconds() << endl;
00332   cout << "Date: " << td.year() << "-" << td.month() << "-" << td.day_of_month() << endl;
00333   cout << "Clock Time: " << td.clock_hour() << ":" << td.minutes() << " " 
00334        << td.clock_period() << "M." << endl;   
00335   td.addHours(7);
00336   td.normalize();
00337   cout << "LAST TIME +7 hours : " << endl;
00338   cout << "Time: " << td.hour() << ":" << td.minutes() << ":" << td.seconds() << endl;
00339   cout << "Date: " << td.year() << "-" << td.month() << "-" << td.day_of_month() << endl;
00340   cout << "Clock Time: " << td.clock_hour() << ":" << td.minutes() << " " 
00341        << td.clock_period() << "M." << endl;    
00342   td.now();
00343   cout << "NOW" << endl;
00344   cout << "Time: " << td.hour() << ":" << td.minutes() << ":" << td.seconds() << endl;
00345   cout << "Date: " << abs(td.year()) << "-" << td.month() << "-" << td.day_of_month() << endl;
00346   cout << "Clock Time: " << td.clock_hour() << ":" << td.minutes() << " " 
00347        << td.clock_period() << "M." << endl; 
00348   string strDT = td.format( "%m/%d/%Y  %I:%M:%S %p" );
00349   cout << strDT << endl;  
00350   td = t;
00351   
00352   // Fails! normalize 'mktime' fails before 1970!
00353   td.day_of_month(210);
00354   td.year(1960);
00355   td.month(1);
00356   td.normalize();
00357   cout << "TIME ZERO: " << td.format( "%m/%d/%Y  %I:%M:%S %p" ) << endl;
00358   td.parse(strDT.c_str(),"%m/%d/%Y  %I:%M:%S %p");
00359   cout << "TIME RESTORED: " << td.format( "%m/%d/%Y  %I:%M:%S %p" ) << endl;
00360   
00361   // money type
00362   money m = 723.44;
00363   cout << "MONEY: " << m.format("%n") << endl;
00364   cout << " WHOLE: " << m.whole()  << " FRACTIONAL: " << m.fractional() << endl;
00365   m.amount()+=5612.33;
00366   cout << "MONEY: " << m.format("%n") << endl;
00367   money more_money;
00368   more_money = 2345.43;
00369   cout << "MORE MONEY: " << more_money.format("%n") << endl;
00370   m.amount() *= more_money.amount();
00371   cout << "MONEY X MORE MONEY: " << m.format("%n") << endl;
00372   
00373   
00374   oc_date myDate;
00375   cout << "current date: " << myDate << endl;
00376   myDate.parse("10/27/1972");
00377   cout << "birth date: " << myDate << endl;
00378   myDate.addDays(5);
00379   myDate.normalize();
00380   cout << "five days after birthday: " << myDate << endl;
00381   
00382   // money type
00383   cout << "Testing money again for neg value " << -23.99 << endl;
00384   money mny = -23.99;
00385   cout << " WHOLE: " << mny.whole()  << " FRACTIONAL: " << mny.fractional() << endl;
00386   double dt = -23.05;
00387   cout << "Testing money again for neg value " << dt << endl;
00388   mny = dt;
00389   cout << " WHOLE: " << mny.whole()  << " FRACTIONAL: " << mny.fractional() << endl;
00390   
00391   dt = 23.05;
00392   cout << "Testing money again for pos value " << dt << endl;
00393   mny = dt;
00394   cout << " WHOLE: " << mny.whole()  << " FRACTIONAL: " << mny.fractional() << endl;
00395   
00396   
00397   
00398 /* end test harness */
00399 #endif
00400 
00401 

Generated on Tue Jan 20 09:03:27 2004 for OpenTools by doxygen1.2.18