|
|
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.