date.c (1961B)
1 #include <u.h> 2 #include <stdlib.h> /* setenv etc. */ 3 #define NOPLAN9DEFINES 4 #include <libc.h> 5 #include <time.h> 6 7 #define _HAVETIMEGM 1 8 #define _HAVETMZONE 1 9 #define _HAVETMTZOFF 1 10 11 #if defined(__linux__) 12 # undef _HAVETMZONE 13 # undef _HAVETMTZOFF 14 15 #elif defined(__sun__) 16 # undef _HAVETIMEGM 17 # undef _HAVETMZONE 18 # undef _HAVETMTZOFF 19 20 #endif 21 22 static Tm bigtm; 23 24 static void 25 tm2Tm(struct tm *tm, Tm *bigtm) 26 { 27 char *s; 28 29 memset(bigtm, 0, sizeof *bigtm); 30 bigtm->sec = tm->tm_sec; 31 bigtm->min = tm->tm_min; 32 bigtm->hour = tm->tm_hour; 33 bigtm->mday = tm->tm_mday; 34 bigtm->mon = tm->tm_mon; 35 bigtm->year = tm->tm_year; 36 bigtm->wday = tm->tm_wday; 37 strftime(bigtm->zone, sizeof bigtm->zone, "%Z", tm); 38 #ifdef _HAVETZOFF 39 bigtm->tzoff = tm->tm_gmtoff; 40 #endif 41 42 if(bigtm->zone[0] == 0){ 43 s = getenv("TIMEZONE"); 44 if(s){ 45 strecpy(bigtm->zone, bigtm->zone+4, s); 46 free(s); 47 } 48 } 49 } 50 51 static void 52 Tm2tm(Tm *bigtm, struct tm *tm) 53 { 54 memset(tm, 0, sizeof *tm); 55 tm->tm_sec = bigtm->sec; 56 tm->tm_min = bigtm->min; 57 tm->tm_hour = bigtm->hour; 58 tm->tm_mday = bigtm->mday; 59 tm->tm_mon = bigtm->mon; 60 tm->tm_year = bigtm->year; 61 tm->tm_wday = bigtm->wday; 62 #ifdef _HAVETMZONE 63 tm->tm_zone = bigtm->zone; 64 #endif 65 #ifdef _HAVETZOFF 66 tm->tm_gmtoff = bigtm->tzoff; 67 #endif 68 } 69 70 Tm* 71 p9gmtime(long x) 72 { 73 time_t t; 74 struct tm tm; 75 76 t = (time_t)x; 77 tm = *gmtime(&t); 78 tm2Tm(&tm, &bigtm); 79 return &bigtm; 80 } 81 82 Tm* 83 p9localtime(long x) 84 { 85 time_t t; 86 struct tm tm; 87 88 t = (time_t)x; 89 tm = *localtime(&t); 90 tm2Tm(&tm, &bigtm); 91 return &bigtm; 92 } 93 94 #if !defined(_HAVETIMEGM) 95 static time_t 96 timegm(struct tm *tm) 97 { 98 time_t ret; 99 char *tz; 100 char *s; 101 102 tz = getenv("TZ"); 103 putenv("TZ="); 104 tzset(); 105 ret = mktime(tm); 106 if(tz){ 107 s = smprint("TZ=%s", tz); 108 if(s) 109 putenv(s); 110 } 111 return ret; 112 } 113 #endif 114 115 long 116 p9tm2sec(Tm *bigtm) 117 { 118 struct tm tm; 119 120 Tm2tm(bigtm, &tm); 121 if(strcmp(bigtm->zone, "GMT") == 0 || strcmp(bigtm->zone, "UCT") == 0) 122 return timegm(&tm); 123 return mktime(&tm); /* local time zone */ 124 } 125