|
|
1.1 root 1: /*
2: * MAKETIME derive 32-bit time value from TM structure.
3: *
4: * Usage:
5: * long t,maketime();
6: * struct tm *tp; Pointer to TM structure from <time.h>
7: * NOTE: this must be extended version!!!
8: * t = maketime(tp);
9: *
10: * Returns:
11: * 0 if failure; parameter out of range or nonsensical.
12: * else long time-value.
13: * Notes:
14: * This code is quasi-public; it may be used freely in like software.
15: * It is not to be sold, nor used in licensed software without
16: * permission of the author.
17: * For everyone's benefit, please report bugs and improvements!
18: * Copyright 1981 by Ken Harrenstien, SRI International.
19: * (ARPANET: KLH @ SRI)
20: */
21:
22: static char rcsid[]= "$Id: maketime.c,v 4.1 89/08/31 15:30:22 jtkohl Exp $";
23:
24: /* $Log: maketime.c,v $
25: * Revision 4.1 89/08/31 15:30:22 jtkohl
26: * Programmer: Kevin Fall
27: * Auditor: John Kohl
28: * changes: use gettimeofday() for timezone info.
29: * [really should use TZ environ variable on BSD43...]
30: *
31: * Revision 4.0 89/01/23 09:45:59 jtkohl
32: * No change, incrementing vno to 4.x
33: *
34: * Revision 1.1 88/12/20 17:38:52 wesommer
35: * Initial revision
36: *
37: * Revision 1.1 82/05/06 11:38:00 wft
38: * Initial revision
39: *
40: */
41:
42:
43: #include "time.h"
44:
45: int daytb[] = { /* # days in year thus far, indexed by month (0-12!!) */
46: 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
47: };
48:
49: struct tm *localtime();
50:
51: long maketime(atm)
52: struct tm *atm;
53: { register struct tm *tp;
54: register int i;
55: int year, yday, mon, day, hour, min, sec, zone, dst, leap;
56: long tres, curtim, time();
57:
58: (void) time(&curtim);
59: tp = localtime(&curtim); /* Get breakdowns of current time */
60: year = tp->tm_year; /* Use to set up defaults */
61: mon = tp->tm_mon;
62: day = tp->tm_mday;
63:
64:
65: #ifdef DEBUG
66: printf("first YMD: %d %d %d, T=%ld\n",year,mon,day,tres);
67: #endif DEBUG
68: tp = atm;
69:
70: /* First must find date, using specified year, month, day.
71: * If one of these is unspecified, it defaults either to the
72: * current date (if no more global spec was given) or to the
73: * zero-value for that spec (i.e. a more global spec was seen).
74: * Start with year... note 32 bits can only handle 135 years.
75: */
76: if(tp->tm_year != TMNULL)
77: { if((year = tp->tm_year) >= 1900) /* Allow full yr # */
78: year -= 1900; /* by making kosher */
79: mon = 0; /* Since year was given, default */
80: day = 1; /* for remaining specs is zero */
81: }
82: if(year < 70 || 70+134 < year ) /* Check range */
83: return(0); /* ERR: year out of range */
84: /* See if leap year */
85: leap = year&03 ? 0 : ((year+1900) % 100) ? 1 : ((year+1900) % 400) ? 0 : 1;
86: year -= 70; /* UNIX time starts at 1970 */
87:
88: /*
89: * Find day of year.
90: * YDAY is used only if it exists and either the month or day-of-month
91: * is missing.
92: */
93: if (tp->tm_yday != TMNULL
94: && (tp->tm_mon == TMNULL || tp->tm_mday == TMNULL))
95: yday = tp->tm_yday;
96: else
97: { if(tp->tm_mon != TMNULL)
98: { mon = tp->tm_mon; /* Month was specified */
99: day = 1; /* so set remaining default */
100: }
101: if(mon < 0 || 11 < mon) return(0); /* ERR: bad month */
102: if(tp->tm_mday != TMNULL) day = tp->tm_mday;
103: if(day < 1
104: || (((daytb[mon+1]-daytb[mon]) < day)
105: && (day!=29 || mon!=1 || !leap) ))
106: return(0); /* ERR: bad day */
107: yday = daytb[mon] /* Add # of days in months so far */
108: + ((leap /* Leap year, and past Feb? If */
109: && mon>1)? 1:0) /* so, add leap day for this year */
110: + day-1; /* And finally add # days this mon */
111:
112: if (tp->tm_yday != TMNULL /* Confirm that YDAY correct */
113: && tp->tm_yday != yday) return(0); /* ERR: conflict */
114: }
115: if(yday < 0 || (leap?366:365) <= yday)
116: return(0); /* ERR: bad YDAY or maketime bug */
117:
118: tres = year*365 /* Get # days of years so far */
119: + ((year+1)>>2) /* plus # of leap days since 1970 */
120: + yday; /* and finally add # days this year */
121:
122: if((i = tp->tm_wday) != TMNULL) /* Check WDAY if present */
123: if(i < 0 || 6 < i /* Ensure within range */
124: || i != (tres+4)%7) /* Matches? Jan 1,1970 was Thu = 4 */
125: return(0); /* ERR: bad WDAY */
126:
127: #ifdef DEBUG
128: printf("YMD: %d %d %d, T=%ld\n",year,mon,day,tres);
129: #endif DEBUG
130: /*
131: * Now determine time. If not given, default to zeros
132: * (since time is always the least global spec)
133: */
134: tres *= 86400L; /* Get # seconds (24*60*60) */
135: hour = min = sec = 0;
136: if(tp->tm_hour != TMNULL) hour = tp->tm_hour;
137: if(tp->tm_min != TMNULL) min = tp->tm_min;
138: if(tp->tm_sec != TMNULL) sec = tp->tm_sec;
139: if( min < 0 || 60 <= min
140: || sec < 0 || 60 <= sec) return(0); /* ERR: MS out of range */
141: if(hour < 0 || 24 <= hour)
142: if(hour != 24 || (min+sec) !=0) /* Allow 24:00 */
143: return(0); /* ERR: H out of range */
144:
145: /* confirm AM/PM if there */
146: switch(tp->tm_ampm)
147: { case 0: case TMNULL: /* Ignore these values */
148: break;
149: case 1: /* AM */
150: case 2: /* PM */
151: if(hour > 12) return(0); /* ERR: hrs 13-23 bad */
152: if(hour ==12) hour = 0; /* Modulo 12 */
153: if(tp->tm_ampm == 2) /* If PM, then */
154: hour += 12; /* get 24-hour time */
155: break;
156: default: return(0); /* ERR: illegal TM_AMPM value */
157: }
158:
159: tres += sec + 60L*(min + 60L*hour); /* Add in # secs of time */
160:
161: #ifdef DEBUG
162: printf("HMS: %d %d %d T=%ld\n",hour,min,sec,tres);
163: #endif DEBUG
164: /*
165: * We now have the GMT date/time and must make final
166: * adjustment for the specified time zone. If none is specified,
167: * the local time-zone is assumed.
168: */
169: if((zone = tp->tm_zon) == TMNULL /* If unspecified */
170: || (zone == 1)) /* or local-zone requested */
171: zone = localzone(); /* then set to local zone */
172: if(zone < 0 || 24*60 <= zone)
173: return(0); /* ERR: zone out of range */
174:
175: /* See if must apply Daylight Saving Time shift.
176: * Note that if DST is specified, validity is not checked.
177: */
178: if((dst = tp->tm_isdst) == TMNULL) /* Must we figure it out? */
179: { curtim = tres +localzone()*60L; /* Yuck. Get equiv local */
180: dst = localtime(&curtim)->tm_isdst; /* time, and ask. */
181: }
182: tres += zone*60L -(dst?3600:0); /* Add in # seconds of zone adj */
183:
184: return(tres);
185: }
186:
187:
188: /* LOCALZONE return local timezone in # mins west of GMT
189: *
190: */
191:
192: #include <sys/param.h>
193: #if BSD >= 42
194: #define KERNEL /* hack to not get /usr/include/time.h */
195: #include <sys/time.h>
196: #undef KERNEL
197: #else
198: #ifdef V6
199: extern timezone;
200: #else /* V7 */
201: #include <sys/types.h>
202: #include <sys/timeb.h>
203: #endif V6/7
204: #endif
205:
206: int _lclzon = -1;
207: localzone()
208: {
209: #if BSD >= 42
210: struct timezone tz;
211: if (gettimeofday((struct timeval *) 0, &tz) < 0)
212: return (-1);
213: _lclzon = tz.tz_minuteswest;
214: return (_lclzon);
215: #else
216: #ifdef V6
217: return(_lclzon >= 0 ? _lclzon : (_lclzon = timezone/60));
218: #else /* V7 */
219: struct timeb tb;
220:
221: if(_lclzon < 0)
222: { ftime(&tb);
223: _lclzon = tb.timezone;
224: }
225: return(_lclzon);
226:
227: #endif V6/7
228: #endif
229: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.