9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | LICENSE

tm2sec.c (1900B)


      1 #include <u.h>
      2 #include <libc.h>
      3 
      4 #include "zoneinfo.h"
      5 
      6 #define SEC2MIN 60L
      7 #define SEC2HOUR (60L*SEC2MIN)
      8 #define SEC2DAY (24L*SEC2HOUR)
      9 
     10 /*
     11  *  days per month plus days/year
     12  */
     13 static	int	dmsize[] =
     14 {
     15 	365, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
     16 };
     17 static	int	ldmsize[] =
     18 {
     19 	366, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
     20 };
     21 
     22 /*
     23  *  return the days/month for the given year
     24  */
     25 static int *
     26 yrsize(int y)
     27 {
     28 	if((y%4) == 0 && ((y%100) != 0 || (y%400) == 0))
     29 		return ldmsize;
     30 	else
     31 		return dmsize;
     32 }
     33 
     34 /*
     35  * compute seconds since Jan 1 1970 GMT
     36  * and convert to our timezone.
     37  */
     38 long
     39 tm2sec(Tm *tm)
     40 {
     41 	Tinfo ti0, ti1, *ti;
     42 	long secs;
     43 	int i, yday, year, *d2m;
     44 
     45 	secs = 0;
     46 
     47 	/*
     48 	 *  seconds per year
     49 	 */
     50 	year = tm->year + 1900;
     51 	for(i = 1970; i < year; i++){
     52 		d2m = yrsize(i);
     53 		secs += d2m[0] * SEC2DAY;
     54 	}
     55 
     56 	/*
     57 	 *  if mday is set, use mon and mday to compute yday
     58 	 */
     59 	if(tm->mday){
     60 		yday = 0;
     61 		d2m = yrsize(year);
     62 		for(i=0; i<tm->mon; i++)
     63 			yday += d2m[i+1];
     64 		yday += tm->mday-1;
     65 	}else{
     66 		yday = tm->yday;
     67 	}
     68 	secs += yday * SEC2DAY;
     69 
     70 	/*
     71 	 * hours, minutes, seconds
     72 	 */
     73 	secs += tm->hour * SEC2HOUR;
     74 	secs += tm->min * SEC2MIN;
     75 	secs += tm->sec;
     76 
     77 	/*
     78 	 * Assume the local time zone if zone is not GMT
     79 	 */
     80 	if(strcmp(tm->zone, "GMT") != 0) {
     81 		i = zonelookuptinfo(&ti0, secs);
     82 		ti = &ti0;
     83 		if (i != -1)
     84 		if (ti->tzoff!=0) {
     85 			/*
     86 			 * to what local time period `secs' belongs?
     87 			 */
     88 			if (ti->tzoff>0) {
     89 				/*
     90 				 * east of GMT; check previous local time transition
     91 				 */
     92 				if (ti->t+ti->tzoff > secs)
     93 				if (zonetinfo(&ti1, i-1)!=-1)
     94 					ti = &ti1;
     95 			} else
     96 				/*
     97 				 * west of GMT; check next local time transition
     98 				 */
     99 				if (zonetinfo(&ti1, i+1))
    100 				if (ti1.t+ti->tzoff < secs)
    101 					ti = &ti1;
    102 //			fprint(2, "tt: %ld+%d %ld\n", (long)ti->t, ti->tzoff, (long)secs);
    103 			secs -= ti->tzoff;
    104 		}
    105 	}
    106 	
    107 	if(secs < 0)
    108 		secs = 0;
    109 	return secs;
    110 }