Convert uses of XKeycodeToKeysym (deprecated) to XkbKeycodeToKeysym
[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(void)
151 {
152         return bot;
153 }
154
155 /* Return end of time */
156 extern Tick
157 get_eot(void)
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(Tick t)
259 {
260         struct tm *tm;
261         _Xltimeparams localtime_buf;
262
263         tm = _XLocaltime(&t, localtime_buf);
264         return(tm->tm_mon+1);
265 }
266
267 extern int
268 hour(Tick t)
269 {
270         struct tm *tm;
271         _Xltimeparams localtime_buf;
272
273         tm = _XLocaltime(&t, localtime_buf);
274         return(tm->tm_hour);
275 }
276
277 extern int
278 minute(Tick t)
279 {
280         struct tm *tm;
281         _Xltimeparams localtime_buf;
282
283         tm = _XLocaltime(&t, localtime_buf);
284         return(tm->tm_min);
285 }
286
287 extern int
288 leapyr(int y)
289 {
290         return
291          (y % 4 == 0 && y % 100 !=0 || y % 400 == 0);
292 }
293
294 extern int
295 monthlength(Tick t)
296 {
297         int mon;
298         struct tm tm;
299         _Xltimeparams localtime_buf;
300
301         tm = *_XLocaltime(&t, localtime_buf);
302         mon = tm.tm_mon;
303         return(((mon==1) && leapyr(tm.tm_year+1900))? 29 : monthdays[mon]);
304 }
305
306 extern int
307 monthseconds(Tick t)
308 {
309         int mon;
310         struct tm tm;
311         _Xltimeparams localtime_buf;
312         
313         tm = *_XLocaltime(&t, localtime_buf);
314         mon = tm.tm_mon;
315         return(((mon==1) && leapyr(tm.tm_year+1900))? 29*daysec : monthsecs[mon]);
316 }
317
318 extern int
319 dom(Tick t)
320 {
321         struct tm *tm;
322         _Xltimeparams localtime_buf;
323
324         tm = _XLocaltime(&t, localtime_buf);
325         return(tm->tm_mday);
326 }
327
328 extern int
329 wom(Tick t)
330 {
331         struct tm *tm;
332         _Xltimeparams localtime_buf;
333
334         tm = _XLocaltime(&t, localtime_buf);
335         return((12 + tm->tm_mday - tm->tm_wday)/7);
336 }
337
338 /*
339  * If the result falls beyond the system limit, -1 is returned by mktime().
340  */
341 Tick
342 next_nmonth(Tick t, int n)
343 {
344         struct tm tm;
345         int     n12;
346         _Xltimeparams localtime_buf;
347
348         n12 = n/12;
349         n = n%12;
350
351         tm = *_XLocaltime(&t, localtime_buf);
352         tm.tm_hour=0;
353         tm.tm_min=0;
354         tm.tm_sec=0;
355         tm.tm_mday=1;
356         if (n12 > 0)
357                 tm.tm_year += n12;
358
359         if ((tm.tm_mon = tm.tm_mon + n) > 11) {
360                 tm.tm_mon -= 12;
361                 tm.tm_year++;
362         }
363
364         tm.tm_isdst = -1;
365         return(mktime(&tm));
366 }
367
368 extern Tick
369 nextmonth(Tick t)
370 {
371         return(next_nmonth(t, 1));
372 }
373
374 extern boolean_t
375 weekofmonth(Tick t, int *wk)
376 {
377         struct tm tm, tm1, tm2;
378         Tick    firstday;
379         _Xltimeparams localtime_buf;
380
381         tm = *_XLocaltime(&t, localtime_buf);
382         tm.tm_hour = 0;
383         tm.tm_min = 0;
384         tm.tm_sec = 0;
385         tm.tm_mday = 1;
386         firstday = mktime(&tm);
387         tm = *_XLocaltime(&firstday, localtime_buf);
388
389         /* need to get it again since data in tm is changed */
390         tm1 = *_XLocaltime(&t, localtime_buf);
391
392         *wk = wom(t);
393         if (tm1.tm_wday < tm.tm_wday)
394                 (*wk)--;
395
396         if (*wk < 4)
397                 return B_FALSE;
398         else {
399                 t += seconds(7, daysec);
400                 tm2 = *_XLocaltime(&t, localtime_buf);
401
402                 return((tm1.tm_mon == tm2.tm_mon) ? B_FALSE : B_TRUE);
403         }
404 }
405
406 extern int
407 dow(Tick t)
408 {
409         struct tm tm;
410         _Xltimeparams localtime_buf;
411
412         tm = *_XLocaltime(&t, localtime_buf);
413         return(tm.tm_wday);
414 }
415
416 extern int /* find dow(0-6) that 1st dom falls on */
417 fdom(Tick t)
418 {
419         struct tm tm;
420         _Xltimeparams localtime_buf;
421
422         tm              = *_XLocaltime(&t, localtime_buf);
423         tm.tm_mday      = 1;
424         tm.tm_isdst     = -1;
425         t               = mktime(&tm);
426         tm              = *_XLocaltime(&t, localtime_buf);
427         return(tm.tm_wday);
428 }
429
430 extern int
431 ldom(Tick t /* find dow(0-6) that last dom falls on */ )
432 {
433         struct tm tm;
434         _Xltimeparams localtime_buf;
435
436         tm              = *_XLocaltime(&t, localtime_buf);
437         tm.tm_mday      = monthlength(t);
438         tm.tm_isdst     = -1;
439         t               = mktime(&tm);
440         tm              = *_XLocaltime(&t, localtime_buf);
441         return(tm.tm_wday);
442 }
443
444 /* returns tick of last day of month */
445 extern Tick
446 last_dom(Tick tick)
447 {
448         return(upperbound(next_ndays(tick, monthlength(tick) - dom(tick))));
449 }
450
451 /* returns tick of first day of month */
452 extern Tick
453 first_dom(Tick tick)
454 {
455         return(lowerbound(last_ndays(tick, dom(tick)-1)));
456 }
457
458 /* returns tick of first day of week */
459 extern Tick
460 first_dow(Tick tick)
461 {
462         int d;
463
464         if ((d = dow(tick)) == 0)
465                 d = 6;
466         else 
467                 d--;
468
469         return(lowerbound(last_ndays(tick, d)));
470 }
471
472 /* returns tick of first day of week */
473 extern Tick
474 last_dow(Tick tick)
475 {
476         int d;
477
478         if ((d = dow(tick)) == 0)
479                 d = 6;
480         else 
481                 d--;
482         d = 6 - d;
483
484         return(upperbound(next_ndays(tick, d)));
485 }
486 /* returns number of weeks in month */
487 extern int
488 numwks(Tick tick)
489 {
490         return (wom(last_dom(tick)));
491 }
492
493 extern int
494 adjust_dst(Tick start, Tick next) 
495 {
496         DSTchange change;
497         change = dst_changed(start, next);
498         switch(change) {
499                 case nochange:
500                 break;
501                 case dstoff:
502                         next+=(int) hrsec;
503                 break;
504                 case dston:
505                         next-=(int) hrsec;
506                 break;
507         }
508         return(next);
509 }
510
511 extern Tick
512 next_nhours(Tick t, int n)
513 {
514         Tick next;
515         struct tm tm;
516         _Xltimeparams localtime_buf;
517
518         tm              = *_XLocaltime(&t, localtime_buf);
519         tm.tm_sec       = 0;
520         tm.tm_min       = 0;
521  
522         next            = mktime(&tm);
523         next            = next + seconds(n, hrsec);
524         next            = adjust_dst(t, next);
525         return(next);
526 }
527
528 extern Tick
529 last_ndays(Tick t, int n)
530 {
531         Tick last;
532         struct tm tm;
533         _Xltimeparams localtime_buf;
534
535         tm              = *_XLocaltime(&t, localtime_buf);
536         tm.tm_sec       = 0;
537         tm.tm_min       = 0;
538         tm.tm_hour      = 0;
539
540         last            = mktime(&tm);
541         last            = last - seconds(n, daysec);
542         last            = adjust_dst(t, last);
543         return(last);
544 }
545
546 extern Tick
547 next_ndays(Tick t, int n)
548 {
549         Tick next;
550         struct tm tm;
551         _Xltimeparams localtime_buf;
552
553         tm              = *_XLocaltime(&t, localtime_buf);
554         tm.tm_sec       = 0;
555         tm.tm_min       = 0;
556         tm.tm_hour      = 0;
557
558 #ifdef SVR4
559         next            = mktime(&tm);
560 #else
561         next            = timelocal(&tm);
562 #endif /* SVR4 */
563         next            = next + seconds(n, daysec);
564         next            = adjust_dst(t, next);
565         return(next);
566 }
567
568 extern Tick
569 nextday(Tick t)
570 {
571         Tick next;
572
573         next    = t +(int)daysec;
574         next    = adjust_dst(t, next);
575         return(next);
576 }
577
578 extern Tick
579 prevday(Tick t)
580 {
581         Tick prev;
582
583         prev    = t - (int)daysec;
584         prev    = adjust_dst(t, prev);
585         return(prev);
586 }
587
588 extern Tick
589 nextweek(Tick t)
590 {
591         Tick next;
592
593         next    = t + seconds(7, daysec);
594         next    = adjust_dst(t, next);
595         return(next);
596 }
597
598 extern Tick
599 prevweek(Tick t)
600 {
601         Tick prev;
602
603         prev    = t - seconds(7, daysec);
604         prev    = adjust_dst(t, prev);
605         return(prev);
606 }
607
608 extern Tick
609 next2weeks(Tick t)
610 {
611         Tick next;
612
613         next    = t + seconds(14, daysec);
614         next    = adjust_dst(t, next);
615         return(next);
616 }
617
618 extern Tick
619 prev2weeks(Tick t)
620 {
621         Tick prev;
622
623         prev    = t - seconds(14, daysec);
624         prev    = adjust_dst(t, prev);
625         return(prev);
626 }
627
628 /*              WORK OUT A BETTER WAY TO DO THIS!!      */
629 extern Tick
630 prevmonth_exactday(Tick t)
631 {
632         Tick prev; int day;
633         struct tm tm;
634         int sdelta;
635         _Xltimeparams localtime_buf;
636
637         tm = *_XLocaltime(&t, localtime_buf);
638         sdelta = tm.tm_hour * hrsec + tm.tm_min * minsec + tm.tm_sec; 
639         day = tm.tm_mday;
640         if((tm.tm_mday < 31 && tm.tm_mon != 0) ||       /* at least 30 days everywhere, except Feb.*/
641            (tm.tm_mday==31 && tm.tm_mon==6)    ||       /* two 31s -- Jul./Aug.         */
642            (tm.tm_mday==31 && tm.tm_mon==11)   ||       /* two 31s -- Dec./Jan.         */
643            (tm.tm_mon == 0 &&(tm.tm_mday < 29  ||(tm.tm_mday==29 && leapyr(tm.tm_year+1900))))) {       
644                 prev = t-monthseconds(previousmonth(t));
645                 prev = adjust_dst(t, prev);
646         }
647         else {  /* brute force */
648                 prev = previousmonth(previousmonth(t));         /* hop over the month */
649                 tm = *_XLocaltime(&prev, localtime_buf);
650                 tm.tm_mday = day;
651 #ifdef SVR4
652                 tm.tm_isdst = -1;
653                 prev =(mktime(&tm)) + sdelta;
654 #else
655                 prev =(timelocal(&tm)) + sdelta;
656 #endif /* SVR4 */
657
658         }
659         return(prev);
660 }
661
662 /*              WORK OUT A BETTER WAY TO DO THIS!!      */
663 extern Tick
664 nextmonth_exactday(Tick t)
665 {
666         Tick next; int day;
667         struct tm tm;
668         int sdelta;
669         _Xltimeparams localtime_buf;
670
671         tm = *_XLocaltime(&t, localtime_buf);
672         sdelta = tm.tm_hour * hrsec + tm.tm_min * minsec + tm.tm_sec; 
673         day = tm.tm_mday;
674         if((tm.tm_mday < 31 && tm.tm_mon != 0) ||       /* at least 30 days everywhere, except Feb.*/
675            (tm.tm_mday==31 && tm.tm_mon==6)    ||       /* two 31s -- Jul./Aug.         */
676            (tm.tm_mday==31 && tm.tm_mon==11)   ||       /* two 31s -- Dec./Jan.         */
677            (tm.tm_mon == 0 &&(tm.tm_mday < 29  ||(tm.tm_mday==29 && leapyr(tm.tm_year+1900))))) {       
678                 next = t+monthseconds(t);
679                 next = adjust_dst(t, next);
680         }
681         else {  /* brute force */
682                 next = next_nmonth(t, 2);               /* hop over the month */
683                 tm = *_XLocaltime(&next, localtime_buf);
684                 tm.tm_mday = day;
685 #ifdef SVR4
686                 tm.tm_isdst = -1;
687                 next = mktime(&tm) + sdelta;
688 #else
689                 next =(timelocal(&tm)) + sdelta;
690 #endif /* SVR4 */
691         }
692         return(next);
693 }
694
695 extern Tick
696 nextnyear(Tick t, int n)
697 {
698         struct tm tm;
699         _Xltimeparams localtime_buf;
700
701         tm      = *_XLocaltime(&t, localtime_buf);
702         tm.tm_year += n;
703 #ifdef SVR4
704         return(mktime(&tm));
705 #else
706         return(timelocal(&tm));
707 #endif /* SVR4 */
708 }
709
710 extern Tick
711 nextyear(Tick t)
712 {
713         return(nextnyear(t, 1));
714 }
715
716 extern Tick
717 prevnday_exacttime(Tick t, int n)
718 {
719         Tick prev;
720
721         prev    = t - seconds(n, daysec);
722         prev    = adjust_dst(t, prev);
723         return(prev);
724 }
725
726 extern Tick
727 prevnyear(Tick t, int n)
728 {
729         struct tm tm;
730         _Xltimeparams localtime_buf;
731
732         tm = *_XLocaltime(&t, localtime_buf);
733         tm.tm_year -= n;
734 #ifdef SVR4
735         return(mktime(&tm));
736 #else
737         return(timelocal(&tm));
738 #endif /* SVR4 */
739 }
740
741 extern Tick
742 prevyear(Tick t)
743 {
744         return(prevnyear(t, 1));
745 }
746
747 extern Tick
748 previousmonth(Tick t)
749 {
750         struct tm tm;
751         _Xltimeparams localtime_buf;
752
753         tm = *_XLocaltime(&t, localtime_buf);
754         tm.tm_hour=0;
755         tm.tm_min=0;
756         tm.tm_sec=0;
757         if(tm.tm_mon==0) {
758                 tm.tm_mon=11;
759                 tm.tm_mday=1;
760                 tm.tm_year--;
761         }
762         else {
763                 tm.tm_mday=1;
764                 tm.tm_mon--;
765         }
766 #ifdef SVR4
767         tm.tm_isdst = -1;
768         return(mktime(&tm));
769 #else
770         return(timelocal(&tm));
771 #endif /* SVR4 */
772 }
773
774 extern Tick
775 prev_nmonth(Tick t, int n)
776 {
777         struct tm tm;
778         int     n12;
779         _Xltimeparams localtime_buf;
780
781         n12 = n/12;
782         n = n%12;
783
784         tm = *_XLocaltime(&t, localtime_buf);
785         tm.tm_hour=0;
786         tm.tm_min=0;
787         tm.tm_sec=0;
788         tm.tm_mday=1;
789         if (n12 > 0)
790                 tm.tm_year -= n12;
791
792         if ((tm.tm_mon = tm.tm_mon - n) < 0) {
793                 tm.tm_mon += 12;
794                 tm.tm_year--;
795         }
796 #ifdef SVR4
797         tm.tm_isdst = -1;
798         return(mktime(&tm));
799 #else
800         return(timelocal(&tm));
801 #endif /* SVR4 */
802 }
803
804 extern Tick
805 jan1(Tick t)
806 {
807         struct tm tm;
808         _Xltimeparams localtime_buf;
809
810         tm              = *_XLocaltime(&t, localtime_buf);
811         tm.tm_mon       = 0;
812         tm.tm_mday      = 1;
813 #ifdef SVR4
814         tm.tm_isdst = -1;
815         return(mktime(&tm));
816 #else
817         return(timelocal(&tm));
818 #endif /* SVR4 */
819 }
820
821 extern Tick
822 nextjan1(Tick t)
823 {
824         struct tm tm;
825         _Xltimeparams localtime_buf;
826
827         tm              = *_XLocaltime(&t, localtime_buf);
828         tm.tm_mon       = 0;
829         tm.tm_mday      = 1;
830         tm.tm_year++;    
831 #ifdef SVR4
832         tm.tm_isdst = -1;
833         return(mktime(&tm));
834 #else
835         return(timelocal(&tm));
836 #endif /* SVR4 */
837 }
838
839 extern Tick
840 lastjan1(Tick t)
841 {
842         struct tm tm;
843         _Xltimeparams localtime_buf;
844
845         tm              = *_XLocaltime(&t, localtime_buf);
846         tm.tm_mon       = 0;
847         tm.tm_mday      = 1;
848         tm.tm_year--;    
849 #ifdef SVR4
850         tm.tm_isdst = -1;
851         return(mktime(&tm));
852 #else
853         return(timelocal(&tm));
854 #endif /* SVR4 */
855 }
856
857 extern Tick
858 lowerbound(Tick t)
859 {
860         struct tm tm;
861         _Xltimeparams localtime_buf;
862
863         tm              =  *_XLocaltime(&t, localtime_buf);
864         tm.tm_sec       =  0;
865         tm.tm_min       =  0;
866         tm.tm_hour      =  0;
867         tm.tm_isdst     = -1;
868 #ifdef SVR4
869         return(mktime(&tm));
870 #else
871         return(timelocal(&tm));
872 #endif /* SVR4 */
873 }
874 extern Tick
875 lower_bound(int i, Tick t)
876 {
877         struct tm tm;
878         _Xltimeparams localtime_buf;
879
880         tm              =  *_XLocaltime(&t, localtime_buf);
881         tm.tm_sec       =  0;
882         tm.tm_min       =  0;
883         tm.tm_hour      =  i;
884         tm.tm_isdst     = -1;
885 #ifdef SVR4
886         return(mktime(&tm));
887 #else
888         return (timelocal(&tm));
889 #endif /* SVR4 */
890 }
891 extern Tick
892 upperbound(Tick t)
893 {
894         struct tm tm;
895         _Xltimeparams localtime_buf;
896
897         tm              =  *_XLocaltime(&t, localtime_buf);
898         tm.tm_sec       =  59;
899         tm.tm_min       =  59;
900         tm.tm_hour      =  23;
901         tm.tm_isdst     = -1;
902 #ifdef SVR4
903         return(mktime(&tm)-1);
904 #else
905         return(timelocal(&tm)-1);
906 #endif /* SVR4 */
907 }
908
909 static int
910 leapsB4(int y)
911 {
912         return((y-1)/4 -(y-1)/100 +(y-1)/400);
913 }
914
915 extern Tick
916 xytoclock(int x, int y, Tick t)
917 {
918         int dd, mn, yr, ly, leaps;
919         char buf[10];
920         struct tm tm;
921         struct tm timestruct;
922         Tick tick;
923         _Xltimeparams localtime_buf;
924
925         memset(&timestruct, 0, sizeof(struct tm));
926
927         tm      = *_XLocaltime(&t, localtime_buf);
928         mn      = tm.tm_mon + 1;
929         yr      = tm.tm_year + 1900;
930         leaps   = leapsB4(yr);
931         ly      = leapyr(yr);
932
933         dd = 7*(y-1) + x - 
934          (yr+leaps+3055L*(mn+2)/100-84-(mn>2)*(2-ly))%7;
935
936         timestruct.tm_mon = tm.tm_mon;
937         timestruct.tm_mday = dd;
938         timestruct.tm_year = tm.tm_year;
939         timestruct.tm_sec = 0;
940         timestruct.tm_isdst = -1;
941
942         tick = mktime(&timestruct);
943         return(tick);
944 }
945
946 extern Tick
947 now(void)
948 {
949         return(time(0));
950 }
951
952 extern void
953 set_timezone(char *tzname)
954 {
955         static char tzenv[MAXPATHLEN];
956
957 #ifdef SVR4
958         /* I don't like using 'system', but this does the right
959          * thing according to tha man pages
960          */
961         if (tzname==NULL) system("unset TZ\n");
962 #else
963         if (tzname==NULL) tzsetwall();
964 #endif /* SVR4 */
965
966         else {
967                 sprintf(tzenv, "TZ=%s", tzname);
968                 putenv(tzenv);
969                 tzset();
970         }
971 }
972  
973 extern long
974 gmt_off(void)
975 {
976         struct tm tm;
977         Tick t;
978         static Tick gmt;
979  
980 #ifdef SVR4
981         extern long timezone;
982
983         gmt             = timezone;
984 #else
985         _Xltimeparams localtime_buf;
986
987         t       = now();
988         tm      = *_XLocaltime(&t, localtime_buf);
989         gmt = tm.tm_gmtoff;
990 #endif /* SVR4 */
991         return(gmt);
992 }
993
994
995 /* [ytso 1/26/93]
996  * cm now supports to up end of 1999.  This is due to the limitation
997  * of cm_getdate() which can only handle up to end of 1999.
998  * When cm_getdate() is improved to handle up to the system limit,
999  * definitions of eot and EOT need to be changed as well as some
1000  * of the routines in this file and the caller of these routines.
1001  */
1002 extern void
1003 init_time(void)
1004 {
1005         struct tm tm, gm;
1006         Tick    t;
1007         _Xltimeparams localtime_buf;
1008         _Xgtimeparams gmtime_buf;
1009
1010 #ifdef SVR4
1011         /* Fix for QAR 31607 */
1012         tzset();
1013         if (getenv("TZ") == NULL){
1014                 char *tzptr;
1015                 tzptr = malloc(strlen(tzname[0]) + strlen(tzname[1]) + 10);
1016                 sprintf (tzptr,"TZ=%s%ld%s", tzname[0], timezone/3600, tzname[1]);
1017                 putenv(tzptr);
1018                 tzset();
1019         }
1020 #endif
1021
1022         t               = now();
1023         tm              = *_XLocaltime(&t, localtime_buf);
1024         gm              = *_XGmtime(&t, gmtime_buf);
1025
1026         bot             = mktime(&gm) - mktime(&tm);
1027
1028         tm.tm_sec       =59;
1029         tm.tm_min       =59;
1030         tm.tm_hour      =23;
1031         tm.tm_mday      =31;
1032         tm.tm_mon       =11;
1033         tm.tm_year      =137;                   /* Dec. 31, 2037 */
1034         tm.tm_isdst = -1;
1035         eot             =mktime(&tm);
1036 }
1037
1038 extern int
1039 seconds_to_hours(int n)
1040 {
1041         return(n/(int)hrsec);
1042 }
1043
1044 extern int
1045 hours_to_seconds(int n)
1046 {
1047         return(n *(int)hrsec);
1048 }
1049
1050 extern int
1051 seconds_to_minutes(int n)
1052 {
1053         return(n/60);
1054 }
1055
1056 extern int
1057 minutes_to_seconds(int n)
1058 {
1059         return(n *(int)minsec);
1060 }
1061
1062
1063 extern int
1064 days_to_seconds(int n)
1065 {
1066         return(n *(int)daysec);
1067 }
1068
1069 seconds_to_days(int n)
1070 {
1071         return(n/(int)daysec);
1072 }
1073
1074 /*
1075 extern int
1076 weeks_to_seconds(int n)
1077 {
1078         return(n *(int)wksec);
1079 }
1080
1081 extern int
1082 seconds_to_weeks(int)
1083 {
1084         return(n/(int)wksec);
1085 }
1086 */
1087
1088 extern Tick
1089 monthdayyear(int m, int d, int y)
1090 {
1091         int t, t1;
1092         char buf[10];
1093
1094         struct tm timestruct;
1095
1096         memset(&timestruct, 0, sizeof(struct tm));
1097         timestruct.tm_mon = m - 1;
1098         timestruct.tm_mday = d;
1099         timestruct.tm_year = y - 1900;
1100         timestruct.tm_sec = 0;
1101         timestruct.tm_isdst = -1;
1102
1103         t = mktime(&timestruct);
1104 /*
1105         sprintf(buf, "%d/%d/%d", m, d, y);
1106         t = cm_getdate(buf, NULL);
1107
1108 printf("monthdayyear, m= %d, d = %d, y = %d, t1 = %d, t = %d\n", m, d, y, t1, t);
1109         
1110 */
1111         return(t);
1112 }