home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / yacl-012.zip / base / timeofda.cxx < prev    next >
C/C++ Source or Header  |  1995-04-08  |  10KB  |  459 lines

  1.  
  2.  
  3.  
  4.  
  5. /*
  6.  *
  7.  *          Copyright (C) 1994, M. A. Sridhar
  8.  *  
  9.  *
  10.  *     This software is Copyright M. A. Sridhar, 1994. You are free
  11.  *     to copy, modify or distribute this software  as you see fit,
  12.  *     and to use  it  for  any  purpose, provided   this copyright
  13.  *     notice and the following   disclaimer are included  with all
  14.  *     copies.
  15.  *
  16.  *                        DISCLAIMER
  17.  *
  18.  *     The author makes no warranties, either expressed or implied,
  19.  *     with respect  to  this  software, its  quality, performance,
  20.  *     merchantability, or fitness for any particular purpose. This
  21.  *     software is distributed  AS IS.  The  user of this  software
  22.  *     assumes all risks  as to its quality  and performance. In no
  23.  *     event shall the author be liable for any direct, indirect or
  24.  *     consequential damages, even if the  author has been  advised
  25.  *     as to the possibility of such damages.
  26.  *
  27.  */
  28.  
  29.  
  30.  
  31.  
  32. #ifdef __GNUC__
  33. #pragma implementation
  34. #endif
  35.  
  36.  
  37.  
  38. #include <iostream.h>
  39. #include <ctype.h>
  40. #include <time.h>
  41. #include <stdlib.h>
  42.  
  43.  
  44. #include "base/timeofda.h"
  45. #include "base/bytstrng.h"
  46. #include "base/string.h"
  47. #include "base/error.h"
  48. #include "base/stream.h"
  49.  
  50. // This constant is used of out of bound error checking ( 24 hrs * 3600 secs)
  51.  
  52. #define MAX_SECS 86400L
  53.  
  54. CL_DEFINE_CLASS(CL_TimeOfDay, _CL_TimeOfDay_CLASSID);
  55.  
  56.  
  57. //-------------------Constructors and Destructors----------------------
  58.  
  59. CL_TimeOfDay::CL_TimeOfDay()
  60. {
  61.     _numSecs = 0;
  62. }
  63.  
  64. CL_TimeOfDay::CL_TimeOfDay (long nsecs)
  65. {
  66.     _numSecs = nsecs % MAX_SECS;
  67. }
  68.  
  69.  
  70.  
  71. CL_TimeOfDay CL_TimeOfDay::Now ()
  72. {
  73.     time_t long_secs;
  74.     struct tm *time_struct_ptr;
  75.     long_secs = time(NULL);
  76.     time_struct_ptr = localtime(&long_secs);
  77.     return CL_TimeOfDay (time_struct_ptr->tm_hour * 3600L +
  78.                time_struct_ptr->tm_min * 60L +
  79.                time_struct_ptr->tm_sec);
  80. }
  81.  
  82.  
  83. CL_TimeOfDay::CL_TimeOfDay (short hour, short min, short sec)
  84. {
  85.     _numSecs = hour * 3600L + min * 60 + sec;
  86.     if (! (hour >= 0 && hour < 24) ) {
  87.         CL_Error::Warning
  88.              ("CL_TimeOfDay constructor: invalid hour %d", hour);
  89.         _numSecs = 0;
  90.     }
  91.     if (! (min >= 0 && min < 60) ) {
  92.         CL_Error::Warning
  93.              ("CL_TimeOfDay constructor: invalid minutes %d", min);
  94.         _numSecs = 0;
  95.     }
  96.     if (! (sec >= 0 && sec < 60) ) {
  97.         CL_Error::Warning
  98.              ("CL_TimeOfDay constructor: invalid seconds %d", sec);
  99.         _numSecs = 0;
  100.     }
  101. }
  102.  
  103. CL_TimeOfDay::CL_TimeOfDay (const CL_String& s)
  104. {
  105.     *this = s;
  106. }
  107.  
  108. void CL_TimeOfDay::operator= (const CL_String& s)
  109. {
  110.     if (!PrepareToChange())
  111.         return;
  112.     if (s.Size() == 0) {
  113.         _numSecs = 0;
  114.         Notify ();
  115.         return;
  116.     }
  117.     long l = ParseAndConvert (s);
  118.     if (l < 0) {
  119.         // CL_Error::Warning ("CL_TimeOfDay::op= (const CL_String&): "
  120.         //                    "Invalid form '%s'", (char*) s);
  121.         _numSecs = 0;
  122.     }
  123.     else
  124.         _numSecs = l;
  125.     Notify ();
  126. }
  127.  
  128.  
  129. long CL_TimeOfDay::ParseAndConvert (const CL_String& s)
  130. {
  131.     CL_String fld[4];
  132.     short hour, min, sec;
  133.  
  134.     short n;
  135.     if ((n = s.Split (fld, 4, ":")) == 2 || n == 3) {
  136.         hour = (short) fld[0].AsLong ();
  137.         min  = (short) fld[1].AsLong ();
  138.         sec  = (short) fld[2].AsLong ();
  139.     }
  140.     else if (s.Split (fld, 4, ": ") == 3) {
  141.         hour = (short) fld[0].AsLong ();
  142.         min  = (short) fld[1].AsLong ();
  143.         sec = 0;
  144.         if (fld[2] == "pm")
  145.             hour += 12;
  146.     }
  147.     else {
  148.         // Assume that it's either four or six digits, and try to parse it.
  149.         for (short i = 0; i < s.Size(); i++) {
  150.             if (s[i] > '9' || s[i] < '0') {
  151.                 return -1;
  152.             }
  153.         }
  154.         hour = (s[0]-'0')*10 + s[1]-'0';
  155.         min  = (s[2]-'0')*10 + s[3]-'0';
  156.         if (s.Size() == 6) {
  157.             sec  = (s[4]-'0')*10 + s[5]-'0';
  158.         }
  159.         else
  160.             sec = 0;
  161.     }
  162.     if (! (hour >= 0 && hour < 24) ) {
  163.         return -1;
  164.     }
  165.     if (! (min >= 0 && min < 60) ) {
  166.         return -1;
  167.     }
  168.     if (! (sec >= 0 && sec < 60) ) {
  169.         return -1;
  170.     }
  171.     return (hour * 3600L + min * 60 + sec);
  172. }    
  173.  
  174.         
  175.         
  176.         
  177.  
  178.  
  179. CL_TimeOfDay::CL_TimeOfDay (const CL_TimeOfDay& a_time)
  180. {
  181.     _numSecs = a_time._numSecs;
  182. }
  183.  
  184.  
  185. CL_TimeOfDay::~CL_TimeOfDay()
  186. {
  187. }
  188.  
  189.  
  190.  
  191.  
  192. short CL_TimeOfDay::Hour () const
  193. {
  194.     return _numSecs/3600;
  195. }
  196.  
  197.  
  198. short CL_TimeOfDay::Minute() const
  199. {
  200.     return (_numSecs%3600)/60;
  201. }
  202.  
  203.  
  204. short CL_TimeOfDay::Second() const
  205. {
  206.     return (_numSecs%3600)%60; 
  207. }
  208.  
  209.  
  210.  
  211. //-----------------------Printable string conversion ----------------
  212.  
  213.  
  214.  
  215. CL_String CL_TimeOfDay::PrintString (TimePrintForm form) const
  216. {
  217.     CL_String time_string;
  218.     long hour = Hour();
  219.     long min = Minute();
  220.     long sec = Second();
  221.     switch (form) {
  222.     case Time_Military:
  223.     {
  224.         CL_String smin (min, 2, '0'), ssec (sec, 2, '0');
  225.         time_string =  CL_String(hour, 2, '0') + ":" + smin + ":" + ssec;
  226.         break;
  227.     }
  228.  
  229.     
  230.     case Time_Normal:
  231.     default:
  232.     {
  233.         CL_String tmin (min, 2);
  234.         if (hour > 12) {
  235.             hour -= 12;
  236.             time_string = CL_String(hour) + ":" + tmin + " pm";
  237.         }
  238.         else if (hour == 12)
  239.             time_string = CL_String(hour) + ":" + tmin + " pm";
  240.         else
  241.             time_string = CL_String(hour) + ":" + tmin + " am";
  242.         break;
  243.     }
  244.         
  245.     }
  246.     return time_string;
  247. }
  248.  
  249.  
  250.  
  251.  
  252.  
  253. //----------------------Modification---------------------------------
  254.  
  255.  
  256. CL_TimeOfDay& CL_TimeOfDay::operator= (const CL_TimeOfDay& a_time)
  257. {
  258.     if (this == &a_time || !PrepareToChange())
  259.         return *this;
  260.     _numSecs = a_time._numSecs;
  261.     Notify ();
  262.     return *this;
  263. }
  264.  
  265. //-------------------TimeOfDay arithmetic---------------------------
  266.  
  267.  
  268. CL_TimeOfDay CL_TimeOfDay::operator+ (long seconds) const
  269. {
  270.     CL_TimeOfDay new_time;
  271.     new_time._numSecs = _numSecs + seconds;
  272.     if (new_time._numSecs >= MAX_SECS)
  273.         new_time._numSecs -= MAX_SECS;
  274.     return new_time;
  275. }
  276.  
  277.  
  278.  
  279. CL_TimeOfDay& CL_TimeOfDay::operator+= (long seconds)
  280. {
  281.     if (!PrepareToChange())
  282.         return *this;
  283.     _numSecs += seconds;
  284.     if (_numSecs >= MAX_SECS)
  285.         _numSecs -= MAX_SECS;
  286.     Notify ();
  287.     return *this;
  288. }
  289.  
  290.  
  291.  
  292. CL_TimeOfDay CL_TimeOfDay::operator- (long seconds) const
  293. {
  294.     CL_TimeOfDay new_time;
  295.     new_time._numSecs = _numSecs - seconds;
  296.     if (new_time._numSecs < 0)
  297.         new_time._numSecs += MAX_SECS;
  298.     return new_time;
  299. }
  300.  
  301.  
  302. CL_TimeOfDay& CL_TimeOfDay::operator-= (long seconds)
  303. {
  304.     if (PrepareToChange()) {
  305.         _numSecs -= seconds;
  306.         if (_numSecs < 0)
  307.             _numSecs += MAX_SECS;
  308.         Notify ();
  309.     }
  310.     return *this;
  311. }
  312.  
  313.  
  314.  
  315. long CL_TimeOfDay::operator- (const CL_TimeOfDay& a_time) const
  316. {
  317.     return (_numSecs - a_time._numSecs);
  318. }
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329. void CL_TimeOfDay::FromStream (istream& s)
  330. {
  331.     CL_String rep;
  332.     char c;
  333.     long count = 0;
  334.     char fill_char = s.fill ();
  335.     
  336.     while (s.get (c) && c == fill_char);
  337.     if (!s.good() || s.eof()) {
  338.         _numSecs = 0;
  339.         return;
  340.     }
  341.     do {
  342.         if (isalnum (c) || c == ':') {
  343.             rep.Append (c);
  344.             count++;
  345.         }
  346.         else
  347.             break;
  348.     } while (s.get (c));
  349.  
  350.     long n = ParseAndConvert (rep);
  351.     if (n > 0) {
  352.         if (!s.eof())
  353.             s.putback (c);
  354.         _numSecs = n;
  355.     }
  356.     else {
  357.         s.seekg (s.tellg() - count, istream::cur);
  358.         _numSecs = 0;
  359.     }
  360. }
  361.  
  362.  
  363.  
  364.  
  365. bool CL_TimeOfDay::ReadFrom (const CL_Stream& s)
  366. {
  367.     if (!PrepareToChange() || !ReadClassId (s) || !s.Read (_numSecs))
  368.         return FALSE;
  369.     Notify();
  370.     return TRUE;
  371. }
  372.  
  373.  
  374.  
  375. bool CL_TimeOfDay::WriteTo (CL_Stream& s) const
  376. {
  377.     return s.Write (ClassId())  && s.Write (_numSecs);
  378. }
  379.  
  380. long CL_TimeOfDay::StorableFormWidth() const
  381. {
  382.     return sizeof (CL_ClassId) + sizeof (long);
  383. }
  384.  
  385.  
  386.  
  387. bool CL_TimeOfDay::operator<  (const CL_Object& o) const
  388. {
  389.     if (!IsA (o))
  390.         return FALSE;
  391.     return *this < ((const CL_TimeOfDay&) o);
  392. }
  393.  
  394.  
  395. bool CL_TimeOfDay::operator<= (const CL_Object& o) const
  396. {
  397.     if (!IsA (o))
  398.         return FALSE;
  399.     return *this <= ((const CL_TimeOfDay&) o);
  400. }
  401.  
  402.  
  403. bool CL_TimeOfDay::operator>  (const CL_Object& o) const
  404. {
  405.     if (!IsA (o))
  406.         return FALSE;
  407.     return *this > ((const CL_TimeOfDay&) o);
  408. }
  409.  
  410.  
  411. bool CL_TimeOfDay::operator>= (const CL_Object& o) const
  412. {
  413.     if (!IsA (o))
  414.         return FALSE;
  415.     return *this >= ((const CL_TimeOfDay&) o);
  416. }
  417.  
  418.  
  419.  
  420. bool CL_TimeOfDay::operator== (const CL_Object& o) const
  421. {
  422.     if (!IsA (o))
  423.         return FALSE;
  424.     return *this == ((const CL_TimeOfDay&) o);
  425. }
  426.  
  427.  
  428.  
  429. bool CL_TimeOfDay::operator!= (const CL_Object& o) const
  430. {
  431.     if (!IsA (o))
  432.         return FALSE;
  433.     return *this != ((const CL_TimeOfDay&) o);
  434. }
  435.  
  436.  
  437.  
  438.  
  439. bool CL_TimeOfDay::IsBetween  (const CL_TimeOfDay& t1, const CL_TimeOfDay&
  440.                                t2) const
  441. {
  442.     return _numSecs >= minl (t1._numSecs, t2._numSecs) &&
  443.         _numSecs <= maxl (t1._numSecs, t2._numSecs);
  444. }
  445.  
  446.  
  447.  
  448.  
  449.  
  450. #if defined(__GNUC__) && __GNUC_MINOR__ >= 6
  451. #include "base/cmparatr.h"
  452. #include "base/basicops.h"
  453. #include "base/binding.h"
  454.  
  455. template class CL_Binding<CL_TimeOfDay>;
  456. template class CL_Comparator<CL_TimeOfDay>;
  457. template class CL_Basics<CL_TimeOfDay>;
  458. #endif
  459.