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 }