458066f9ddada8c492acf75d670502191da72a92
[ctsim.git] / libctsupport / timedate.cpp
1 /*****************************************************************************
2 **  This is part of the CTSim program
3 **  Copyright (C) 1983-2000 Kevin Rosenberg
4 **
5 **  $Id: timedate.cpp,v 1.2 2000/06/19 19:04:05 kevin Exp $
6 **
7 **  This program is free software; you can redistribute it and/or modify
8 **  it under the terms of the GNU General Public License (version 2) as
9 **  published by the Free Software Foundation.
10 **
11 **  This program is distributed in the hope that it will be useful,
12 **  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 **  GNU General Public License for more details.
15 **
16 **  You should have received a copy of the GNU General Public License
17 **  along with this program; if not, write to the Free Software
18 **  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 ******************************************************************************/
20
21 /*----------------------------------------------------------------------*/
22 /*                      ROUTINES THAT MANAGE TIME                       */
23 /*----------------------------------------------------------------------*/
24
25 #include <stdio.h>
26 #include <time.h>
27 #include "ctsupport.h"
28
29
30 /* NAME
31  *    td_get_time                       Return time of day
32  *
33  * SYNOPSIS
34  *    t = td_get_time (t)
35  *    TIME *t;                          Returned time
36  */
37
38 TIME *
39 td_get_time (TIME *t)
40 {
41   time_t currtime;
42   struct tm *tm;
43
44   currtime = time(NULL);
45   tm = localtime(&currtime);
46
47   t->hour   = tm->tm_hour;
48   t->minute = tm->tm_min; 
49   t->second = tm->tm_sec; 
50   t->ms     = 0;       
51
52   return (t);
53 }
54
55
56 DATE *
57 td_get_date (DATE *d)
58 {
59   time_t t = time(NULL);
60   struct tm *lt = localtime(&t);
61
62   d->year = lt->tm_year + 1900;
63   d->month = lt->tm_mon;
64   d->month++;
65   d->date = lt->tm_mday;
66   d->dow = lt->tm_wday;
67   d->dow++;
68
69   return (d);
70 }
71
72 double td_current_sec (void)
73 {
74         TIME t;
75
76         td_get_time (&t);
77         return (td_time_to_sec (&t));
78 }
79
80
81 double 
82 td_time_to_sec (TIME *t)
83 {
84         double ts;
85
86         ts = t->hour * 3600.;
87         ts += t->minute * 60.;
88         ts += t->second;
89         ts += t->ms / 1000.;
90
91         return (ts);
92 }
93
94
95 TIME *
96 td_time_sub (const TIME *t1, const TIME *t2, TIME *tdiff)
97 {
98         tdiff->hour   = t1->hour   - t2->hour;
99         tdiff->minute = t1->minute - t2->minute;
100         tdiff->second = t1->second - t2->second;
101         tdiff->ms     = t1->ms     - t2->ms;
102
103         return td_time_norm (tdiff);
104 }
105
106
107 TIME *
108 td_time_add (const TIME *t1, const TIME *t2, TIME *tsum)
109 {
110         tsum->ms       = t1->ms     + t2->ms;
111         tsum->second   = t1->second + t2->second;
112         tsum->minute   = t1->minute + t2->minute;
113         tsum->hour     = t1->hour   + t2->hour;
114
115         return td_time_norm (tsum);
116 }
117
118
119 TIME *
120 td_time_copy (TIME *to, const TIME *from)
121 {
122         to->ms       = from->ms;
123         to->second   = from->second;
124         to->minute   = from->minute;
125         to->hour     = from->hour;
126
127         return (to);
128 }
129
130
131 /* NAME
132  *      td_time_norm                    Normalize time in structure
133  *
134  * SYNOPSIS
135  *      t = td_time_norm (t)
136  *      TIME *t                         Time to be normalized
137  */
138
139 TIME *
140 td_time_norm (TIME *t)
141 {
142         while (t->ms < 0) {
143             t->ms += 1000;
144             t->second--;
145         }
146         while (t->second < 0) {
147             t->second += 60;
148             t->minute--;
149         }
150         while (t->minute < 0) {
151             t->minute += 60;
152             t->hour--;
153         }
154
155         while (t->ms > 1000) {
156             t->ms -= 1000;
157             t->second++;
158         }
159         while (t->second > 60) {
160             t->second -= 60;
161             t->minute++;
162         }
163         while (t->minute > 60) {
164             t->minute -= 60;
165             t->hour++;
166         }
167
168         return (t);
169 }
170
171
172 /* NAME
173  *    td_get_tmdt                       Return current time and date
174  *
175  * SYNOPSIS
176  *    get_tmdt (td)
177  *    TIMEDATE *td                      Pointer to structure that holds time & date
178  */
179
180 void 
181 td_get_tmdt (TIMEDATE *td)
182 {
183         td_get_date (&td->d);
184         td_get_time (&td->t);
185 }
186
187
188 /* NAME
189  *      td_str_tmdt             Put time & date into string
190  *
191  * SYNOPSIS
192  *      str = td_str_tmdt (td)
193  *      TIMEDATE *td            Pointer ot time & date structure
194  *      char *str               Pointer to output string (Width = 21 chars)
195  *
196  * NOTES
197  *          str points to a area of memory devoted to this routine
198  *      DO NOT make any changes to str
199  */
200
201 const char *
202 td_str_tmdt (const TIMEDATE *td)
203 {
204         static char str[80];
205
206         strncpy (str, td_str_date(&td->d), sizeof(str));
207         strncat (str, " ", sizeof(str));
208         strncat (str, td_str_stime(&td->t), sizeof(str));
209
210         return (str);
211 }
212
213
214 /* NAME
215  *   td_str_time                        Convert time into long string form
216  *
217  * SYNOPSIS
218  *   str = td_str_time (t)
219  *   char *str                          Output string (Field width = 12 chars)
220  *   TIME *t                            Time to be converted
221  */
222  
223 const char *
224 td_str_time (const TIME *t)
225 {
226         static char str[80];
227         char am_pm;
228         int hour;
229
230         hour = t->hour;
231         if (hour < 12) {
232             am_pm = 'a';
233             if (hour == 0)
234                 hour = 12;
235         } else if (hour >= 12) {
236             am_pm = 'p';
237             if (hour > 12)
238                 hour -= 12;
239         }
240
241         snprintf (str, sizeof(str), "%2d:%02d:%02d.%03d%c",
242                 hour, t->minute, t->second, t->ms, am_pm);
243
244         return (str);
245 }
246
247
248
249 /* NAME
250  *   td_str_stime                       Convert time into short string form
251  *
252  * SYNOPSIS
253  *   str = td_str_stime (t)
254  *   char *str                          Output string (Field width = 6 chars)
255  *   TIME *t                            Time to be converted
256  */
257  
258 const char *
259 td_str_stime (const TIME *t)
260 {
261         static char str[80];
262         char am_pm;
263         int hour;
264
265         hour = t->hour;
266         if (hour < 12) {
267             am_pm = 'a';
268             if (hour == 0)
269                 hour = 12;
270         } else if (hour >= 12) {
271             am_pm = 'p';
272             if (hour > 12)
273                 hour -= 12;
274         }
275
276         snprintf (str, sizeof(str), "%2d:%02d%c",
277                 hour, t->minute, am_pm);
278
279         return (str);
280 }
281
282
283 /* NAME
284  *      td_str_date             Convert date to string form
285  *
286  * SYNOPSIS
287  *      str = td_str_date (d)
288  *      DATE *d                 Date to be converted
289  *      char *str               Pointer to output string (Width = 8 chars)
290  *
291  * NOTES
292  *      DO NOT make any changes to str.  It belongs to this routine
293  */
294
295 const char *
296 td_str_date (const DATE *d)
297 {
298         static char str[80];
299
300         snprintf (str, sizeof(str), "%2d-%02d-%02d", d->month, d->date, d->year - 1900);
301
302         return (str);
303 }
304
305 /*-----------------------------------------------------------------------------
306  * NAME
307  *   td_str_cdate                       Convert date to a character string
308  *
309  * SYNOPSIS
310  *   str = td_str_cdate (d)
311  *   DATE *d                            Date to convert
312  *   char *str                          Pointer to date in character format
313  *
314  * DESCRIPTION
315  *    The date is put in the form:
316  *          <day name>, <month name> <date>, <year>
317  *
318  *    Field width ranges from 17 to 29 characters
319  *
320  * NOTES
321  *    str belongs to this routine, do NOT alter str
322  *---------------------------------------------------------------------------*/
323
324
325 char *
326 td_str_cdate (DATE *d)
327 {
328         static char str[50];
329         char temp[50];
330
331         strcpy (str, "");
332
333         if (d->dow != 0) {                      /* only print day name if dow != 0 */
334             strcat (str, td_day_name(d->dow));
335             strcat (str, ", ");
336         }
337
338         snprintf (temp, sizeof(temp), "%s %d, %d", td_month_name(d->month), d->date, d->year);
339         strcat (str, temp);
340
341         return (str);
342 }
343
344
345 /*--------------------------------------------------------------*/
346 /* td_month_name(int n)                                         */
347 /*      return pointer to name of month given month number, n   */
348 /*--------------------------------------------------------------*/
349 char *
350 td_month_name ( /* return name of n-th month */
351     int n
352 )
353 {
354         static char *name[] = {
355             "",
356             "January",
357             "February",
358             "March",
359             "April",
360             "May",
361             "June",
362             "July",
363             "August",
364             "September",
365             "October",
366             "November",
367             "December"
368         };
369
370         return ((n < 1 || n > 12) ? name[0] : name[n]);
371 }
372
373
374 /*--------------------------------------------------------------*/
375 /* td_day_name(int n)                                           */
376 /*      return pointer to name of day given day number, n (1..7)*/
377 /*--------------------------------------------------------------*/
378 char *
379 td_day_name (int n)
380 {
381         static char *name[] = {
382             "",
383             "Monday",
384             "Tuesday",
385             "Wednesday",
386             "Thursday",
387             "Friday",
388             "Saturday",
389             "Sunday"
390         };
391
392         return ((n < 1 || n > 7) ? name[0] : name[n]);
393 }