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: 
  23: static char rcsid[]= "$Id: maketime.c,v 1.1 82/05/06 11:38:00 wft Exp $";
  24: 
  25: /* $Log:	maketime.c,v $
  26:  * Revision 1.1  82/05/06  11:38:00  wft
  27:  * Initial revision
  28:  *
  29:  */
  30: 
  31: 
  32: #include "time.h"
  33: 
  34: int daytb[] = {   /* # days in year thus far, indexed by month (0-12!!) */
  35:     0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
  36: };
  37: 
  38: struct tm *localtime();
  39: 
  40: long maketime(atm)
  41: struct tm *atm;
  42: {   register struct tm *tp;
  43:     register int i;
  44:     int year, yday, mon, day, hour, min, sec, zone, dst, leap;
  45:     long tres, curtim;
  46: 
  47:     time(&curtim);
  48:     tp = localtime(&curtim);        /* Get breakdowns of current time */
  49:     year = tp->tm_year;     /* Use to set up defaults */
  50:     mon = tp->tm_mon;
  51:     day = tp->tm_mday;
  52: 
  53: 
  54: #ifdef DEBUG
  55: printf("first YMD: %d %d %d, T=%ld\n",year,mon,day,tres);
  56: #endif DEBUG
  57:     tp = atm;
  58: 
  59:     /* First must find date, using specified year, month, day.
  60: 	 * If one of these is unspecified, it defaults either to the
  61: 	 * current date (if no more global spec was given) or to the
  62: 	 * zero-value for that spec (i.e. a more global spec was seen).
  63: 	 * Start with year... note 32 bits can only handle 135 years.
  64: 	 */
  65:     if(tp->tm_year != TMNULL)
  66:       { if((year = tp->tm_year) >= 1900)    /* Allow full yr # */
  67:             year -= 1900;           /* by making kosher */
  68:         mon = 0;        /* Since year was given, default */
  69:         day = 1;        /* for remaining specs is zero */
  70:       }
  71:     if(year < 70 || 70+134 < year ) /* Check range */
  72:         return(0);      /* ERR: year out of range */
  73:     leap = year&03 ? 0 : 1;     /* See if leap year */
  74:     year -= 70;         /* UNIX time starts at 1970 */
  75: 
  76:     /*
  77: 	 * Find day of year.
  78: 	 * YDAY is used only if it exists and either the month or day-of-month
  79: 	 * is missing.
  80: 	 */
  81:     if (tp->tm_yday != TMNULL
  82:      && (tp->tm_mon == TMNULL || tp->tm_mday == TMNULL))
  83:         yday = tp->tm_yday;
  84:     else
  85:       { if(tp->tm_mon  != TMNULL)
  86:           { mon = tp->tm_mon;   /* Month was specified */
  87:             day = 1;        /* so set remaining default */
  88:           }
  89:         if(mon < 0 || 11 < mon) return(0);  /* ERR: bad month */
  90:         if(tp->tm_mday != TMNULL) day = tp->tm_mday;
  91:         if(day < 1
  92:          || (((daytb[mon+1]-daytb[mon]) < day)
  93:             && (day!=29 || mon!=1 || !leap) ))
  94:                 return(0);      /* ERR: bad day */
  95:         yday = daytb[mon]   /* Add # of days in months so far */
  96:           + ((leap      /* Leap year, and past Feb?  If */
  97:               && mon>1)? 1:0)   /* so, add leap day for this year */
  98:           + day-1;      /* And finally add # days this mon */
  99: 
 100:                 if (tp->tm_yday != TMNULL       /* Confirm that YDAY correct */
 101:                  && tp->tm_yday != yday) return(0);     /* ERR: conflict */
 102:       }
 103:     if(yday < 0 || (leap?366:365) <= yday)
 104:         return(0);      /* ERR: bad YDAY or maketime bug */
 105: 
 106:     tres = year*365         /* Get # days of years so far */
 107:         + ((year+1)>>2)     /* plus # of leap days since 1970 */
 108:         + yday;         /* and finally add # days this year */
 109: 
 110:         if((i = tp->tm_wday) != TMNULL) /* Check WDAY if present */
 111:                 if(i < 0 || 6 < i       /* Ensure within range */
 112:                   || i != (tres+4)%7)   /* Matches? Jan 1,1970 was Thu = 4 */
 113:                         return(0);      /* ERR: bad WDAY */
 114: 
 115: #ifdef DEBUG
 116: printf("YMD: %d %d %d, T=%ld\n",year,mon,day,tres);
 117: #endif DEBUG
 118:     /*
 119: 	 * Now determine time.  If not given, default to zeros
 120: 	 * (since time is always the least global spec)
 121: 	 */
 122:     tres *= 86400L;         /* Get # seconds (24*60*60) */
 123:     hour = min = sec = 0;
 124:     if(tp->tm_hour != TMNULL) hour = tp->tm_hour;
 125:     if(tp->tm_min  != TMNULL) min  = tp->tm_min;
 126:     if(tp->tm_sec  != TMNULL) sec  = tp->tm_sec;
 127:     if( min < 0 || 60 <= min
 128:      || sec < 0 || 60 <= sec) return(0);    /* ERR: MS out of range */
 129:     if(hour < 0 || 24 <= hour)
 130:         if(hour != 24 || (min+sec) !=0) /* Allow 24:00 */
 131:             return(0);      /* ERR: H out of range */
 132: 
 133:     /* confirm AM/PM if there */
 134:     switch(tp->tm_ampm)
 135:       { case 0: case TMNULL:    /* Ignore these values */
 136:             break;
 137:         case 1:         /* AM */
 138:         case 2:         /* PM */
 139:             if(hour > 12) return(0);  /* ERR: hrs 13-23 bad */
 140:             if(hour ==12) hour = 0; /* Modulo 12 */
 141:             if(tp->tm_ampm == 2)    /* If PM, then */
 142:                 hour += 12; /*   get 24-hour time */
 143:             break;
 144:         default: return(0); /* ERR: illegal TM_AMPM value */
 145:       }
 146: 
 147:     tres += sec + 60L*(min + 60L*hour); /* Add in # secs of time */
 148: 
 149: #ifdef DEBUG
 150: printf("HMS: %d %d %d T=%ld\n",hour,min,sec,tres);
 151: #endif DEBUG
 152:     /*
 153: 	 * We now have the GMT date/time and must make final
 154: 	 * adjustment for the specified time zone.  If none is specified,
 155: 	 * the local time-zone is assumed.
 156: 	 */
 157:     if((zone = tp->tm_zon) == TMNULL    /* If unspecified */
 158:      || (zone == 1))            /* or local-zone requested */
 159:         zone = localzone();     /* then set to local zone */
 160:     if(zone < 0 || 24*60 <= zone)
 161:         return(0);          /* ERR: zone out of range */
 162: 
 163:     /* See if must apply Daylight Saving Time shift.
 164: 	 * Note that if DST is specified, validity is not checked.
 165: 	 */
 166:     if((dst = tp->tm_isdst) == TMNULL)  /* Must we figure it out? */
 167:       { curtim = tres +localzone()*60L; /* Yuck.  Get equiv local */
 168:         dst = localtime(&curtim)->tm_isdst;     /* time, and ask. */
 169:       }
 170:     tres += zone*60L -(dst?3600:0); /* Add in # seconds of zone adj */
 171: 
 172:     return(tres);
 173: }
 174: 
 175: 
 176: /* LOCALZONE		return local timezone in # mins west of GMT
 177:  *
 178:  */
 179: 
 180: #ifdef V6
 181: extern timezone;
 182: #else /* V7 */
 183: #include <sys/types.h>
 184: #include <sys/timeb.h>
 185: #endif V6/7
 186: 
 187: int _lclzon = -1;
 188: localzone()
 189: {
 190: #ifdef V6
 191:     return(_lclzon >= 0 ? _lclzon : (_lclzon = timezone/60));
 192: #else /* V7 */
 193:     struct timeb tb;
 194: 
 195:     if(_lclzon < 0)
 196:       { ftime(&tb);
 197:         _lclzon = tb.timezone;
 198:       }
 199:     return(_lclzon);
 200: 
 201: #endif V6/7
 202: }

Defined functions

localzone defined in line 188; used 2 times
maketime defined in line 40; used 4 times

Defined variables

_lclzon defined in line 187; used 6 times
daytb defined in line 34; used 3 times
rcsid defined in line 23; never used
Last modified: 1983-03-28
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1053
Valid CSS Valid XHTML 1.0 Strict