libDtCmP: use TIRPC on linux, fix some warnings
[oweals/cde.git] / cde / programs / dtcm / libDtCmP / timeops.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /*******************************************************************************
24 **
25 **  timeops.c
26 **
27 **  $XConsortium: timeops.c /main/6 1996/11/21 19:44:23 drk $
28 **
29 **  RESTRICTED CONFIDENTIAL INFORMATION:
30 **
31 **  The information in this document is subject to special
32 **  restrictions in a confidential disclosure agreement between
33 **  HP, IBM, Sun, USL, SCO and Univel.  Do not distribute this
34 **  document outside HP, IBM, Sun, USL, SCO, or Univel without
35 **  Sun's specific written approval.  This document and all copies
36 **  and derivative works thereof must be returned or destroyed at
37 **  Sun's request.
38 **
39 **  Copyright 1993 Sun Microsystems, Inc.  All rights reserved.
40 **
41 *******************************************************************************/
42
43 /*                                                                      *
44  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
45  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
46  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
47  * (c) Copyright 1993, 1994 Novell, Inc.                                *
48  */
49
50 #ifndef lint
51 static char sccsid[] = "@(#)timeops.c 1.13 95/05/02 Copyr 1991 Sun Microsystems, Inc.";
52 #endif
53
54 #include <EUSCompat.h>
55 #include <stdio.h>
56 #include <unistd.h>
57 #include <stdlib.h>
58
59 #define XOS_USE_NO_LOCKING
60 #define X_INCLUDE_TIME_H
61 #if defined(__linux__)
62 #undef SVR4
63 #endif
64 #include <X11/Xos_r.h>
65 #if defined(__linux__)
66 #define SVR4
67 #endif
68
69 #include <sys/param.h>
70 #include <sys/time.h>
71 #include <csa.h>
72 #include "util.h"
73 #include "timeops.h"
74 #include "getdate.h"
75
76 extern int debug;
77
78 typedef enum {dstoff, dston, nochange} DSTchange;
79
80 Tick bot, eot;
81
82 char *months[] = {"",
83            (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL,
84            (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL,
85            (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL
86 };
87
88 char *months2[] = {"",
89            (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL,
90            (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL,
91            (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL
92 };
93
94 int monthdays[12] = {
95         31,     28,     31,
96         30,     31,     30,
97         31,     31,     30,
98         31,     30,     31
99 };
100
101 int monthsecs[12] = {
102         31*daysec,      28*daysec,      31*daysec,
103         30*daysec,      31*daysec,      30*daysec,
104         31*daysec,      31*daysec,      30*daysec,
105         31*daysec,      30*daysec,      31*daysec
106 };
107
108 char *days[8] = {(char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL};
109
110 char *days2[8] = {(char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL};
111
112 char *days3[8] = {(char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL};
113
114 char *days4[8] = {(char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL};
115
116 char *numbers[32] = {"",
117         " 1 ", " 2 ", " 3 ", " 4 ", " 5 ", " 6 ", " 7 ",
118         " 8 ", " 9 ", "10", "11", "12", "13", "14",
119         "15", "16", "17", "18", "19", "20", "21",
120         "22", "23", "24", "25", "26", "27", "28",
121         "29", "30", "31"
122 };
123
124 char *hours[24] = {
125         "12", " 1", " 2", " 3", " 4", " 5", " 6", " 7", " 8", " 9", "10", "11",
126         "12", " 1", " 2", " 3", " 4", " 5", " 6", " 7", " 8", " 9", "10", "11"
127 };
128
129 /*
130  * Given a weekmask and the first day of the week, calculate
131  * the number of times outstanding in the week.
132  */
133 extern int
134 ntimes_this_week(u_int weekmask, int firstday)
135 {
136         int i, ntimes, weekdaymask = 1 << firstday;
137
138         if (weekmask == 0)
139                 return 0;
140
141         for (i=firstday, ntimes=0; i < 7; i++, weekdaymask <<= 1) {
142                 if (weekdaymask & weekmask)
143                         ntimes++;
144         }
145         return ntimes;
146 }
147
148 /* Return beginning of time */
149 extern Tick
150 get_bot()
151 {
152         return bot;
153 }
154
155 /* Return end of time */
156 extern Tick
157 get_eot()
158 {
159         return eot;
160 }
161
162 /* Given a weekmask, find the last appointment in the week */
163 extern int
164 lastapptofweek(u_int mask)
165 {
166         int n;
167
168         if (mask == 0)
169                 return -1;
170
171         for (n = -1; mask != 0; n++, mask = mask >> 1);
172
173         return n;
174 }
175
176 /*      Remove after v3 release */
177 extern boolean_t
178 magic_time(Tick t)
179 {
180         boolean_t magic=B_FALSE;
181         struct tm *tm;
182         _Xltimeparams localtime_buf;
183
184         tm = _XLocaltime(&t, localtime_buf);
185
186         if (tm->tm_hour == 3 && tm->tm_min == 41)
187                  magic=B_TRUE;
188         return(magic);
189 }
190 /* for 12 hour clock, if 24 subtract 12 */
191 extern boolean_t
192 adjust_hour(int *hr)
193 {
194         boolean_t am = B_TRUE;
195
196         if (*hr == 0)
197                 *hr = 12;
198         else if (*hr >= 12) {
199                 if (*hr > 12)
200                         *hr -= 12;
201                 am = B_FALSE;
202         }
203         return am;
204 }
205
206
207 extern int
208 timeok( Tick t)
209 {
210         int r =((t >= bot) &&(t <= eot));
211         return(r);
212 }
213
214 static DSTchange
215 dst_changed(Tick old, Tick new)
216 {       
217         struct tm oldtm;
218         struct tm newtm;
219         _Xltimeparams localtime_buf;
220
221         oldtm   = *_XLocaltime(&old, localtime_buf);
222         newtm   = *_XLocaltime(&new, localtime_buf);
223         
224         if(oldtm.tm_isdst ==  newtm.tm_isdst) return(nochange);
225         switch(oldtm.tm_isdst) {
226                 case 1:
227                         return(dstoff);
228                 case 0:
229                         return(dston);
230                 default:
231                         return(nochange);
232         }
233 }
234         
235 extern int
236 seconds(int n, Unit unit)
237 {
238         return(n *(int)unit);
239 }
240
241 extern double
242 seconds_dble(double n, Unit unit)
243 {
244         return((double)(n * (int)unit));
245 }
246
247 extern int
248 year(Tick t)
249 {
250         struct tm *tm;
251         _Xltimeparams localtime_buf;
252
253         tm = _XLocaltime(&t, localtime_buf);
254         return(tm->tm_year + 1900);
255 }
256
257 extern int
258 month(t)
259         Tick t;
260 {
261         struct tm *tm;
262         _Xltimeparams localtime_buf;
263
264         tm = _XLocaltime(&t, localtime_buf);
265         return(tm->tm_mon+1);
266 }
267
268 extern int
269 hour(Tick t)
270 {
271         struct tm *tm;
272         _Xltimeparams localtime_buf;
273
274         tm = _XLocaltime(&t, localtime_buf);
275         return(tm->tm_hour);
276 }
277
278 extern int
279 minute(Tick t)
280 {
281         struct tm *tm;
282         _Xltimeparams localtime_buf;
283
284         tm = _XLocaltime(&t, localtime_buf);
285         return(tm->tm_min);
286 }
287
288 extern int
289 leapyr(int y)
290 {
291         return
292          (y % 4 == 0 && y % 100 !=0 || y % 400 == 0);
293 }
294
295 extern int
296 monthlength(Tick t)
297 {
298         int mon;
299         struct tm tm;
300         _Xltimeparams localtime_buf;
301
302         tm = *_XLocaltime(&t, localtime_buf);
303         mon = tm.tm_mon;
304         return(((mon==1) && leapyr(tm.tm_year+1900))? 29 : monthdays[mon]);
305 }
306
307 extern int
308 monthseconds(Tick t)
309 {
310         int mon;
311         struct tm tm;
312         _Xltimeparams localtime_buf;
313         
314         tm = *_XLocaltime(&t, localtime_buf);
315         mon = tm.tm_mon;
316         return(((mon==1) && leapyr(tm.tm_year+1900))? 29*daysec : monthsecs[mon]);
317 }
318
319 extern int
320 dom(Tick t)
321 {
322         struct tm *tm;
323         _Xltimeparams localtime_buf;
324
325         tm = _XLocaltime(&t, localtime_buf);
326         return(tm->tm_mday);
327 }
328
329 extern int
330 wom(Tick t)
331 {
332         struct tm *tm;
333         _Xltimeparams localtime_buf;
334
335         tm = _XLocaltime(&t, localtime_buf);
336         return((12 + tm->tm_mday - tm->tm_wday)/7);
337 }
338
339 /*
340  * If the result falls beyond the system limit, -1 is returned by mktime().
341  */
342 Tick
343 next_nmonth(Tick t, int n)
344 {
345         struct tm tm;
346         int     n12;
347         _Xltimeparams localtime_buf;
348
349         n12 = n/12;
350         n = n%12;
351
352         tm = *_XLocaltime(&t, localtime_buf);
353         tm.tm_hour=0;
354         tm.tm_min=0;
355         tm.tm_sec=0;
356         tm.tm_mday=1;
357         if (n12 > 0)
358                 tm.tm_year += n12;
359
360         if ((tm.tm_mon = tm.tm_mon + n) > 11) {
361                 tm.tm_mon -= 12;
362                 tm.tm_year++;
363         }
364
365         tm.tm_isdst = -1;
366         return(mktime(&tm));
367 }
368
369 extern Tick
370 nextmonth(Tick t)
371 {
372         return(next_nmonth(t, 1));
373 }
374
375 extern boolean_t
376 weekofmonth(Tick t, int *wk)
377 {
378         struct tm tm, tm1, tm2;
379         Tick    firstday;
380         _Xltimeparams localtime_buf;
381
382         tm = *_XLocaltime(&t, localtime_buf);
383         tm.tm_hour = 0;
384         tm.tm_min = 0;
385         tm.tm_sec = 0;
386         tm.tm_mday = 1;
387         firstday = mktime(&tm);
388         tm = *_XLocaltime(&firstday, localtime_buf);
389
390         /* need to get it again since data in tm is changed */
391         tm1 = *_XLocaltime(&t, localtime_buf);
392
393         *wk = wom(t);
394         if (tm1.tm_wday < tm.tm_wday)
395                 (*wk)--;
396
397         if (*wk < 4)
398                 return B_FALSE;
399         else {
400                 t += seconds(7, daysec);
401                 tm2 = *_XLocaltime(&t, localtime_buf);
402
403                 return((tm1.tm_mon == tm2.tm_mon) ? B_FALSE : B_TRUE);
404         }
405 }
406
407 extern int
408 dow(Tick t)
409 {
410         struct tm tm;
411         _Xltimeparams localtime_buf;
412
413         tm = *_XLocaltime(&t, localtime_buf);
414         return(tm.tm_wday);
415 }
416
417 extern int /* find dow(0-6) that 1st dom falls on */
418 fdom(Tick t)
419 {
420         struct tm tm;
421         _Xltimeparams localtime_buf;
422
423         tm              = *_XLocaltime(&t, localtime_buf);
424         tm.tm_mday      = 1;
425         tm.tm_isdst     = -1;
426         t               = mktime(&tm);
427         tm              = *_XLocaltime(&t, localtime_buf);
428         return(tm.tm_wday);
429 }
430
431 extern int
432 ldom(Tick t /* find dow(0-6) that last dom falls on */ )
433 {
434         struct tm tm;
435         _Xltimeparams localtime_buf;
436
437         tm              = *_XLocaltime(&t, localtime_buf);
438         tm.tm_mday      = monthlength(t);
439         tm.tm_isdst     = -1;
440         t               = mktime(&tm);
441         tm              = *_XLocaltime(&t, localtime_buf);
442         return(tm.tm_wday);
443 }
444
445 /* returns tick of last day of month */
446 extern Tick
447 last_dom(Tick tick)
448 {
449         return(upperbound(next_ndays(tick, monthlength(tick) - dom(tick))));
450 }
451
452 /* returns tick of first day of month */
453 extern Tick
454 first_dom(Tick tick)
455 {
456         return(lowerbound(last_ndays(tick, dom(tick)-1)));
457 }
458
459 /* returns tick of first day of week */
460 extern Tick
461 first_dow(Tick tick)
462 {
463         int d;
464
465         if ((d = dow(tick)) == 0)
466                 d = 6;
467         else 
468                 d--;
469
470         return(lowerbound(last_ndays(tick, d)));
471 }
472
473 /* returns tick of first day of week */
474 extern Tick
475 last_dow(Tick tick)
476 {
477         int d;
478
479         if ((d = dow(tick)) == 0)
480                 d = 6;
481         else 
482                 d--;
483         d = 6 - d;
484
485         return(upperbound(next_ndays(tick, d)));
486 }
487 /* returns number of weeks in month */
488 extern int
489 numwks(Tick tick)
490 {
491         return (wom(last_dom(tick)));
492 }
493
494 extern int
495 adjust_dst(Tick start, Tick next) 
496 {
497         DSTchange change;
498         change = dst_changed(start, next);
499         switch(change) {
500                 case nochange:
501                 break;
502                 case dstoff:
503                         next+=(int) hrsec;
504                 break;
505                 case dston:
506                         next-=(int) hrsec;
507                 break;
508         }
509         return(next);
510 }
511
512 extern Tick
513 next_nhours(Tick t, int n)
514 {
515         Tick next;
516         struct tm tm;
517         _Xltimeparams localtime_buf;
518
519         tm              = *_XLocaltime(&t, localtime_buf);
520         tm.tm_sec       = 0;
521         tm.tm_min       = 0;
522  
523         next            = mktime(&tm);
524         next            = next + seconds(n, hrsec);
525         next            = adjust_dst(t, next);
526         return(next);
527 }
528
529 extern Tick
530 last_ndays(Tick t, int n)
531 {
532         Tick last;
533         struct tm tm;
534         _Xltimeparams localtime_buf;
535
536         tm              = *_XLocaltime(&t, localtime_buf);
537         tm.tm_sec       = 0;
538         tm.tm_min       = 0;
539         tm.tm_hour      = 0;
540
541         last            = mktime(&tm);
542         last            = last - seconds(n, daysec);
543         last            = adjust_dst(t, last);
544         return(last);
545 }
546
547 extern Tick
548 next_ndays(Tick t, int n)
549 {
550         Tick next;
551         struct tm tm;
552         _Xltimeparams localtime_buf;
553
554         tm              = *_XLocaltime(&t, localtime_buf);
555         tm.tm_sec       = 0;
556         tm.tm_min       = 0;
557         tm.tm_hour      = 0;
558
559 #ifdef SVR4
560         next            = mktime(&tm);
561 #else
562         next            = timelocal(&tm);
563 #endif /* SVR4 */
564         next            = next + seconds(n, daysec);
565         next            = adjust_dst(t, next);
566         return(next);
567 }
568
569 extern Tick
570 nextday(Tick t)
571 {
572         Tick next;
573
574         next    = t +(int)daysec;
575         next    = adjust_dst(t, next);
576         return(next);
577 }
578
579 extern Tick
580 prevday(Tick t)
581 {
582         Tick prev;
583
584         prev    = t - (int)daysec;
585         prev    = adjust_dst(t, prev);
586         return(prev);
587 }
588
589 extern Tick
590 nextweek(Tick t)
591 {
592         Tick next;
593
594         next    = t + seconds(7, daysec);
595         next    = adjust_dst(t, next);
596         return(next);
597 }
598
599 extern Tick
600 prevweek(Tick t)
601 {
602         Tick prev;
603
604         prev    = t - seconds(7, daysec);
605         prev    = adjust_dst(t, prev);
606         return(prev);
607 }
608
609 extern Tick
610 next2weeks(Tick t)
611 {
612         Tick next;
613
614         next    = t + seconds(14, daysec);
615         next    = adjust_dst(t, next);
616         return(next);
617 }
618
619 extern Tick
620 prev2weeks(Tick t)
621 {
622         Tick prev;
623
624         prev    = t - seconds(14, daysec);
625         prev    = adjust_dst(t, prev);
626         return(prev);
627 }
628
629 /*              WORK OUT A BETTER WAY TO DO THIS!!      */
630 extern Tick
631 prevmonth_exactday(Tick t)
632 {
633         Tick prev; int day;
634         struct tm tm;
635         int sdelta;
636         _Xltimeparams localtime_buf;
637
638         tm = *_XLocaltime(&t, localtime_buf);
639         sdelta = tm.tm_hour * hrsec + tm.tm_min * minsec + tm.tm_sec; 
640         day = tm.tm_mday;
641         if((tm.tm_mday < 31 && tm.tm_mon != 0) ||       /* at least 30 days everywhere, except Feb.*/
642            (tm.tm_mday==31 && tm.tm_mon==6)    ||       /* two 31s -- Jul./Aug.         */
643            (tm.tm_mday==31 && tm.tm_mon==11)   ||       /* two 31s -- Dec./Jan.         */
644            (tm.tm_mon == 0 &&(tm.tm_mday < 29  ||(tm.tm_mday==29 && leapyr(tm.tm_year+1900))))) {       
645                 prev = t-monthseconds(previousmonth(t));
646                 prev = adjust_dst(t, prev);
647         }
648         else {  /* brute force */
649                 prev = previousmonth(previousmonth(t));         /* hop over the month */
650                 tm = *_XLocaltime(&prev, localtime_buf);
651                 tm.tm_mday = day;
652 #ifdef SVR4
653                 tm.tm_isdst = -1;
654                 prev =(mktime(&tm)) + sdelta;
655 #else
656                 prev =(timelocal(&tm)) + sdelta;
657 #endif /* SVR4 */
658
659         }
660         return(prev);
661 }
662
663 /*              WORK OUT A BETTER WAY TO DO THIS!!      */
664 extern Tick
665 nextmonth_exactday(Tick t)
666 {
667         Tick next; int day;
668         struct tm tm;
669         int sdelta;
670         _Xltimeparams localtime_buf;
671
672         tm = *_XLocaltime(&t, localtime_buf);
673         sdelta = tm.tm_hour * hrsec + tm.tm_min * minsec + tm.tm_sec; 
674         day = tm.tm_mday;
675         if((tm.tm_mday < 31 && tm.tm_mon != 0) ||       /* at least 30 days everywhere, except Feb.*/
676            (tm.tm_mday==31 && tm.tm_mon==6)    ||       /* two 31s -- Jul./Aug.         */
677            (tm.tm_mday==31 && tm.tm_mon==11)   ||       /* two 31s -- Dec./Jan.         */
678            (tm.tm_mon == 0 &&(tm.tm_mday < 29  ||(tm.tm_mday==29 && leapyr(tm.tm_year+1900))))) {       
679                 next = t+monthseconds(t);
680                 next = adjust_dst(t, next);
681         }
682         else {  /* brute force */
683                 next = next_nmonth(t, 2);               /* hop over the month */
684                 tm = *_XLocaltime(&next, localtime_buf);
685                 tm.tm_mday = day;
686 #ifdef SVR4
687                 tm.tm_isdst = -1;
688                 next = mktime(&tm) + sdelta;
689 #else
690                 next =(timelocal(&tm)) + sdelta;
691 #endif /* SVR4 */
692         }
693         return(next);
694 }
695
696 extern Tick
697 nextnyear(Tick t, int n)
698 {
699         struct tm tm;
700         _Xltimeparams localtime_buf;
701
702         tm      = *_XLocaltime(&t, localtime_buf);
703         tm.tm_year += n;
704 #ifdef SVR4
705         return(mktime(&tm));
706 #else
707         return(timelocal(&tm));
708 #endif /* SVR4 */
709 }
710
711 extern Tick
712 nextyear(Tick t)
713 {
714         return(nextnyear(t, 1));
715 }
716
717 extern Tick
718 prevnday_exacttime(Tick t, int n)
719 {
720         Tick prev;
721
722         prev    = t - seconds(n, daysec);
723         prev    = adjust_dst(t, prev);
724         return(prev);
725 }
726
727 extern Tick
728 prevnyear(Tick t, int n)
729 {
730         struct tm tm;
731         _Xltimeparams localtime_buf;
732
733         tm = *_XLocaltime(&t, localtime_buf);
734         tm.tm_year -= n;
735 #ifdef SVR4
736         return(mktime(&tm));
737 #else
738         return(timelocal(&tm));
739 #endif /* SVR4 */
740 }
741
742 extern Tick
743 prevyear(Tick t)
744 {
745         return(prevnyear(t, 1));
746 }
747
748 extern Tick
749 previousmonth(Tick t)
750 {
751         struct tm tm;
752         _Xltimeparams localtime_buf;
753
754         tm = *_XLocaltime(&t, localtime_buf);
755         tm.tm_hour=0;
756         tm.tm_min=0;
757         tm.tm_sec=0;
758         if(tm.tm_mon==0) {
759                 tm.tm_mon=11;
760                 tm.tm_mday=1;
761                 tm.tm_year--;
762         }
763         else {
764                 tm.tm_mday=1;
765                 tm.tm_mon--;
766         }
767 #ifdef SVR4
768         tm.tm_isdst = -1;
769         return(mktime(&tm));
770 #else
771         return(timelocal(&tm));
772 #endif /* SVR4 */
773 }
774
775 extern Tick
776 prev_nmonth(Tick t, int n)
777 {
778         struct tm tm;
779         int     n12;
780         _Xltimeparams localtime_buf;
781
782         n12 = n/12;
783         n = n%12;
784
785         tm = *_XLocaltime(&t, localtime_buf);
786         tm.tm_hour=0;
787         tm.tm_min=0;
788         tm.tm_sec=0;
789         tm.tm_mday=1;
790         if (n12 > 0)
791                 tm.tm_year -= n12;
792
793         if ((tm.tm_mon = tm.tm_mon - n) < 0) {
794                 tm.tm_mon += 12;
795                 tm.tm_year--;
796         }
797 #ifdef SVR4
798         tm.tm_isdst = -1;
799         return(mktime(&tm));
800 #else
801         return(timelocal(&tm));
802 #endif /* SVR4 */
803 }
804
805 extern Tick
806 jan1(Tick t)
807 {
808         struct tm tm;
809         _Xltimeparams localtime_buf;
810
811         tm              = *_XLocaltime(&t, localtime_buf);
812         tm.tm_mon       = 0;
813         tm.tm_mday      = 1;
814 #ifdef SVR4
815         tm.tm_isdst = -1;
816         return(mktime(&tm));
817 #else
818         return(timelocal(&tm));
819 #endif /* SVR4 */
820 }
821
822 extern Tick
823 nextjan1(Tick t)
824 {
825         struct tm tm;
826         _Xltimeparams localtime_buf;
827
828         tm              = *_XLocaltime(&t, localtime_buf);
829         tm.tm_mon       = 0;
830         tm.tm_mday      = 1;
831         tm.tm_year++;    
832 #ifdef SVR4
833         tm.tm_isdst = -1;
834         return(mktime(&tm));
835 #else
836         return(timelocal(&tm));
837 #endif /* SVR4 */
838 }
839
840 extern Tick
841 lastjan1(Tick t)
842 {
843         struct tm tm;
844         _Xltimeparams localtime_buf;
845
846         tm              = *_XLocaltime(&t, localtime_buf);
847         tm.tm_mon       = 0;
848         tm.tm_mday      = 1;
849         tm.tm_year--;    
850 #ifdef SVR4
851         tm.tm_isdst = -1;
852         return(mktime(&tm));
853 #else
854         return(timelocal(&tm));
855 #endif /* SVR4 */
856 }
857
858 extern Tick
859 lowerbound(Tick t)
860 {
861         struct tm tm;
862         _Xltimeparams localtime_buf;
863
864         tm              =  *_XLocaltime(&t, localtime_buf);
865         tm.tm_sec       =  0;
866         tm.tm_min       =  0;
867         tm.tm_hour      =  0;
868         tm.tm_isdst     = -1;
869 #ifdef SVR4
870         return(mktime(&tm));
871 #else
872         return(timelocal(&tm));
873 #endif /* SVR4 */
874 }
875 extern Tick
876 lower_bound(int i, Tick t)
877 {
878         struct tm tm;
879         _Xltimeparams localtime_buf;
880
881         tm              =  *_XLocaltime(&t, localtime_buf);
882         tm.tm_sec       =  0;
883         tm.tm_min       =  0;
884         tm.tm_hour      =  i;
885         tm.tm_isdst     = -1;
886 #ifdef SVR4
887         return(mktime(&tm));
888 #else
889         return (timelocal(&tm));
890 #endif /* SVR4 */
891 }
892 extern Tick
893 upperbound(Tick t)
894 {
895         struct tm tm;
896         _Xltimeparams localtime_buf;
897
898         tm              =  *_XLocaltime(&t, localtime_buf);
899         tm.tm_sec       =  59;
900         tm.tm_min       =  59;
901         tm.tm_hour      =  23;
902         tm.tm_isdst     = -1;
903 #ifdef SVR4
904         return(mktime(&tm)-1);
905 #else
906         return(timelocal(&tm)-1);
907 #endif /* SVR4 */
908 }
909
910 static int
911 leapsB4(int y)
912 {
913         return((y-1)/4 -(y-1)/100 +(y-1)/400);
914 }
915
916 extern Tick
917 xytoclock(int x, int y, Tick t)
918 {
919         int dd, mn, yr, ly, leaps;
920         char buf[10];
921         struct tm tm;
922         struct tm timestruct;
923         Tick tick;
924         _Xltimeparams localtime_buf;
925
926         memset(&timestruct, 0, sizeof(struct tm));
927
928         tm      = *_XLocaltime(&t, localtime_buf);
929         mn      = tm.tm_mon + 1;
930         yr      = tm.tm_year + 1900;
931         leaps   = leapsB4(yr);
932         ly      = leapyr(yr);
933
934         dd = 7*(y-1) + x - 
935          (yr+leaps+3055L*(mn+2)/100-84-(mn>2)*(2-ly))%7;
936
937         timestruct.tm_mon = tm.tm_mon;
938         timestruct.tm_mday = dd;
939         timestruct.tm_year = tm.tm_year;
940         timestruct.tm_sec = 0;
941         timestruct.tm_isdst = -1;
942
943         tick = mktime(&timestruct);
944         return(tick);
945 }
946
947 extern Tick
948 now()
949 {
950         return(time(0));
951 }
952
953 extern void
954 set_timezone(char *tzname)
955 {
956         static char tzenv[MAXPATHLEN];
957
958 #ifdef SVR4
959         /* I don't like using 'system', but this does the right
960          * thing according to tha man pages
961          */
962         if (tzname==NULL) system("unset TZ\n");
963 #else
964         if (tzname==NULL) tzsetwall();
965 #endif /* SVR4 */
966
967         else {
968                 sprintf(tzenv, "TZ=%s", tzname);
969                 putenv(tzenv);
970                 tzset();
971         }
972 }
973  
974 extern long
975 gmt_off()
976 {
977         struct tm tm;
978         Tick t;
979         static Tick gmt;
980  
981 #ifdef SVR4
982         extern long timezone;
983
984         gmt             = timezone;
985 #else
986         _Xltimeparams localtime_buf;
987
988         t       = now();
989         tm      = *_XLocaltime(&t, localtime_buf);
990         gmt = tm.tm_gmtoff;
991 #endif /* SVR4 */
992         return(gmt);
993 }
994
995
996 /* [ytso 1/26/93]
997  * cm now supports to up end of 1999.  This is due to the limitation
998  * of cm_getdate() which can only handle up to end of 1999.
999  * When cm_getdate() is improved to handle up to the system limit,
1000  * definitions of eot and EOT need to be changed as well as some
1001  * of the routines in this file and the caller of these routines.
1002  */
1003 extern void
1004 init_time()
1005 {
1006         struct tm tm, gm;
1007         Tick    t;
1008         _Xltimeparams localtime_buf;
1009         _Xgtimeparams gmtime_buf;
1010
1011 #ifdef SVR4
1012         /* Fix for QAR 31607 */
1013         tzset();
1014         if (getenv("TZ") == NULL){
1015                 char *tzptr;
1016                 tzptr = malloc(strlen(tzname[0]) + strlen(tzname[1]) + 10);
1017                 sprintf (tzptr,"TZ=%s%ld%s", tzname[0], timezone/3600, tzname[1]);
1018                 putenv(tzptr);
1019                 tzset();
1020         }
1021 #endif
1022
1023         t               = now();
1024         tm              = *_XLocaltime(&t, localtime_buf);
1025         gm              = *_XGmtime(&t, gmtime_buf);
1026
1027         bot             = mktime(&gm) - mktime(&tm);
1028
1029         tm.tm_sec       =59;
1030         tm.tm_min       =59;
1031         tm.tm_hour      =23;
1032         tm.tm_mday      =31;
1033         tm.tm_mon       =11;
1034         tm.tm_year      =137;                   /* Dec. 31, 2037 */
1035         tm.tm_isdst = -1;
1036         eot             =mktime(&tm);
1037 }
1038
1039 extern int
1040 seconds_to_hours(int n)
1041 {
1042         return(n/(int)hrsec);
1043 }
1044
1045 extern int
1046 hours_to_seconds(int n)
1047 {
1048         return(n *(int)hrsec);
1049 }
1050
1051 extern int
1052 seconds_to_minutes(int n)
1053 {
1054         return(n/60);
1055 }
1056
1057 extern int
1058 minutes_to_seconds(int n)
1059 {
1060         return(n *(int)minsec);
1061 }
1062
1063
1064 extern int
1065 days_to_seconds(int n)
1066 {
1067         return(n *(int)daysec);
1068 }
1069
1070 seconds_to_days(int n)
1071 {
1072         return(n/(int)daysec);
1073 }
1074
1075 /*
1076 extern int
1077 weeks_to_seconds(int n)
1078 {
1079         return(n *(int)wksec);
1080 }
1081
1082 extern int
1083 seconds_to_weeks(int)
1084 {
1085         return(n/(int)wksec);
1086 }
1087 */
1088
1089 extern Tick
1090 monthdayyear(int m, int d, int y)
1091 {
1092         int t, t1;
1093         char buf[10];
1094
1095         struct tm timestruct;
1096
1097         memset(&timestruct, 0, sizeof(struct tm));
1098         timestruct.tm_mon = m - 1;
1099         timestruct.tm_mday = d;
1100         timestruct.tm_year = y - 1900;
1101         timestruct.tm_sec = 0;
1102         timestruct.tm_isdst = -1;
1103
1104         t = mktime(&timestruct);
1105 /*
1106         sprintf(buf, "%d/%d/%d", m, d, y);
1107         t = cm_getdate(buf, NULL);
1108
1109 printf("monthdayyear, m= %d, d = %d, y = %d, t1 = %d, t = %d\n", m, d, y, t1, t);
1110         
1111 */
1112         return(t);
1113 }