cdate.cpp 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893
  1. //-----------------------------------------------------------------------------
  2. // @doc
  3. //
  4. // @module cdate.cpp : implementation file for <c CDate> |
  5. //
  6. // This file implements the functionality for a date processing
  7. // class, as well as parsing functionality and an example of one
  8. // way to implement a state machine in C++.
  9. //
  10. // Copyright <cp> 1995 Microsoft Corporation, All Rights Reserved
  11. //
  12. // Mark Snyder (MarkSn), Software Design Engineer/Test
  13. //
  14. #include "stdafx.h"
  15. #include "cdate.h"
  16. #include "ctype.h"
  17. // Parsing functions
  18. int Parse99NTor9NT(const char* lpChar, rcParse& rcp);
  19. int Parse99or9(const char* lpChar, rcParse& rcp);
  20. int Parse9999or99(const char* lpChar, rcParse& rcp);
  21. int ParseMonthName(const char* lpChar, rcParse& rcp);
  22. int Parse99Slashor9Slash(const char* lpChar, rcParse& rcp);
  23. int Parse99Colonor9Colon(const char* lpChar, rcParse& rcp);
  24. int Parse99Commaor9Comma(const char* lpChar, rcParse& rcp);
  25. int Parse9999Commaor99Comma(const char* lpChar, rcParse& rcp);
  26. int ParseDash(const char* lpChar, rcParse& rcp);
  27. int ParseEOM(const char* lpChar, rcParse& rcp);
  28. int Parse99NTor9NT(const char* lpChar, rcParse& rcp)
  29. {
  30. if (isdigit(*lpChar) && isdigit(*(lpChar+1)) && *(lpChar+2)=='N' && *(lpChar+3)=='T')
  31. {
  32. char szToken[3];
  33. szToken[0]=lpChar[0];
  34. szToken[1]=lpChar[2];
  35. szToken[2]='\0';
  36. rcp.nVal = atoi(szToken);
  37. rcp.nBump = 4;
  38. return 1;
  39. }
  40. if (isdigit(*lpChar) && *(lpChar+1)=='N' && *(lpChar+2)=='T')
  41. {
  42. char szToken[2];
  43. szToken[0]=lpChar[0];
  44. szToken[1]='\0';
  45. rcp.nVal = atoi(szToken);
  46. rcp.nBump = 3;
  47. return 1;
  48. }
  49. return 0;
  50. }
  51. int Parse99or9(const char* lpChar, rcParse& rcp)
  52. {
  53. if (isdigit(*lpChar) && isdigit(*(lpChar+1)) )
  54. {
  55. char szToken[3];
  56. szToken[0]=lpChar[0];
  57. szToken[1]=lpChar[1];
  58. szToken[2]='\0';
  59. rcp.nVal = atoi(szToken);
  60. rcp.nBump = 2;
  61. return 1;
  62. }
  63. if (isdigit(*lpChar))
  64. {
  65. char szToken[2];
  66. szToken[0]=lpChar[0];
  67. szToken[1]='\0';
  68. rcp.nVal = atoi(szToken);
  69. rcp.nBump = 1;
  70. return 1;
  71. }
  72. return 0;
  73. }
  74. int Parse9999or99(const char* lpChar, rcParse& rcp)
  75. {
  76. if (isdigit(*lpChar) && isdigit(*(lpChar+1)) && isdigit(*(lpChar+2)) && isdigit(*(lpChar+3)))
  77. {
  78. char szToken[5];
  79. szToken[0]=lpChar[0];
  80. szToken[1]=lpChar[1];
  81. szToken[2]=lpChar[2];
  82. szToken[3]=lpChar[3];
  83. szToken[4]='\0';
  84. rcp.nVal = atoi(szToken);
  85. rcp.nBump = 4;
  86. return 1;
  87. }
  88. if (isdigit(*lpChar) && isdigit(*(lpChar+1)) )
  89. {
  90. char szToken[3];
  91. szToken[0]=lpChar[0];
  92. szToken[1]=lpChar[1];
  93. szToken[2]='\0';
  94. rcp.nVal = atoi(szToken)+1900;
  95. rcp.nBump = 2;
  96. return 1;
  97. }
  98. return 0;
  99. }
  100. int ParseMonthName(const char* lpChar, rcParse& rcp)
  101. {
  102. static char Months[12][12] =
  103. {
  104. "january","february","march","april","may","june","july","august","september","october","november","december"
  105. };
  106. char target[12];
  107. // move the string that is supposed to be a month abbreviation to target[]
  108. for (int i=0;i<12;i++)
  109. {
  110. if( isalpha(*(lpChar+i)) )
  111. target[i] = tolower(*(lpChar+i));
  112. else
  113. {
  114. target[i]='\0';
  115. break;
  116. }
  117. }
  118. // if they didn't enter at least 3 characters, it's an error!
  119. if (lstrlen(target)<3)
  120. return 0;
  121. // see if target[] is an abbreviation for one of the month names
  122. for (i=0;i<12;i++)
  123. {
  124. if ( strstr(Months[i],target) )
  125. {
  126. rcp.nBump = lstrlen(target);
  127. rcp.nVal = i+1;
  128. return 1;
  129. }
  130. }
  131. // the string was not an abbreviation for a month, so...
  132. return 0;
  133. }
  134. int Parse99Slashor9Slash(const char* lpChar, rcParse& rcp)
  135. {
  136. if (isdigit(*lpChar) && isdigit(*(lpChar+1)) && *(lpChar+2)=='/' )
  137. {
  138. char szToken[3];
  139. szToken[0]=lpChar[0];
  140. szToken[1]=lpChar[1];
  141. szToken[2]='\0';
  142. rcp.nVal = atoi(szToken);
  143. rcp.nBump = 3;
  144. return 1;
  145. }
  146. if (isdigit(*lpChar) && *(lpChar+1)=='/' )
  147. {
  148. char szToken[2];
  149. szToken[0] = lpChar[0];
  150. szToken[1]='\0';
  151. rcp.nVal = atoi(szToken);
  152. rcp.nBump = 2;
  153. return 1;
  154. }
  155. return 0;
  156. }
  157. int Parse99Colonor9Colon(const char* lpChar, rcParse& rcp)
  158. {
  159. if (isdigit(*lpChar) && isdigit(*(lpChar+1)) && *(lpChar+2)==':' )
  160. {
  161. char szToken[3];
  162. szToken[0]=lpChar[0];
  163. szToken[1]=lpChar[1];
  164. szToken[2]='\0';
  165. rcp.nVal = atoi(szToken);
  166. rcp.nBump = 3;
  167. return 1;
  168. }
  169. if (isdigit(*lpChar) && *(lpChar+1)==':' )
  170. {
  171. char szToken[2];
  172. szToken[0]=lpChar[0];
  173. szToken[1]='\0';
  174. rcp.nVal = atoi(szToken);
  175. rcp.nBump = 2;
  176. return 1;
  177. }
  178. return 0;
  179. }
  180. int Parse99Commaor9Comma(const char* lpChar, rcParse& rcp)
  181. {
  182. if (isdigit(*lpChar) && isdigit(*(lpChar+1)) && *(lpChar+2)==',' )
  183. {
  184. char szToken[3];
  185. szToken[0]=lpChar[0];
  186. szToken[1]=lpChar[1];
  187. szToken[2]='\0';
  188. rcp.nVal = atoi(szToken);
  189. rcp.nBump = 3;
  190. return 1;
  191. }
  192. if (isdigit(*lpChar) && *(lpChar+1)==',' )
  193. {
  194. char szToken[2];
  195. szToken[0]=lpChar[0];
  196. szToken[1]='\0';
  197. rcp.nVal = atoi(szToken);
  198. rcp.nBump = 2;
  199. return 1;
  200. }
  201. return 0;
  202. }
  203. int Parse9999Commaor99Comma(const char* lpChar, rcParse& rcp)
  204. {
  205. if (isdigit(*lpChar) && isdigit(*(lpChar+1)) && isdigit(*(lpChar+2)) && isdigit(*(lpChar+3)) && *(lpChar+4)==',' )
  206. {
  207. char szToken[5];
  208. szToken[0]=lpChar[0];
  209. szToken[1]=lpChar[1];
  210. szToken[2]=lpChar[2];
  211. szToken[3]=lpChar[3];
  212. szToken[4]='\0';
  213. rcp.nVal = atoi(szToken);
  214. rcp.nBump = 5;
  215. return 1;
  216. }
  217. if (isdigit(*lpChar) && isdigit(*(lpChar+1)) && *(lpChar+2)==',' )
  218. {
  219. char szToken[3];
  220. szToken[0]=lpChar[0];
  221. szToken[1]=lpChar[1];
  222. szToken[2]='\0';
  223. rcp.nVal = atoi(szToken)+1900;
  224. rcp.nBump = 3;
  225. return 1;
  226. }
  227. return 0;
  228. }
  229. int ParseDash(const char* lpChar, rcParse& rcp)
  230. {
  231. if (*lpChar=='-' )
  232. {
  233. rcp.nVal = 0;
  234. rcp.nBump = 1;
  235. return 1;
  236. }
  237. return 0;
  238. }
  239. int ParseEOM(const char* lpChar, rcParse& rcp)
  240. {
  241. if (*lpChar=='\0' )
  242. {
  243. rcp.nVal = 0;
  244. rcp.nBump = 1;
  245. return 1;
  246. }
  247. return 0;
  248. }
  249. enum { State_Init=0, State_1, State_2, State_3, State_4, State_5,
  250. State_6, State_7, State_8, State_9, State_10, State_11, State_12,
  251. State_End, State_Error};
  252. // These templates are needed to allow us to add/sub any class to a CDate for which
  253. // CDate supplies the + and - that these use for valid math types, namely the
  254. // classes CMin, CSec, CHour, CMonth, CDay, and CYear.
  255. #define definePlusEquals(type) \
  256. CDate operator+=(CDate& d,const type& t) { d = d + type(t); return d; }
  257. #define defineMinusEquals(type) \
  258. CDate operator-=(CDate& d,const type& t) { d = d - type(t); return d; }
  259. definePlusEquals(CYear)
  260. defineMinusEquals(CYear)
  261. definePlusEquals(CMon)
  262. defineMinusEquals(CMon)
  263. definePlusEquals(CDay)
  264. defineMinusEquals(CDay)
  265. definePlusEquals(CHour)
  266. defineMinusEquals(CHour)
  267. definePlusEquals(CMin)
  268. defineMinusEquals(CMin)
  269. definePlusEquals(CSec)
  270. defineMinusEquals(CSec)
  271. //------------------------------------------------------------------------------
  272. //
  273. // @mfunc Sets the object to the current date/time.
  274. //
  275. // @rdesc None.
  276. //
  277. void CDate::SetDateCurrent()
  278. {
  279. time_t timer = time(NULL);
  280. *this = timer;
  281. }
  282. //------------------------------------------------------------------------------
  283. //
  284. // @mfunc Tests two date objects for equality for use in making all the
  285. // cobject sortable.
  286. //
  287. // @rdesc TRUE if the specified date is equal.
  288. //
  289. BOOL CDate::isEqualTo(const CDate& testDate) const
  290. {
  291. // compare the first 6 int's to see if the dates/times are equal
  292. return ( sec == testDate.GetSec() &&
  293. minute == testDate.GetMin() &&
  294. hour == testDate.GetHour() &&
  295. mday == testDate.GetDay() &&
  296. mon == testDate.GetMonth() &&
  297. year == testDate.GetYear() );
  298. }
  299. //------------------------------------------------------------------------------
  300. //
  301. // @mfunc Tests two object for less than to allow the object to be
  302. // sortable.
  303. //
  304. // @rdesc TRUE if the specified date is less than this.
  305. //
  306. BOOL CDate::isLessThan(const CDate& testDate) const
  307. {
  308. // see if our date/time is less than the passed date/time
  309. if ( year > testDate.GetYear() )
  310. return 0;
  311. else if ( year < testDate.GetYear() )
  312. return 1;
  313. if ( mon > testDate.GetMonth() )
  314. return 0;
  315. else if ( mon < testDate.GetMonth() )
  316. return 1;
  317. if ( mday > testDate.GetDay() )
  318. return 0;
  319. else if ( mday < testDate.GetDay() )
  320. return 1;
  321. if ( hour > testDate.GetHour() )
  322. return 0;
  323. else if ( hour < testDate.GetHour() )
  324. return 1;
  325. if ( minute > testDate.GetMin() )
  326. return 0;
  327. else if ( sec < testDate.GetSec() )
  328. return 1;
  329. return 0;
  330. }
  331. //------------------------------------------------------------------------------
  332. //
  333. // @mfunc This function calculates the number of units between x and y
  334. // which are divisible by z. Whichever is smaller is inclusive,
  335. // larger one non-inclusive. This means that if the smaller value
  336. // is a leap year, it counts, but if the larger one is a leap year,
  337. // it doesn't count.
  338. //
  339. // @rdesc The number of units calculated.
  340. //
  341. int CDate::DivisibleUnits( int x, int y, int z ) const
  342. {
  343. // get the number of units between x and y div. by z
  344. int nDiv = abs(x-y)/z;
  345. // if the lower operand of the two is divisible by z, add another
  346. int lower = x<y ? x : y;
  347. nDiv += (lower%z) ? 0 : 1;
  348. return nDiv;
  349. }
  350. //------------------------------------------------------------------------------
  351. //
  352. // @mfunc Calculates the number of leap years between the two years spec'd.
  353. //
  354. // @rdesc An integer number of years.
  355. //
  356. int CDate::LeapYearsBetween( int x, int y ) const
  357. {
  358. return DivisibleUnits(x,y,4) - DivisibleUnits(x,y,100) + DivisibleUnits(x,y,400);
  359. }
  360. //------------------------------------------------------------------------------
  361. //
  362. // @mfunc Calculates the number of days in the current month.
  363. //
  364. // @rdesc An integer number of months.
  365. //
  366. int CDate::GetDaysInMonth() const
  367. {
  368. return GetDaysInMonth( mon );
  369. }
  370. int CDate::GetDaysInMonth( int i ) const
  371. {
  372. int md[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  373. return (i==2 && isLeapYear()) ? 29 : md[i-1];
  374. }
  375. //------------------------------------------------------------------------------
  376. //
  377. // @mfunc Calculates the day of year of the currently held date.
  378. //
  379. // @rdesc A one-based integer day number within the year.
  380. //
  381. int CDate::GetDayOfYear() const
  382. {
  383. int md[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
  384. int i = md[mon-1];
  385. i += mday;
  386. i += (mon>2 && isLeapYear()) ? 1 : 0;
  387. return i;
  388. }
  389. //------------------------------------------------------------------------------
  390. //
  391. // @mfunc Calculates the number of days in the current month.
  392. //
  393. // @rdesc An integer number of weeks.
  394. //
  395. int CDate::GetWeeksInMonth() const
  396. {
  397. // Create a CDate for the first day of the selected month
  398. CDate date(GetYear(), GetMonth(), 1, 0, 0, 0);
  399. // Compute the number of weeks the selected month spans
  400. int nDaySpan = date.GetDayOfWeek() + date.GetDaysInMonth();
  401. return (nDaySpan + 6) / 7;
  402. }
  403. //------------------------------------------------------------------------------
  404. //
  405. // @mfunc Determines if the year is a leap year. The rule specifies that
  406. // any given year is a leap year if it is divisible by four, unless
  407. // it is divisible by 100, unless it is divisible by 400.
  408. //
  409. // @rdesc TRUE if the current year is a leap year, otherwise FALSE.
  410. //
  411. int CDate::isLeapYear() const
  412. {
  413. // if it's a leap year, then this will return 1. Otherwise, 0.
  414. return LeapYearsBetween( year, year );
  415. }
  416. //------------------------------------------------------------------------------
  417. //
  418. // @mfunc Calculates the day of week for the current date.
  419. //
  420. // @rdesc 0 for Sunday, 1 for Monday, thru 6 for Saturday.
  421. //
  422. int CDate::GetDayOfWeek() const
  423. {
  424. // Start at Sunday Jan 1, 1989
  425. // Compute day of week for January 1st of the target year.
  426. int wday = ( year > 1989 ) ? ( year-1989 ) : (1989-year);
  427. // Adjust for the leap years between 1989 and the target year. This adds a day for each leap year
  428. // after 1989, and subtracts a day for every leap year prior to 1989.
  429. wday += ( year > 1989 ) ? LeapYearsBetween( 1989, year ) : -LeapYearsBetween( 1989, year );
  430. // Now adjust for the current day of year of the target date.
  431. wday = ( wday + GetDayOfYear() - 1 ) % 7;
  432. return wday;
  433. }
  434. //------------------------------------------------------------------------------
  435. //
  436. // @mfunc This function calculates the number of days between two dates.
  437. //
  438. // @rdesc The number of days between this date and the specified date.
  439. //
  440. int CDate::DayDiff( const CDate& ADate ) const
  441. {
  442. CDate d1 = min(*this,ADate);
  443. CDate d2 = max(*this,ADate);
  444. // set both working dates to 1/1 of the year
  445. int dx = d2.GetDayOfYear() - d1.GetDayOfYear();
  446. d1.SetDate(1,1,d1.GetYear());
  447. d2.SetDate(1,1,d2.GetYear());
  448. int j = (d2.GetYear()-d1.GetYear())*365;
  449. dx += j ? j + LeapYearsBetween(d1.GetYear(),d2.GetYear()) : j;
  450. return dx;
  451. }
  452. //------------------------------------------------------------------------------
  453. //
  454. // @mfunc Formats a character representation of this object in the format
  455. // specified by the tokens in the format string. See the strftime
  456. // function for more details on the format of szFmt.
  457. //
  458. // @rdesc The number of characters copied to the buffer.
  459. //
  460. int CDate::GetDate( LPSTR szBuf, int nBufSize, LPCSTR szFmt )
  461. {
  462. struct tm strDateTime;
  463. strDateTime.tm_sec = GetSec(); /* Seconds */
  464. strDateTime.tm_min = GetMin(); /* Minutes */
  465. strDateTime.tm_hour = GetHour(); /* Hour (0--23) */
  466. strDateTime.tm_mday = GetDay(); /* Day of month (1--31) */
  467. strDateTime.tm_mon = GetMonth()-1; /* Month (0--11) */
  468. strDateTime.tm_year = GetYear()-1900; /* Year (calendar year minus 1900) */
  469. return int(strftime( szBuf, nBufSize, szFmt, &strDateTime));
  470. }
  471. //------------------------------------------------------------------------
  472. //
  473. // @mfunc Creates a text string representation of the time value.
  474. //
  475. // @rdesc None.
  476. //
  477. void CDate::GetWinTime(CString& str)
  478. {
  479. // Read the Windows international time format settings
  480. LPCSTR szSection = "INTL";
  481. BOOL iTime;
  482. char sTime[2];
  483. char s1159[10];
  484. char s2359[10];
  485. BOOL iTLZero;
  486. iTime = GetProfileInt(szSection, "iTime", 0);
  487. GetProfileString(szSection, "sTime", ":", sTime, sizeof(sTime));
  488. GetProfileString(szSection, "s1159", "AM", s1159, sizeof(s1159));
  489. GetProfileString(szSection, "s2359", "PM", s2359, sizeof(s2359));
  490. iTLZero = GetProfileInt(szSection, "iTLZero", 0);
  491. // Create the text strings based on WIN.INI International settings
  492. char szString[sizeof(s1159)];
  493. UINT uHour = GetHour();
  494. if (!iTime)
  495. {
  496. if (GetHour() == 0)
  497. uHour = 12;
  498. else if (GetHour() > 12)
  499. uHour -= 12;
  500. lstrcpy(szString, (GetHour() < 12) ? s1159 : s2359);
  501. }
  502. else
  503. lstrcpy(szString, s2359);
  504. char szTime[20];
  505. wsprintf(szTime, iTLZero ? "%02u%c%02u%c%02u%s" : "%u%c%02u%c%02u%s",
  506. uHour, sTime[0], GetMin(), sTime[0], GetSec(), szString);
  507. str = szTime;
  508. }
  509. //------------------------------------------------------------------------
  510. //
  511. // @mfunc Creates a text string representation of the date value.
  512. //
  513. // @rdesc None.
  514. //
  515. void CDate::GetWinShortDate(CString& str)
  516. {
  517. // Get the short date format string from the WIN.INI file [Intl] section
  518. char sShortDate[20];
  519. GetProfileString("INTL", "sShortDate", "MM/DD/YY", sShortDate, sizeof(sShortDate));
  520. // Format a date string based on the Windows short date format
  521. LPSTR szDate = new char[lstrlen(sShortDate) * 2 + 1];
  522. *szDate = '\0';
  523. LPCSTR lpFormat = sShortDate;
  524. char szTemp[10];
  525. while (*lpFormat)
  526. {
  527. LPCSTR lpToken = lpFormat;
  528. switch (GetNextDateToken(lpFormat))
  529. {
  530. case DateToken_m:
  531. wsprintf(szTemp, "%u", GetMonth());
  532. break;
  533. case DateToken_mm:
  534. wsprintf(szTemp, "%02u", GetMonth());
  535. break;
  536. case DateToken_d:
  537. wsprintf(szTemp, "%u", GetDay());
  538. break;
  539. case DateToken_dd:
  540. wsprintf(szTemp, "%02u", GetDay());
  541. break;
  542. case DateToken_yy:
  543. wsprintf(szTemp, "%02u", GetYear()-1900);
  544. break;
  545. case DateToken_yyyy:
  546. wsprintf(szTemp, "%04u", GetYear());
  547. break;
  548. case DateTokenUnrecognized:
  549. {
  550. LPSTR lpTemp = szTemp;
  551. while (lpToken != lpFormat)
  552. *lpTemp++ = *lpToken++;
  553. *lpTemp = '\0';
  554. break;
  555. }
  556. }
  557. lstrcat(szDate, szTemp);
  558. }
  559. str = szDate;
  560. }
  561. //------------------------------------------------------------------------
  562. //
  563. // @mfunc Creates a text string representation of the date value that
  564. // matches the format that is parsed for in SetDate.
  565. //
  566. // @rdesc None.
  567. //
  568. void CDate::GetParseDate(CString& str) const
  569. {
  570. char szDate[64];
  571. wsprintf( szDate, "%02d/%02d/%02d, %02d:%02d", GetMonth(), GetDay(), GetYear(), GetHour(), GetMin());
  572. str = szDate;
  573. }
  574. //------------------------------------------------------------------------
  575. //
  576. // @mfunc Creates a text string representation of the time value only
  577. // which matches the format that is parsed for in SetDate.
  578. //
  579. // @rdesc None.
  580. //
  581. void CDate::GetParseTime(CString& str)
  582. {
  583. char szDate[64];
  584. wsprintf( szDate, "%02d:%02d", GetHour(), GetMin());
  585. str = szDate;
  586. }
  587. //------------------------------------------------------------------------
  588. //
  589. // @mfunc Creates a text string representation of the time value only
  590. // which matches the format that is parsed for in SetDate.
  591. //
  592. // @rdesc None.
  593. //
  594. void CDate::GetFiletime(FILETIME* ft) const
  595. {
  596. SYSTEMTIME systime;
  597. CTime t(GetYear(), GetMonth(), GetDay(), GetHour(), GetMin(), GetSec());
  598. t.GetAsSystemTime(systime);
  599. SystemTimeToFileTime(&systime, ft);
  600. }
  601. //------------------------------------------------------------------------
  602. //
  603. // @mfunc Determines the date token that the specified pointer is
  604. // pointing to and increments the pointer past the token.
  605. //
  606. // @rdesc The type of token pointed to by the specified pointer.
  607. //
  608. CDate::DateToken CDate::GetNextDateToken(LPCSTR & lpFormat)
  609. {
  610. // Determine which date token, if any, is being pointed to
  611. int nCount;
  612. switch (*lpFormat)
  613. {
  614. case '\0':
  615. return DateTokenUnrecognized;
  616. case 'm':
  617. case 'M':
  618. // Count the number of times this character occurs
  619. nCount = 1;
  620. while (*(++lpFormat) == 'm' || *lpFormat == 'M')
  621. ++nCount;
  622. switch (nCount)
  623. {
  624. case 1:
  625. return DateToken_m;
  626. case 2:
  627. return DateToken_mm;
  628. }
  629. return DateTokenUnrecognized;
  630. case 'd':
  631. case 'D':
  632. // Count the number of times this character occurs
  633. nCount = 1;
  634. while (*(++lpFormat) == 'd' || *lpFormat == 'D')
  635. ++nCount;
  636. switch (nCount)
  637. {
  638. case 1:
  639. return DateToken_d;
  640. case 2:
  641. return DateToken_dd;
  642. }
  643. return DateTokenUnrecognized;
  644. case 'y':
  645. case 'Y':
  646. // Count the number of times this character occurs
  647. nCount = 1;
  648. while (*(++lpFormat) == 'y' || *lpFormat == 'Y')
  649. ++nCount;
  650. switch (nCount)
  651. {
  652. case 2:
  653. return DateToken_yy;
  654. case 4:
  655. return DateToken_yyyy;
  656. }
  657. return DateTokenUnrecognized;
  658. default:
  659. // Bump the pointer to the next token
  660. while (*(++lpFormat) != 'm' && *lpFormat != 'M' &&
  661. *lpFormat != 'd' && *lpFormat != 'D' &&
  662. *lpFormat != 'y' && *lpFormat != 'Y');
  663. return DateTokenUnrecognized;
  664. }
  665. }
  666. //------------------------------------------------------------------------------
  667. //
  668. // @mfunc Increments the second field by the specified number.
  669. //
  670. // @rdesc None.
  671. //
  672. void CDate::IncSec( int sec_inc )
  673. {
  674. if ( sec_inc < 0 )
  675. {
  676. DecSec( -sec_inc );
  677. return;
  678. }
  679. sec = sec + sec_inc;
  680. int m_inc = sec / 60;
  681. sec = sec % 60;
  682. if (m_inc)
  683. IncMin(m_inc);
  684. }
  685. //------------------------------------------------------------------------------
  686. //
  687. // @mfunc Increments the minute field by the specified number.
  688. //
  689. // @rdesc None.
  690. //
  691. void CDate::IncMin( int min_inc )
  692. {
  693. if ( min_inc < 0 )
  694. {
  695. DecMin( -min_inc );
  696. return;
  697. }
  698. minute = minute + min_inc;
  699. int h_inc = minute / 60;
  700. minute = minute % 60;
  701. if (h_inc)
  702. IncHour(h_inc);
  703. }
  704. //------------------------------------------------------------------------------
  705. //
  706. // @mfunc Increments the hour field by the specified number.
  707. //
  708. // @rdesc None.
  709. //
  710. void CDate::IncHour( int hour_inc )
  711. {
  712. if ( hour_inc < 0 )
  713. {
  714. DecHour( -hour_inc );
  715. return;
  716. }
  717. hour = hour + hour_inc;
  718. int d_inc = hour / 24;
  719. hour = hour % 24;
  720. if (d_inc)
  721. IncDay(d_inc);
  722. }
  723. //------------------------------------------------------------------------------
  724. //
  725. // @mfunc Increments the day field by the specified number.
  726. //
  727. // @rdesc None.
  728. //
  729. void CDate::IncDay( int day_inc )
  730. {
  731. if ( day_inc < 0 )
  732. {
  733. DecDay( -day_inc );
  734. return;
  735. }
  736. while (day_inc)
  737. {
  738. int dim = GetDaysInMonth();
  739. int DaysLeftInMonth = dim - mday;
  740. if ( day_inc <= DaysLeftInMonth )
  741. {
  742. mday = mday + day_inc;
  743. day_inc = 0;
  744. }
  745. else
  746. {
  747. day_inc -= DaysLeftInMonth;
  748. IncMonth();
  749. mday = 0;
  750. }
  751. }
  752. }
  753. //------------------------------------------------------------------------------
  754. //
  755. // @mfunc Increments the month field by the specified number.
  756. //
  757. // @rdesc None.
  758. //
  759. void CDate::IncMonth( int mon_inc )
  760. {
  761. if ( mon_inc < 0 )
  762. {
  763. DecMonth( -mon_inc );
  764. return;
  765. }
  766. mon = mon + mon_inc;
  767. int y_inc = (mon-1) / 12;
  768. mon = (mon-1) % 12 + 1;
  769. if (y_inc)
  770. IncYear(y_inc);
  771. }
  772. //------------------------------------------------------------------------------
  773. //
  774. // @mfunc Increments the year field by the specified number.
  775. //
  776. // @rdesc None.
  777. //
  778. void CDate::IncYear( int year_inc )
  779. {
  780. if ( year_inc < 0 )
  781. {
  782. DecYear( -year_inc );
  783. return;
  784. }
  785. year = year + year_inc;
  786. }
  787. //------------------------------------------------------------------------------
  788. //
  789. // @mfunc Decrements the second field by the specified number.
  790. //
  791. // @rdesc None.
  792. //
  793. void CDate::DecSec( int sec_inc )
  794. {
  795. if ( sec_inc < 0 )
  796. {
  797. IncSec( -sec_inc );
  798. return;
  799. }
  800. int m_inc = sec_inc / 60;
  801. sec_inc %= 60;
  802. if (sec_inc > sec)
  803. {
  804. m_inc++;
  805. sec_inc-=60;
  806. }
  807. sec = sec - sec_inc;
  808. if (m_inc)
  809. DecMin(m_inc);
  810. }
  811. //------------------------------------------------------------------------------
  812. //
  813. // @mfunc Decrements the minute field by the specified number.
  814. //
  815. // @rdesc None.
  816. //
  817. void CDate::DecMin( int min_inc )
  818. {
  819. if ( min_inc < 0 )
  820. {
  821. IncMin( -min_inc );
  822. return;
  823. }
  824. int h_inc = min_inc / 60;
  825. min_inc %= 60;
  826. if (min_inc > minute)
  827. {
  828. h_inc++;
  829. min_inc-=60;
  830. }
  831. minute = minute - min_inc;
  832. if (h_inc)
  833. DecHour(h_inc);
  834. }
  835. //------------------------------------------------------------------------------
  836. //
  837. // @mfunc Decrements the hour field by the specified number.
  838. //
  839. // @rdesc None.
  840. //
  841. void CDate::DecHour( int hour_inc )
  842. {
  843. if ( hour_inc < 0 )
  844. {
  845. IncHour( -hour_inc );
  846. return;
  847. }
  848. int d_inc = hour_inc / 24;
  849. hour_inc %= 24;
  850. if (hour_inc > hour)
  851. {
  852. d_inc++;
  853. hour_inc-=24;
  854. }
  855. hour = hour - hour_inc;
  856. if (d_inc)
  857. DecDay(d_inc);
  858. }
  859. //------------------------------------------------------------------------------
  860. //
  861. // @mfunc Decrements the day field by the specified number.
  862. //
  863. // @rdesc None.
  864. //
  865. void CDate::DecDay( int day_inc )
  866. {
  867. if ( day_inc < 0 )
  868. {
  869. IncDay( -day_inc );
  870. return;
  871. }
  872. while (day_inc)
  873. {
  874. if ( day_inc < mday )
  875. {
  876. mday = mday - day_inc;
  877. day_inc = 0;
  878. }
  879. else
  880. {
  881. DecMonth();
  882. day_inc -= mday;
  883. mday = GetDaysInMonth();
  884. }
  885. }
  886. }
  887. //------------------------------------------------------------------------------
  888. //
  889. // @mfunc Decrements the month field by the specified number.
  890. //
  891. // @rdesc None.
  892. //
  893. void CDate::DecMonth( int mon_inc )
  894. {
  895. if ( mon_inc < 0 )
  896. {
  897. IncMonth( -mon_inc );
  898. return;
  899. }
  900. int y_inc = mon_inc / 12;
  901. mon_inc %= 12;
  902. if (mon_inc > mon - 1)
  903. {
  904. y_inc++;
  905. mon_inc-=12;
  906. }
  907. mon = mon - mon_inc;
  908. if (y_inc)
  909. DecYear(y_inc);
  910. }
  911. //------------------------------------------------------------------------------
  912. //
  913. // @mfunc Decrements the year field by the specified number.
  914. //
  915. // @rdesc None.
  916. //
  917. void CDate::DecYear( int year_inc )
  918. {
  919. if ( year_inc < 0 )
  920. {
  921. IncYear( -year_inc );
  922. return;
  923. }
  924. year = year - year_inc;
  925. }
  926. //------------------------------------------------------------------------------
  927. //
  928. // @mfunc Sets the second field to the specified value.
  929. //
  930. // @rdesc None.
  931. //
  932. void CDate::SetSec( int secNew )
  933. {
  934. if (secNew < 0 || secNew > 59)
  935. return;
  936. sec = secNew;
  937. }
  938. //------------------------------------------------------------------------------
  939. //
  940. // @mfunc Sets the minute field to the specified value.
  941. //
  942. // @rdesc None.
  943. //
  944. void CDate::SetMin( int minNew )
  945. {
  946. if (minNew < 0 || minNew > 59)
  947. return;
  948. minute = minNew;
  949. }
  950. //------------------------------------------------------------------------------
  951. //
  952. // @mfunc Sets the hour field to the specified value.
  953. //
  954. // @rdesc None.
  955. //
  956. void CDate::SetHour( int hourNew )
  957. {
  958. if (hourNew < 0 || hourNew > 23)
  959. return;
  960. hour = hourNew;
  961. }
  962. //------------------------------------------------------------------------------
  963. //
  964. // @mfunc Sets the day field to the specified value.
  965. //
  966. // @rdesc None.
  967. //
  968. void CDate::SetDay( int mdayNew )
  969. {
  970. if (mdayNew < 1 || mdayNew > GetDaysInMonth(mon))
  971. return;
  972. mday = mdayNew;
  973. }
  974. //------------------------------------------------------------------------------
  975. //
  976. // @mfunc Sets the month field to the specified value.
  977. //
  978. // @rdesc None.
  979. //
  980. void CDate::SetMonth( int monNew )
  981. {
  982. if (monNew < 1 || monNew > 12)
  983. return;
  984. mon = monNew;
  985. if (mday > GetDaysInMonth(mon))
  986. mday = GetDaysInMonth();
  987. }
  988. //------------------------------------------------------------------------------
  989. //
  990. // @mfunc Sets the year field to the specified value.
  991. //
  992. // @rdesc None.
  993. //
  994. void CDate::SetYear( int yearNew )
  995. {
  996. if (yearNew < 1900 || yearNew > 3000)
  997. return;
  998. year = yearNew;
  999. }
  1000. //------------------------------------------------------------------------------
  1001. //
  1002. // @mfunc Sets the time fields to the specified values.
  1003. //
  1004. // @rdesc None.
  1005. //
  1006. void CDate::SetTime( int hourNew, int minNew, int secNew )
  1007. {
  1008. SetHour( hourNew );
  1009. SetMin( minNew );
  1010. SetSec( secNew );
  1011. }
  1012. //------------------------------------------------------------------------------
  1013. //
  1014. // @mfunc Sets the date fields to the specified value.
  1015. //
  1016. // @rdesc None.
  1017. //
  1018. void CDate::SetDate( int monNew, int mdayNew, int yearNew )
  1019. {
  1020. SetYear( yearNew );
  1021. SetMonth( monNew );
  1022. SetDay( mdayNew );
  1023. }
  1024. int CDate::SetDate( const char* lpszDate )
  1025. {
  1026. int nState = 0;
  1027. char szChar[28];
  1028. int j=0;
  1029. for (unsigned int i=0; i<min(lstrlen(lpszDate),sizeof(szChar)); i++)
  1030. {
  1031. if (*(lpszDate+i)!=' ')
  1032. {
  1033. szChar[j]=*(lpszDate+i);
  1034. j++;
  1035. }
  1036. }
  1037. szChar[j] = '\0';
  1038. CDate fDate;
  1039. const char* lpszChar = szChar;
  1040. while ( 1 )
  1041. {
  1042. switch( nState )
  1043. {
  1044. case State_Init: nState = StateInit( lpszChar, fDate );
  1045. break;
  1046. case State_1: nState = State1( lpszChar, fDate );
  1047. break;
  1048. case State_2: nState = State2( lpszChar, fDate );
  1049. break;
  1050. case State_3: nState = State3( lpszChar, fDate );
  1051. break;
  1052. case State_4: nState = State4( lpszChar, fDate );
  1053. break;
  1054. case State_10: nState = State10( lpszChar, fDate );
  1055. break;
  1056. case State_11: nState = State11( lpszChar, fDate );
  1057. break;
  1058. case State_12: nState = State12( lpszChar, fDate );
  1059. break;
  1060. // This state means that parsing was successful
  1061. case State_End: *this = fDate; return 0;
  1062. // This case means that a syntax error was found during parsing
  1063. case State_Error: return nState;
  1064. }
  1065. }
  1066. }
  1067. int CDate::StateInit(const char*& lpChar, CDate& fDate )
  1068. {
  1069. rcParse rcp;
  1070. int NextState;
  1071. if ( ParseMonthName(lpChar,rcp) )
  1072. {
  1073. fDate.SetMonth(rcp.nVal);
  1074. NextState = State_2;
  1075. }
  1076. else if ( Parse99Slashor9Slash(lpChar, rcp) )
  1077. {
  1078. fDate.SetMonth(rcp.nVal);
  1079. NextState = State_2;
  1080. }
  1081. else if ( Parse99Colonor9Colon(lpChar, rcp) )
  1082. {
  1083. fDate.SetHour(rcp.nVal);
  1084. NextState = State_10;
  1085. }
  1086. else if ( Parse99or9(lpChar, rcp) )
  1087. {
  1088. fDate.SetDay(rcp.nVal);
  1089. NextState = State_1;
  1090. }
  1091. else
  1092. return State_Error;
  1093. lpChar += rcp.nBump;
  1094. return NextState;
  1095. }
  1096. int CDate::State1(const char*& lpChar, CDate& fDate )
  1097. {
  1098. rcParse rcp;
  1099. int NextState;
  1100. if ( ParseMonthName(lpChar,rcp) )
  1101. {
  1102. fDate.SetMonth(rcp.nVal);
  1103. NextState = State_3;
  1104. }
  1105. else
  1106. return State_Error;
  1107. lpChar += rcp.nBump;
  1108. return NextState;
  1109. }
  1110. int CDate::State2(const char*& lpChar, CDate& fDate )
  1111. {
  1112. rcParse rcp;
  1113. int NextState;
  1114. if ( Parse99Slashor9Slash(lpChar, rcp) )
  1115. {
  1116. fDate.SetDay(rcp.nVal);
  1117. NextState = State_3;
  1118. }
  1119. else if ( Parse99Commaor9Comma(lpChar, rcp) )
  1120. {
  1121. fDate.SetDay(rcp.nVal);
  1122. NextState = State_12;
  1123. }
  1124. else if ( Parse99or9(lpChar, rcp) )
  1125. {
  1126. fDate.SetDay(rcp.nVal);
  1127. NextState = State_4;
  1128. }
  1129. else
  1130. return State_Error;
  1131. lpChar += rcp.nBump;
  1132. return NextState;
  1133. }
  1134. int CDate::State3(const char*& lpChar, CDate& fDate )
  1135. {
  1136. rcParse rcp;
  1137. int NextState;
  1138. if ( Parse9999Commaor99Comma(lpChar, rcp) )
  1139. {
  1140. fDate.SetYear(rcp.nVal);
  1141. NextState = State_12;
  1142. }
  1143. else if ( Parse9999or99(lpChar, rcp) )
  1144. {
  1145. fDate.SetYear(rcp.nVal);
  1146. NextState = State_4;
  1147. }
  1148. else
  1149. return State_Error;
  1150. lpChar += rcp.nBump;
  1151. return NextState;
  1152. }
  1153. int CDate::State4(const char*& lpChar, CDate& )
  1154. {
  1155. rcParse rcp;
  1156. int NextState;
  1157. if ( ParseEOM(lpChar, rcp) )
  1158. NextState = State_End;
  1159. else
  1160. return State_Error;
  1161. lpChar += rcp.nBump;
  1162. return NextState;
  1163. }
  1164. int CDate::State10(const char*& lpChar, CDate& fDate)
  1165. {
  1166. rcParse rcp;
  1167. int NextState;
  1168. if ( Parse99Colonor9Colon(lpChar, rcp) )
  1169. {
  1170. fDate.SetMin(rcp.nVal);
  1171. NextState = State_11;
  1172. }
  1173. else if ( Parse99or9(lpChar, rcp) )
  1174. {
  1175. fDate.SetMin(rcp.nVal);
  1176. NextState = State_4;
  1177. }
  1178. else
  1179. return State_Error;
  1180. lpChar += rcp.nBump;
  1181. return NextState;
  1182. }
  1183. int CDate::State11(const char*& lpChar, CDate& fDate)
  1184. {
  1185. rcParse rcp;
  1186. int NextState;
  1187. if ( Parse99or9(lpChar, rcp) )
  1188. {
  1189. fDate.SetSec(rcp.nVal);
  1190. NextState = State_4;
  1191. }
  1192. else
  1193. return State_Error;
  1194. lpChar += rcp.nBump;
  1195. return NextState;
  1196. }
  1197. int CDate::State12(const char*& lpChar, CDate& fDate)
  1198. {
  1199. rcParse rcp;
  1200. int NextState;
  1201. if ( Parse99Colonor9Colon(lpChar, rcp) )
  1202. {
  1203. fDate.SetHour(rcp.nVal);
  1204. NextState = State_10;
  1205. }
  1206. else
  1207. return State_Error;
  1208. lpChar += rcp.nBump;
  1209. return NextState;
  1210. }
  1211. //------------------------------------------------------------------------------
  1212. //
  1213. // @mfunc Provides the ability to add to the second field.
  1214. //
  1215. // @rdesc The resulting CDate value.
  1216. //
  1217. CDate CDate::operator + ( const CSec inc ) const
  1218. {
  1219. CDate mD(*this);
  1220. mD.IncSec(inc);
  1221. return mD;
  1222. }
  1223. CDate CDate::operator + ( const CMin inc ) const
  1224. {
  1225. CDate mD(*this);
  1226. mD.IncMin(inc);
  1227. return mD;
  1228. }
  1229. CDate CDate::operator + ( const CHour inc ) const
  1230. {
  1231. CDate mD(*this);
  1232. mD.IncHour(inc);
  1233. return mD;
  1234. }
  1235. CDate CDate::operator + ( const CDay inc ) const
  1236. {
  1237. CDate mD(*this);
  1238. mD.IncDay(inc);
  1239. return mD;
  1240. }
  1241. CDate CDate::operator + ( const CMon inc ) const
  1242. {
  1243. CDate mD(*this);
  1244. mD.IncMonth(inc);
  1245. return mD;
  1246. }
  1247. CDate CDate::operator + ( const CYear inc ) const
  1248. {
  1249. CDate mD(*this);
  1250. mD.IncYear(inc);
  1251. return mD;
  1252. }
  1253. //------------------------------------------------------------------------------
  1254. //
  1255. // @mfunc Provides the ability to subtract from the second field.
  1256. //
  1257. // @rdesc The resulting CDate value.
  1258. //
  1259. CDate CDate::operator - ( const CSec inc ) const
  1260. {
  1261. CDate mD(*this);
  1262. mD.DecSec(inc);
  1263. return mD;
  1264. }
  1265. CDate CDate::operator - ( const CMin inc ) const
  1266. {
  1267. CDate mD(*this);
  1268. mD.DecMin(inc);
  1269. return mD;
  1270. }
  1271. CDate CDate::operator - ( const CHour inc ) const
  1272. {
  1273. CDate mD(*this);
  1274. mD.DecHour(inc);
  1275. return mD;
  1276. }
  1277. CDate CDate::operator - ( const CDay inc ) const
  1278. {
  1279. CDate mD(*this);
  1280. mD.DecDay(inc);
  1281. return mD;
  1282. }
  1283. CDate CDate::operator - ( const CMon inc ) const
  1284. {
  1285. CDate mD(*this);
  1286. mD.DecMonth(inc);
  1287. return mD;
  1288. }
  1289. CDate CDate::operator - ( const CYear inc ) const
  1290. {
  1291. CDate mD(*this);
  1292. mD.DecYear(inc);
  1293. return mD;
  1294. }
  1295. //------------------------------------------------------------------------------
  1296. //
  1297. // @mfunc Provides the ability to set the date/time from a time_t.
  1298. //
  1299. // @rdesc None.
  1300. //
  1301. void CDate::operator = ( const time_t time )
  1302. {
  1303. tm* t = localtime(&(time));
  1304. sec = CSec (t->tm_sec);
  1305. minute = CMin (t->tm_min);
  1306. hour = CHour(t->tm_hour);
  1307. mday = CDay (t->tm_mday);
  1308. mon = CMon (t->tm_mon + 1); // our day of month is 1-based, not 0-based like dos
  1309. year = CYear(t->tm_year + 1900); // dos routines only handle post-1900 dates
  1310. }
  1311. //------------------------------------------------------------------------------
  1312. //
  1313. // @mfunc Provides the ability to construct the date/time from a system
  1314. // clock value.
  1315. //
  1316. // @rdesc None.
  1317. //
  1318. CDate::CDate(const FILETIME ft)
  1319. {
  1320. CTime c(ft);
  1321. struct tm t;
  1322. c.GetGmtTm(&t);
  1323. sec = CSec (t.tm_sec);
  1324. minute = CMin (t.tm_min);
  1325. hour = CHour(t.tm_hour);
  1326. mday = CDay (t.tm_mday);
  1327. mon = CMon (t.tm_mon + 1); // our day of month is 1-based, not 0-based like dos
  1328. year = CYear(t.tm_year + 1900); // dos routines only handle post-1900 dates
  1329. }
  1330. //------------------------------------------------------------------------------
  1331. //
  1332. // @mfunc Provides the ability to get the date/time in the form of an ATime.
  1333. //
  1334. // @rdesc None.
  1335. //
  1336. #if 0
  1337. CDate::operator ATime (void) const
  1338. {
  1339. ATime atime;
  1340. atime.SetDate(year, mon, mday);
  1341. atime.SetTime(hour, minute);
  1342. return atime;
  1343. }
  1344. CDate::CDate(const RTime &rtm)
  1345. {
  1346. ATime atm(rtm);
  1347. year = atm.Year();
  1348. mon = atm.Month();
  1349. mday = atm.Day();
  1350. hour = atm.Hour();
  1351. minute = atm.Minute();
  1352. sec = 0;
  1353. }
  1354. CDate::operator RTime (void) const
  1355. {
  1356. ATime atm;
  1357. atm.SetDate(year, mon, mday);
  1358. atm.SetTime(hour, minute);
  1359. RTime rtm(atm);
  1360. return(rtm);
  1361. }
  1362. #endif
  1363. //------------------------------------------------------------------------------
  1364. //
  1365. // @mfunc Provides the ability to make the CDate persistent.
  1366. //
  1367. // @rdesc None.
  1368. //
  1369. void CDate::Serialize( CArchive& ar )
  1370. {
  1371. if (ar.IsStoring())
  1372. {
  1373. ar << BYTE(39); // version number--started at 38 for improved error-catching
  1374. // serialize out the data specific to this class only
  1375. ar << (WORD) GetYear();
  1376. ar << (BYTE) GetMonth();
  1377. ar << (BYTE) GetDay();
  1378. ar << (BYTE) GetHour();
  1379. ar << (BYTE) GetMin();
  1380. ar << (BYTE) GetSec();
  1381. }
  1382. else
  1383. {
  1384. BYTE bVer;
  1385. ar >> bVer; // Read in the version.
  1386. switch( bVer )
  1387. {
  1388. case 39:
  1389. {
  1390. // serialize in the data specific to this class only
  1391. WORD wTemp;
  1392. BYTE bTemp;
  1393. ar >> wTemp; SetYear(wTemp);
  1394. ar >> bTemp; SetMonth(bTemp);
  1395. ar >> bTemp; SetDay(bTemp);
  1396. ar >> bTemp; SetHour(bTemp);
  1397. ar >> bTemp; SetMin(bTemp);
  1398. ar >> bTemp; SetSec(bTemp);
  1399. }
  1400. break;
  1401. default:
  1402. // fail the load!!! invalid binder file!!!
  1403. AfxThrowArchiveException(CArchiveException::generic);
  1404. ASSERT(FALSE);
  1405. }
  1406. }
  1407. }
  1408. CArchive& operator>> (CArchive& ar, CDate& d)
  1409. {
  1410. d.Serialize(ar);
  1411. return ar;
  1412. }
  1413. CArchive& operator<< (CArchive& ar, CDate& d)
  1414. {
  1415. d.Serialize(ar);
  1416. return ar;
  1417. }
  1418. //------------------------------------------------------------------------------
  1419. //
  1420. // @mfunc Sets the range for the CDateRange object. Return code zero
  1421. // means that the range was set properly based on the specified
  1422. // input string.
  1423. //
  1424. // @rdesc None.
  1425. //
  1426. int CDateRange::SetRange(LPCSTR lpszDateRange)
  1427. {
  1428. int nState = 0;
  1429. const char* lpChar = lpszDateRange;
  1430. while ( 1 )
  1431. {
  1432. switch( nState )
  1433. {
  1434. case State_Init: nState = StateInit( lpChar, m_fDate, m_lDate );
  1435. break;
  1436. case State_1: nState = State1( lpChar, m_fDate, m_lDate );
  1437. break;
  1438. case State_2: nState = State2( lpChar, m_fDate, m_lDate );
  1439. break;
  1440. case State_3: nState = State3( lpChar, m_fDate, m_lDate );
  1441. break;
  1442. case State_4: nState = State4( lpChar, m_fDate, m_lDate );
  1443. break;
  1444. case State_5: nState = State5( lpChar, m_fDate, m_lDate );
  1445. break;
  1446. case State_6: nState = State6( lpChar, m_fDate, m_lDate );
  1447. break;
  1448. case State_7: nState = State7( lpChar, m_fDate, m_lDate );
  1449. break;
  1450. case State_8: nState = State8( lpChar, m_fDate, m_lDate );
  1451. break;
  1452. case State_9: nState = State9( lpChar, m_fDate, m_lDate );
  1453. break;
  1454. case State_End: return 0;
  1455. case State_Error: return nState;
  1456. }
  1457. }
  1458. }
  1459. int CDateRange::StateInit(const char*& lpChar, CDate& fDate, CDate& )
  1460. {
  1461. rcParse rcp;
  1462. int NextState;
  1463. if ( ParseMonthName(lpChar,rcp) )
  1464. {
  1465. fDate.SetMonth(rcp.nVal);
  1466. NextState = State_2;
  1467. }
  1468. else if ( Parse99Slashor9Slash(lpChar, rcp) )
  1469. {
  1470. fDate.SetMonth(rcp.nVal);
  1471. NextState = State_2;
  1472. }
  1473. else if ( Parse99or9(lpChar, rcp) )
  1474. {
  1475. fDate.SetDay(rcp.nVal);
  1476. NextState = State_1;
  1477. }
  1478. else
  1479. return State_Error;
  1480. lpChar += rcp.nBump;
  1481. return NextState;
  1482. }
  1483. int CDateRange::State1(const char*& lpChar, CDate& fDate, CDate& )
  1484. {
  1485. rcParse rcp;
  1486. int NextState;
  1487. if ( ParseMonthName(lpChar,rcp) )
  1488. {
  1489. fDate.SetMonth(rcp.nVal);
  1490. NextState = State_4;
  1491. }
  1492. else
  1493. return State_Error;
  1494. lpChar += rcp.nBump;
  1495. return NextState;
  1496. }
  1497. int CDateRange::State2(const char*& lpChar, CDate& fDate, CDate& )
  1498. {
  1499. rcParse rcp;
  1500. int NextState;
  1501. if ( Parse99Slashor9Slash(lpChar, rcp) )
  1502. {
  1503. fDate.SetDay(rcp.nVal);
  1504. NextState = State_3;
  1505. }
  1506. else if ( Parse99or9(lpChar, rcp) )
  1507. {
  1508. fDate.SetDay(rcp.nVal);
  1509. NextState = State_4;
  1510. }
  1511. else
  1512. return State_Error;
  1513. lpChar += rcp.nBump;
  1514. return NextState;
  1515. }
  1516. int CDateRange::State3(const char*& lpChar, CDate& fDate, CDate& )
  1517. {
  1518. rcParse rcp;
  1519. int NextState;
  1520. if ( Parse9999or99(lpChar, rcp) )
  1521. {
  1522. fDate.SetYear(rcp.nVal);
  1523. NextState = State_4;
  1524. }
  1525. else
  1526. return State_Error;
  1527. lpChar += rcp.nBump;
  1528. return NextState;
  1529. }
  1530. int CDateRange::State4(const char*& lpChar, CDate& fDate, CDate& lDate )
  1531. {
  1532. rcParse rcp;
  1533. int NextState;
  1534. if ( ParseDash(lpChar, rcp) )
  1535. {
  1536. NextState = State_5;
  1537. }
  1538. else if ( ParseEOM(lpChar, rcp) )
  1539. {
  1540. lDate = fDate;
  1541. NextState = State_End;
  1542. }
  1543. else
  1544. return State_Error;
  1545. lpChar += rcp.nBump;
  1546. return NextState;
  1547. }
  1548. int CDateRange::State5(const char*& lpChar, CDate& fDate, CDate& lDate )
  1549. {
  1550. rcParse rcp;
  1551. int NextState;
  1552. if ( Parse99NTor9NT(lpChar,rcp) )
  1553. {
  1554. lDate = fDate;
  1555. lDate += CDay(rcp.nVal);
  1556. NextState = State_9;
  1557. }
  1558. else if ( ParseMonthName(lpChar,rcp) )
  1559. {
  1560. lDate.SetMonth(rcp.nVal);
  1561. NextState = State_7;
  1562. }
  1563. else if ( Parse99Slashor9Slash(lpChar, rcp) )
  1564. {
  1565. lDate.SetMonth(rcp.nVal);
  1566. NextState = State_7;
  1567. }
  1568. else if ( Parse99or9(lpChar, rcp) )
  1569. {
  1570. lDate.SetDay(rcp.nVal);
  1571. NextState = State_6;
  1572. }
  1573. else
  1574. return State_Error;
  1575. lpChar += rcp.nBump;
  1576. return NextState;
  1577. }
  1578. int CDateRange::State6(const char*& lpChar, CDate&, CDate& lDate )
  1579. {
  1580. rcParse rcp;
  1581. int NextState;
  1582. if ( ParseMonthName(lpChar,rcp) )
  1583. {
  1584. lDate.SetMonth(rcp.nVal);
  1585. NextState = State_9;
  1586. }
  1587. else
  1588. return State_Error;
  1589. lpChar += rcp.nBump;
  1590. return NextState;
  1591. }
  1592. int CDateRange::State7(const char*& lpChar, CDate&, CDate& lDate )
  1593. {
  1594. rcParse rcp;
  1595. int NextState;
  1596. if ( Parse99Slashor9Slash(lpChar, rcp) )
  1597. {
  1598. lDate.SetDay(rcp.nVal);
  1599. NextState = State_8;
  1600. }
  1601. else if ( Parse99or9(lpChar, rcp) )
  1602. {
  1603. lDate.SetDay(rcp.nVal);
  1604. NextState = State_9;
  1605. }
  1606. else
  1607. return State_Error;
  1608. lpChar += rcp.nBump;
  1609. return NextState;
  1610. }
  1611. int CDateRange::State8(const char*& lpChar, CDate&, CDate& lDate )
  1612. {
  1613. rcParse rcp;
  1614. int NextState;
  1615. if ( Parse9999or99(lpChar, rcp) )
  1616. {
  1617. lDate.SetYear(rcp.nVal);
  1618. NextState = State_9;
  1619. }
  1620. else
  1621. return State_Error;
  1622. lpChar += rcp.nBump;
  1623. return NextState;
  1624. }
  1625. int CDateRange::State9(const char*& lpChar, CDate&, CDate& lDate )
  1626. {
  1627. rcParse rcp;
  1628. int NextState;
  1629. if ( ParseEOM(lpChar, rcp) )
  1630. {
  1631. lDate = lDate;
  1632. NextState = State_End;
  1633. }
  1634. else
  1635. return State_Error;
  1636. lpChar += rcp.nBump;
  1637. return NextState;
  1638. }
  1639. //------------------------------------------------------------------------
  1640. //
  1641. // @mfunc Creates a text string representation of the date value that
  1642. // matches the format that is parsed for in SetDate.
  1643. //
  1644. // @rdesc None.
  1645. //
  1646. void CDateRange::GetParseDate(CString& str) const
  1647. {
  1648. m_fDate.GetParseDate(str);
  1649. str += "-";
  1650. CString strTemp;
  1651. m_lDate.GetParseDate(strTemp);
  1652. str += strTemp;
  1653. }
  1654. void DDX_CDate(CDataExchange* pDX, int nIDC, CDate& value)
  1655. {
  1656. HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
  1657. CString strWndText;
  1658. if (pDX->m_bSaveAndValidate)
  1659. {
  1660. int nLen = ::GetWindowTextLength(hWndCtrl);
  1661. ::GetWindowText(hWndCtrl, strWndText.GetBufferSetLength(nLen), nLen+1);
  1662. strWndText.ReleaseBuffer();
  1663. if (value.SetDate(strWndText))
  1664. pDX->Fail();
  1665. }
  1666. else
  1667. {
  1668. value.GetParseDate(strWndText);
  1669. int nNewLen = strWndText.GetLength();
  1670. TCHAR szOld[256];
  1671. // fast check to see if text really changes (reduces flash in controls)
  1672. if (nNewLen > sizeof(szOld) ||
  1673. ::GetWindowText(hWndCtrl, szOld, sizeof(szOld)) != nNewLen ||
  1674. lstrcmp(szOld, strWndText) != 0)
  1675. {
  1676. // change it
  1677. ::SetWindowText(hWndCtrl, strWndText);
  1678. }
  1679. }
  1680. }