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
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 class time_date: public tm
00028 {
00029 bool good_parse;
00030 public:
00031 time_date & now( void )
00032 {
00033 time_t lt;
00034 time(<);
00035 localtime_r(<,this);
00036 return *this;
00037 }
00038 time_date():tm(),good_parse(false)
00039 {
00040 now();
00041 }
00042 time_date( const time_date & in )
00043 :tm(dynamic_cast< const tm & >(in)),good_parse(in.good_parse)
00044 {;}
00045 time_date( const tm & in )
00046 :tm(dynamic_cast< const tm & >(in)),good_parse(false)
00047 {;}
00048 time_date & operator = ( const time_date in )
00049 {
00050 good_parse = in.good_parse;
00051 dynamic_cast< tm & >( *this ) = dynamic_cast< const tm & >(in);
00052 return * this;
00053 }
00054 time_date & operator = ( const tm & in )
00055 {
00056 dynamic_cast< tm & >( *this ) = in;
00057 return *this;
00058 }
00059 virtual ~time_date(){;}
00060
00061 int addSeconds( int seconds )
00062 {
00063 return (tm_sec+=seconds);
00064 }
00065 int addMinutes( int minutes )
00066 {
00067 return (tm_min+=minutes);
00068 }
00069 int addHours( int hours )
00070 {
00071 return (tm_hour+=hours);
00072 }
00073 int addDays( int days )
00074 {
00075 return (tm_mday+=days);
00076 }
00077 int addMonths( int months )
00078 {
00079 return (tm_mon+=months);
00080 }
00081 int addYears( int years )
00082 {
00083 return (tm_year+=years)+1900;
00084 }
00085 time_t normalize( void )
00086 {
00087 return mktime( & dynamic_cast< tm & >( *this ));
00088 }
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 string format( const char *format, size_t max = 256) const
00102 {
00103 char * temp = new char[max+1];
00104 strftime(temp, max, format, this);
00105 string strTemp = temp;
00106 delete [] temp;
00107 return strTemp;
00108 }
00109 time_date & parse( const char * strTime, const char * strFormat )
00110 {
00111 *this=tm();
00112 good_parse = strptime(strTime, strFormat, this) != 0;
00113 return *this;
00114 }
00115
00116
00117 int seconds(void) { return tm_sec; }
00118 int minutes(void) { return tm_min; }
00119 int hour(void) { return tm_hour; }
00120 int clock_hour(void) { return (tm_hour%12==0?12:tm_hour%12); }
00121 char clock_period(void) { return tm_hour>11?'P':'A'; }
00122 int day_of_month(void) { return tm_mday; }
00123 int month(void) { return tm_mon+1; }
00124 int year(void) { return tm_year+1900; }
00125 int day_of_week(void) { return tm_wday; }
00126 int day_of_year( void ){ return tm_yday; }
00127 int is_DST(void) { return tm_isdst; }
00128
00129 void seconds(int in) { tm_sec=in; }
00130 void minutes(int in) { tm_min=in; }
00131 void hour(int in) { tm_hour=in; }
00132 void day_of_month(int in) { tm_mday=in; }
00133 void month(int in) { tm_mon=in-1; }
00134 void year(int in) { tm_year=in-1900; }
00135 void is_DST(int in) { tm_isdst=in; }
00136
00137 bool is_good_parse(void){return good_parse;}
00138 };
00139
00140
00141 class oc_date : public time_date
00142 {
00143 string fmt;
00144 public:
00145 oc_date():time_date(),fmt("%m/%d/%Y"){;}
00146 oc_date( const time_date & in ):time_date(in),fmt("%m/%d/%Y"){;}
00147 oc_date( const tm & in ):time_date(in),fmt("%m/%d/%Y"){;}
00148 oc_date & operator = ( const tm & in )
00149 {
00150 dynamic_cast< tm & >( *this ) = in;
00151 return *this;
00152 }
00153 oc_date & operator = ( const oc_date & in )
00154 {
00155 dynamic_cast< tm & >( *this ) = dynamic_cast< const tm & >(in);
00156 return *this;
00157 }
00158 ~oc_date(){;}
00159 string format ( size_t max = 256) const
00160 {
00161 return time_date::format( fmt.c_str(), max );
00162 }
00163 oc_date & setFormat( string fmtIn )
00164 {
00165 fmt = fmtIn;
00166 return *this;
00167 }
00168 oc_date & parse( const char * strDate )
00169 {
00170 ocString newDate = strDate;
00171 time_date::parse( newDate.replaceAll("-","/").c_str(), fmt.c_str() );
00172 return *this;
00173 }
00174 };
00175
00176 class oc_time : public time_date
00177 {
00178 string fmt;
00179 public:
00180 oc_time():time_date(),fmt("%I:%M %p"){;}
00181 oc_time( const time_date & in ):time_date(in),fmt("%I:%M %p"){;}
00182 oc_time( const tm & in ):time_date(in),fmt("%I:%M %p"){;}
00183 oc_time & operator = ( const tm & in )
00184 {
00185 dynamic_cast< tm & >( *this ) = in;
00186 return *this;
00187 }
00188 ~oc_time(){;}
00189
00190 oc_time & milTime(void) { fmt="%H:%M:%S"; return *this;}
00191 oc_time & milTimeNoSec(void) { fmt="%H:%M"; return *this;}
00192 oc_time & noSec(void) { fmt="%I:%M %p"; return *this; }
00193 oc_time & withSec(void) { fmt="%I:%M:%S %p"; return *this;}
00194 oc_time & setFormat( string fmtIn )
00195 {
00196 fmt = fmtIn;
00197 return *this;
00198 }
00199 string format ( size_t max = 256) const
00200 {
00201 return time_date::format( fmt.c_str(), max );
00202 }
00203 oc_time & parse( const char * strDate )
00204 {
00205 ocString newDate = strDate;
00206 time_date::parse( newDate.c_str(), fmt.c_str() );
00207
00208
00209 day_of_month(4); month(1); year(2006);
00210 return *this;
00211 }
00212 };
00213
00214 inline std::ostream& operator << (std::ostream & strm, const oc_date & theDate )
00215 {
00216 strm << theDate.format();
00217 return strm;
00218 }
00219 inline std::ostream& operator << (std::ostream & strm, const time_date & theTimeDate )
00220 {
00221 strm << theTimeDate.format("%m/%d/%Y %H:%M");
00222 return strm;
00223 }
00224 inline std::ostream& operator << (std::ostream & strm, const oc_time & theTime )
00225 {
00226 strm << theTime.format();
00227 return strm;
00228 }
00229
00230 typedef class money
00231 {
00232 double m_d;
00233 void localeSet( void )
00234 {
00235 localeconv();
00236 setlocale( LC_MONETARY, "en_US" );
00237 }
00238 public:
00239
00240 money():m_d()
00241 { localeSet(); }
00242 ~money()
00243 { localeSet(); }
00244 money(const money & in):m_d(in.m_d)
00245 { localeSet(); }
00246 money(double in):m_d(in)
00247 { localeSet(); }
00248 money & operator = (const money & in)
00249 {
00250 m_d = in.m_d;
00251 }
00252 money & operator = (const double & in)
00253 {
00254 m_d = in;
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 string format ( const char * spec, size_t max = 256 ) const
00269 {
00270 char * temp = new char[max+1];
00271 strfmon(temp, max, spec, m_d);
00272 string strTemp = temp;
00273 delete [] temp;
00274 return strTemp;
00275 }
00276 long whole( void )
00277 {
00278 long l = long();
00279 double w;
00280 double f = modf(m_d, &w);
00281 if( !isnan(w)) l = static_cast<long>(w);
00282 return l;
00283 }
00284 long fractional( void )
00285 {
00286 long l = long();
00287 double w;
00288 double f = modf(m_d, &w);
00289 if( !isnan(f))
00290 {
00291
00292
00293
00294
00295 char buf[8];
00296 f*=100;
00297 sprintf(buf,"%.2f",fabs(f));
00298 l = atol(buf);
00299 }
00300 return l;
00301 }
00302 double & amount(void) { return m_d; }
00303 };
00304
00305 inline std::ostream& operator << (std::ostream & strm, const money & mony )
00306 {
00307 strm << mony.format("%n");
00308 return strm;
00309 }
00310 #endif
00311 #ifdef IN_T2_TESTHARNESS
00312
00313
00314 {
00315
00316 time_date td;
00317 cout << "NOW" << endl;
00318 cout << td << endl;
00319
00320 td.addDays(300);
00321 td.normalize();
00322 cout << "NORMALIZED NOW + 300 DAYS" << endl;
00323 cout << td << endl;
00324 td.addMonths(15);
00325 td.normalize();
00326 cout << "NORMALIZED NOW + 15 MONTHS, 300 DAYS" << endl;
00327 cout << td << endl;
00328 tm t = tm();
00329 td = t;
00330 cout << "TIME ZERO: " << endl;
00331 cout << td << endl;
00332 td.year(2007);
00333 td.normalize();
00334 cout << "NORMALIZED TIME Y2007: " << endl;
00335 cout << td << endl;
00336 td.addDays(-3);
00337 td.normalize();
00338 cout << td << endl;
00339 cout << "day of week: " << td.day_of_week() << endl;
00340 td.addMonths(2);
00341 td.normalize();
00342 cout << td << endl;
00343 cout << "sequence day of week: " << td.day_of_week() << endl;
00344 td.addDays(1);
00345 td.normalize();
00346 cout << td << endl;
00347 cout << "sequence day of week: " << td.day_of_week() << endl;
00348 td.addDays(1);
00349 td.normalize();
00350 cout << td << endl;
00351 cout << "sequence day of week: " << td.day_of_week() << endl;
00352 td.addDays(1);
00353 td.normalize();
00354 cout << td << endl;
00355 cout << "sequence day of week: " << td.day_of_week() << endl;
00356 td.addDays(1);
00357 td.normalize();
00358 cout << td << endl;
00359 cout << "sequence day of week: " << td.day_of_week() << endl;
00360 td.addDays(1);
00361 td.normalize();
00362 cout << td << endl;
00363 cout << "sequence day of week: " << td.day_of_week() << endl;
00364 cout << td << endl;
00365 td.addYears(1);
00366 td.normalize();
00367 cout << td << endl;
00368 cout << "addYears(1) day of week: " << td.day_of_week() << endl;
00369 cout << td << endl;
00370 td.addYears(1);
00371 td.normalize();
00372 cout << td << endl;
00373 cout << "addYears(1) day of week: " << td.day_of_week() << endl;
00374 cout << td << endl;
00375 td.now();
00376 td.normalize();
00377 cout << td << endl;
00378 cout << "now() day of week: " << td.day_of_week() << endl;
00379 cout << td << endl;
00380 td.addDays(1);
00381 td.normalize();
00382
00383 cout << td << endl;
00384 td.addDays(1);
00385 td.normalize();
00386 cout << td << endl;
00387 cout << "addDays(1) day of week: " << td.day_of_week() << endl;
00388
00389 td.addDays(-1);
00390 td.normalize();
00391 cout << td << endl;
00392 cout << "addDays(-1) day of week: " << td.day_of_week() << endl;
00393
00394
00395 td.addDays(1);
00396 td.normalize();
00397 cout << td << endl;
00398 cout << "addDays(1) day of week: " << td.day_of_week() << endl;
00399
00400
00401 td.addDays(-7);
00402 td.normalize();
00403 cout << td << endl;
00404 cout << "addDays(-7) day of week: " << td.day_of_week() << endl;
00405
00406
00407 td.addDays(1);
00408 td.normalize();
00409 cout << td << endl;
00410 cout << "addDays(1) day of week: " << td.day_of_week() << endl;
00411
00412
00413 td.addDays(1);
00414 td.normalize();
00415 cout << td << endl;
00416 cout << "addDays(1) day of week: " << td.day_of_week() << endl;
00417
00418
00419 td.addDays(1);
00420 td.normalize();
00421 cout << td << endl;
00422 cout << "addDays(1) day of week: " << td.day_of_week() << endl;
00423
00424
00425 td.addDays(1);
00426 td.normalize();
00427 cout << td << endl;
00428 cout << "addDays(1) day of week: " << td.day_of_week() << endl;
00429
00430
00431 td.addDays(1);
00432 td.normalize();
00433 cout << td << endl;
00434 cout << "addDays(1) day of week: " << td.day_of_week() << endl;
00435
00436
00437 td.addDays(1);
00438 td.normalize();
00439 cout << td << endl;
00440 cout << "addDays(1) day of week: " << td.day_of_week() << endl;
00441
00442
00443 td.addDays(1);
00444 td.normalize();
00445 cout << td << endl;
00446 cout << "addDays(1) day of week: " << td.day_of_week() << endl;
00447
00448
00449 td.addDays(1);
00450 td.normalize();
00451 cout << td << endl;
00452 cout << "day of week: " << td.day_of_week() << endl;
00453
00454 td.addSeconds(-12);
00455 td.normalize();
00456 cout << "LAST TIME -12 seconds : " << endl;
00457 cout << "Time: " << td.hour() << ":" << td.minutes() << ":" << td.seconds() << endl;
00458 cout << "Date: " << td.year() << "-" << td.month() << "-" << td.day_of_month() << endl;
00459 cout << "Clock Time: " << td.clock_hour() << ":" << td.minutes() << " "
00460 << td.clock_period() << "M." << endl;
00461 td.addHours(7);
00462 td.normalize();
00463 cout << "LAST TIME +7 hours : " << endl;
00464 cout << "Time: " << td.hour() << ":" << td.minutes() << ":" << td.seconds() << endl;
00465 cout << "Date: " << td.year() << "-" << td.month() << "-" << td.day_of_month() << endl;
00466 cout << "Clock Time: " << td.clock_hour() << ":" << td.minutes() << " "
00467 << td.clock_period() << "M." << endl;
00468 td.addHours(7);
00469 td.normalize();
00470 cout << "LAST TIME +7 hours : " << endl;
00471 cout << "Time: " << td.hour() << ":" << td.minutes() << ":" << td.seconds() << endl;
00472 cout << "Date: " << td.year() << "-" << td.month() << "-" << td.day_of_month() << endl;
00473 cout << "Clock Time: " << td.clock_hour() << ":" << td.minutes() << " "
00474 << td.clock_period() << "M." << endl;
00475 td.addHours(7);
00476 td.normalize();
00477 cout << "LAST TIME +7 hours : " << endl;
00478 cout << "Time: " << td.hour() << ":" << td.minutes() << ":" << td.seconds() << endl;
00479 cout << "Date: " << td.year() << "-" << td.month() << "-" << td.day_of_month() << endl;
00480 cout << "Clock Time: " << td.clock_hour() << ":" << td.minutes() << " "
00481 << td.clock_period() << "M." << endl;
00482 td.addHours(7);
00483 td.normalize();
00484 cout << "LAST TIME +7 hours : " << endl;
00485 cout << "Time: " << td.hour() << ":" << td.minutes() << ":" << td.seconds() << endl;
00486 cout << "Date: " << td.year() << "-" << td.month() << "-" << td.day_of_month() << endl;
00487 cout << "Clock Time: " << td.clock_hour() << ":" << td.minutes() << " "
00488 << td.clock_period() << "M." << endl;
00489 td.now();
00490 cout << "NOW" << endl;
00491 cout << "Time: " << td.hour() << ":" << td.minutes() << ":" << td.seconds() << endl;
00492 cout << "Date: " << abs(td.year()) << "-" << td.month() << "-" << td.day_of_month() << endl;
00493 cout << "Clock Time: " << td.clock_hour() << ":" << td.minutes() << " "
00494 << td.clock_period() << "M." << endl;
00495 string strDT = td.format( "%m/%d/%Y %I:%M:%S %p" );
00496 cout << strDT << endl;
00497 td = t;
00498
00499
00500 td.day_of_month(210);
00501 td.year(1960);
00502 td.month(1);
00503 td.normalize();
00504 cout << "TIME ZERO: " << td.format( "%m/%d/%Y %I:%M:%S %p" ) << endl;
00505 td.parse(strDT.c_str(),"%m/%d/%Y %I:%M:%S %p");
00506 cout << "TIME RESTORED: " << td.format( "%m/%d/%Y %I:%M:%S %p" ) << endl;
00507
00508
00509 string testDate = "2006-12-31";
00510 cout << "test parse failures & successes for : " << testDate << endl;
00511 td.parse(testDate.c_str(),"%m-%d-%Y");
00512 cout << "Parse Success for %m-%d-%Y? " << td.is_good_parse() << endl;
00513
00514 if( !td.is_good_parse() )
00515 {
00516 cout << "Try alternate (working) parse FMT: " << endl;
00517 td.parse(testDate.c_str(),"%Y-%m-%d");
00518 cout << "Parse Success for %Y-%m-%d? " << td.is_good_parse() << endl;
00519 cout << "DATE: " << td.format( "%m/%d/%Y" ) << endl;
00520 }
00521 else
00522 {
00523 cout << "AHRGGG!*&*(&() Parse Success when it SHOULDN'T" << endl;
00524 }
00525
00526
00527
00528 money m = 723.44;
00529 cout << "MONEY: " << m.format("%n") << endl;
00530 cout << " WHOLE: " << m.whole() << " FRACTIONAL: " << m.fractional() << endl;
00531 m.amount()+=5612.33;
00532 cout << "MONEY: " << m.format("%n") << endl;
00533 money more_money;
00534 more_money = 2345.43;
00535 cout << "MORE MONEY: " << more_money.format("%n") << endl;
00536 m.amount() *= more_money.amount();
00537 cout << "MONEY X MORE MONEY: " << m.format("%n") << endl;
00538
00539
00540 oc_date myDate;
00541 cout << "current date: " << myDate << endl;
00542 myDate.parse("10/27/1972");
00543 cout << "birth date: " << myDate << endl;
00544 myDate.addDays(5);
00545 myDate.normalize();
00546 cout << "five days after birthday: " << myDate << endl;
00547
00548
00549 cout << "Testing money again for neg value " << -23.99 << endl;
00550 money mny = -23.99;
00551 cout << " WHOLE: " << mny.whole() << " FRACTIONAL: " << mny.fractional() << endl;
00552 double dt = -23.05;
00553 cout << "Testing money again for neg value " << dt << endl;
00554 mny = dt;
00555 cout << " WHOLE: " << mny.whole() << " FRACTIONAL: " << mny.fractional() << endl;
00556
00557 dt = 23.05;
00558 cout << "Testing money again for pos value " << dt << endl;
00559 mny = dt;
00560 cout << " WHOLE: " << mny.whole() << " FRACTIONAL: " << mny.fractional() << endl;
00561
00562
00563 cout << endl << "Testing for specific problems in production on oc_date" << endl;
00564
00565 oc_date baddt;
00566 for(int xx=0;xx<10;xx++)
00567 {
00568 baddt.parse("01/27/2006");
00569 cout << "BAD DATE 1st:" << baddt << endl;
00570 baddt.normalize();
00571 cout << "BAD DATE normalized:" << baddt << endl;
00572 for(int x=0; x<35; x++ )
00573 {
00574 baddt.addDays(1);
00575 cout << "BAD DATE day added:" << baddt << endl;
00576 baddt.normalize();
00577 cout << "BAD DATE normalized:" << baddt << endl;
00578 }
00579 }
00580 }
00581
00582 oc_time testTime;
00583 cout << "test time instance:" << testTime << endl;
00584 cout << "try to break it" << endl;
00585 testTime.parse("44:23:22");
00586 cout << "test time after parse 44:23:22:" << testTime << endl;
00587 testTime.normalize();
00588 cout << "test time after parse 44:23 22:" << testTime << endl;
00589
00590 testTime.parse("12:23:22 am");
00591 cout << "test time after parse 12:23:22 am:" << testTime << endl;
00592
00593 testTime.parse("12:23 am");
00594 cout << "test time after parse 12:23 am:" << testTime << endl;
00595 cout << "milTime: " << testTime.milTime() << endl;
00596
00597
00598
00599 for(int h=0;h<24;h++)
00600 {
00601 cout << "hour " << h << " ";
00602 testTime.addHours(1);
00603 time_t t = testTime.normalize();
00604
00605 cout << t << " time: " << testTime << " ";
00606 }
00607 for(int m=0;m<240;m++)
00608 {
00609 cout << "minute " << m << " ";
00610 testTime.addMinutes(m);
00611 time_t t = testTime.normalize();
00612 cout << t << " time: " << testTime << " ";
00613 }
00614
00615 oc_time t1Time;
00616 t1Time.setFormat("%I:%M %p");
00617 t1Time.parse( "11:34 AM" );
00618 t1Time.normalize();
00619
00620 cout << t1Time.time_date::format("%I:%M %p") << " should be 11:34 AM" << endl;
00621
00622 cout << "testing time_date" << endl;
00623
00624 time_date Request_Time;
00625 cout << "before parse " << Request_Time << " next parse 10/27/1957 12:33 " << endl;
00626 string fmt = "%m/%d/%Y %H:%M";
00627 string val = "10/27/1957 12:33";
00628 Request_Time.parse(val.c_str(),fmt.c_str());
00629 Request_Time.normalize();
00630 cout << "x good parse? " << Request_Time.is_good_parse() << " format " << Request_Time.format( "%d/%b/%Y %T" ) << endl;
00631
00632 oc_date addt;
00633 cout << "before parse " << addt << endl;
00634 addt.parse( "10/27/1997" );
00635 cout << "x good parse? " << addt.is_good_parse() << " format " << addt << endl;
00636
00637
00638
00639 #endif
00640
00641