home *** CD-ROM | disk | FTP | other *** search
/ PC Media 7 / PC MEDIA CD07.iso / share / prog / cm / cmtime.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-06  |  6.9 KB  |  276 lines

  1. // CmTime.cpp
  2. // -----------------------------------------------------------------
  3. // Compendium - C++ Container Class Library
  4. // Copyright (C) 1992-1994, Glenn M. Poorman, All rights reserved
  5. // -----------------------------------------------------------------
  6. // Time class implementation.
  7. // -----------------------------------------------------------------
  8.  
  9. #include <time.h>
  10. #include <iostream.h>
  11. #include <iomanip.h>
  12. #include <cm/include/cmtime.h>
  13. #include <stdio.h>
  14.  
  15. // Static constant definitions.
  16. static const CmDate        refDate((unsigned) 0, (unsigned) 0);
  17. static const unsigned long SECONDS_IN_DAY  = 86400L;
  18. static const unsigned long SECONDS_IN_HOUR = 3600L;
  19. static const unsigned long SECONDS_IN_MIN  = 60L;
  20.  
  21. #if defined(hpux)          // For unix machines, use "gettimeofday"
  22.   class CmInitTime {       // function for time zones.
  23.   public:
  24.     CmInitTime();
  25.     long time_zone;
  26.     int  dst_observed;
  27.   };
  28.  
  29.   CmInitTime ___cm_global_init_time;
  30.   CmInitTime::CmInitTime()
  31.   {
  32.     struct timeval  tval;
  33.     struct timezone tz;
  34.     gettimeofday(&tval,&tz);
  35.     time_zone    = (long)(SECONDS_IN_MIN * (unsigned long) tz.tz_minuteswest);
  36.     dst_observed = tz.tz_dsttime;
  37.   }
  38.  
  39. # define TIME_ZONE    ___cm_global_init_time.time_zone
  40. # define DST_OBSERVED ___cm_global_init_time.dst_observed
  41. #else
  42. # define TIME_ZONE    timezone
  43. # define DST_OBSERVED daylight
  44. #endif
  45.  
  46. // Initialize display style.
  47. int CmTime::_displayStyle = CmTime::DATE12;
  48.  
  49.  
  50. // "CmTime" is the default time constructor.
  51. //
  52. CmTime::CmTime()
  53. {
  54.   time_t ltime = time(0);
  55.   struct tm *t = localtime(<ime);
  56.   CmDate today((unsigned)t->tm_mday, (unsigned)(t->tm_mon + 1),
  57.                (unsigned)t->tm_year);
  58.   _sec = localTime(today, (unsigned)t->tm_hour, (unsigned)t->tm_min,
  59.                   (unsigned)t->tm_sec)._sec;
  60.   if (isDST()) _sec -= SECONDS_IN_HOUR;
  61. }
  62.  
  63.  
  64. // "CmTime" constructs a time from the specified hour, minute,
  65. // and second.
  66. //
  67. CmTime::CmTime(unsigned h, unsigned m, unsigned s)
  68. {
  69.   _sec = CmTime(CmDate(), h, m, s)._sec;
  70. }
  71.  
  72.  
  73. // "CmTime" constructs a time from the specified date, hour, minute,
  74. // and second.
  75. //
  76. CmTime::CmTime(const CmDate& d, unsigned h, unsigned m, unsigned s)
  77. {
  78.   _sec = localTime(d, h, m, s)._sec;
  79.   if (isDST()) _sec -= SECONDS_IN_HOUR;
  80. }
  81.  
  82.  
  83. // "isDST" returns TRUE if this time is daylight savings time.
  84. //
  85. Bool CmTime::isDST() const
  86. {
  87.   if (!DST_OBSERVED) return FALSE;
  88.  
  89.   unsigned daycount = (unsigned)(_sec / SECONDS_IN_DAY);
  90.   unsigned year     = CmDate((unsigned) daycount, (unsigned) 0).year();
  91.  
  92.   return (*this >= beginDST(year) && *this < endDST(year));
  93. }
  94.  
  95.  
  96. // "localTime" returns the local time.
  97. //
  98. CmTime CmTime::localTime() const
  99. {
  100.   CmTime local_time(_sec - TIME_ZONE);
  101.   if (local_time.isDST()) local_time._sec += SECONDS_IN_HOUR;
  102.   return local_time;
  103. }
  104.  
  105.  
  106. // "hour" returns the hour number.
  107. //
  108. unsigned CmTime::hour() const
  109. {
  110.   return localTime().hourGMT();
  111. }
  112.  
  113.  
  114. // "hourGMT" returns the hour number (Greenwich mean time).
  115. //
  116. unsigned CmTime::hourGMT() const
  117. {
  118.   return (_sec % SECONDS_IN_DAY) / SECONDS_IN_HOUR;
  119. }
  120.  
  121.  
  122. // "minute" returns the minute number.
  123. //
  124. unsigned CmTime::minute() const
  125. {
  126.   return localTime().minuteGMT();
  127. }
  128.  
  129.  
  130. // "minuteGMT" returns the minute number (Greenwich mean time).
  131. //
  132. unsigned CmTime::minuteGMT() const
  133. {
  134.   return ((_sec % SECONDS_IN_DAY) % SECONDS_IN_HOUR) / SECONDS_IN_MIN;
  135. }
  136.  
  137.  
  138. // "second" returns the second number.
  139. //
  140. unsigned CmTime::second() const
  141. {
  142.   return ((_sec % SECONDS_IN_DAY) % SECONDS_IN_HOUR) % SECONDS_IN_MIN;
  143. }
  144.  
  145.  
  146. // "makeCurrent" makes this time the current time.
  147. //
  148. void CmTime::makeCurrent()
  149. {
  150.   time_t ltime = time(0);
  151.   struct tm *t = localtime(<ime);
  152.   CmDate today((unsigned)t->tm_mday, (unsigned)(t->tm_mon + 1),
  153.                (unsigned)t->tm_year);
  154.   _sec = localTime(today, (unsigned)t->tm_hour, (unsigned)t->tm_min,
  155.                   (unsigned)t->tm_sec)._sec;
  156.   if (isDST()) _sec -= SECONDS_IN_HOUR;
  157. }
  158.  
  159.  
  160. // "CmDate" operator returns a date object based on this time.
  161. //
  162. CmTime::operator CmDate() const
  163. {
  164.   unsigned long ls = _sec;
  165.   if (isDST()) ls += SECONDS_IN_HOUR;
  166.   unsigned long jn = ((unsigned long) 2415386L) + (ls / SECONDS_IN_DAY);
  167.   return CmDate(jn);
  168. }
  169.  
  170.  
  171. // "isEqual" compares this time with the specified time.
  172. //
  173. Bool CmTime::isEqual(CmObject* pObj) const
  174. {
  175.   if (!pObj->isA("CmTime")) return CmObject::isEqual(pObj);
  176.   return (((CmTime*) pObj)->_sec == _sec);
  177. }
  178.  
  179.  
  180. // "compare" compares this time with the specified time.
  181. //
  182. int CmTime::compare(CmObject* pObj) const
  183. {
  184.   if (!pObj->isA("CmTime")) return CmObject::compare(pObj);
  185.   unsigned long sc = ((CmTime*) pObj)->_sec;
  186.   return (_sec == sc ? 0 : (_sec > sc ? 1 : -1));
  187. }
  188.  
  189.  
  190. // "hash" hashes this time returning the hash value.
  191. //
  192. unsigned CmTime::hash(unsigned m) const
  193. {
  194.   return (unsigned) (_sec %  (unsigned long) m);
  195. }
  196.  
  197.  
  198. // "printOn" prints this time to the specified stream.
  199. //
  200. void CmTime::printOn(ostream& os) const
  201. {
  202.   if (CmTime::_displayStyle == DATE24 || CmTime::_displayStyle == DATE12)
  203.     os << CmDate(*this) << ' ';
  204.  
  205.   char buff[40];
  206.   if (CmTime::_displayStyle == DATE24 || CmTime::_displayStyle == NODATE24)
  207.   {
  208.     sprintf(buff, "%u:%02u:%02u ", hour(), minute(), second());
  209.     os << buff;
  210.   }
  211.   else
  212.   {
  213.     unsigned hh24 = hour();
  214.     unsigned hh12 = (hh24 > 12) ? hh24 - 12 : hh24;
  215.     sprintf(buff, "%u:%02u:%02u ", hh12, minute(), second());
  216.     os << buff << (hh24 < 12 ? "am" : "pm");
  217.   }
  218. }
  219.  
  220.  
  221. // "write" writes the time to the specified reserve binary file.
  222. //
  223. Bool CmTime::write(CmReserveFile& file) const
  224. {
  225.   return file.write(_sec);
  226. }
  227.  
  228.  
  229. // "read" reads the time from the specified reserve binary file.
  230. //
  231. Bool CmTime::read(CmReserveFile& file)
  232. {
  233.   return file.read(_sec);
  234. }
  235.  
  236.  
  237. // "beginDST" returns the time daylight savings time begins in the
  238. // specified year.
  239. //
  240. CmTime CmTime::beginDST(unsigned year)
  241. {
  242.   CmTime DSTtime(localTime(CmDate(31,"March",year).previous("Sunday")+7,2));
  243.  
  244.   if (year <= 1986)
  245.   {
  246.     DSTtime = localTime(CmDate(30,"April",year).previous("Sunday"),2);
  247.     if (year==1974) DSTtime = localTime(CmDate(6,"January",1974),2);
  248.     if (year==1975) DSTtime = localTime(CmDate(23,"February",1975),2);
  249.   }
  250.   return DSTtime;
  251. }
  252.  
  253.  
  254. // "endDST" returns the time daylight savings time ends in the
  255. // specified year.
  256. //
  257. CmTime CmTime::endDST(unsigned year)
  258. {
  259.   CmTime STDtime(localTime(CmDate(31,"October",year).previous("Sunday"),1));
  260.  
  261.   return STDtime;
  262. }
  263.  
  264.  
  265. // "localTime" returns the local time based on the date, hour, minute,
  266. // and second.
  267. //
  268. CmTime CmTime::localTime(const CmDate& d, unsigned h, unsigned m, unsigned s)
  269. {
  270.   unsigned long secs = SECONDS_IN_DAY  * (d - refDate).julNum() +
  271.                        SECONDS_IN_HOUR * (unsigned long) h      +
  272.                        SECONDS_IN_MIN  * (unsigned long) m      +
  273.                        (unsigned long) s + (unsigned long) TIME_ZONE;
  274.   return CmTime(secs);
  275. }
  276.