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

Defined functions

localzone defined in line 219; used 2 times

Defined variables

_lclzon defined in line 218; used 9 times
daytb defined in line 60; used 3 times
rcsid defined in line 23; never used
Last modified: 1988-02-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 774
Valid CSS Valid XHTML 1.0 Strict