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