Now, don't get me wrong. We probably have to live with global variables in association with time for a long time - not the least because of backwards compatibility. However, I do feel that a more "object oriented" approach would be superior and wonder how hard it would be to make a rewrite of parts of the code so that one could provide such an interface. It would be particularly useful for languages like C++ etc but would also be useful for C as C too can handle object oriented type features as is handled in FILE etc. What I mean by object oriented approach here is not full fledged OOP - C is not an OO language. What I mean is simply that you can create an object that represent something and then reference that object to refer to that something later and then destroy it when no longer needed. With this in mind I would like a timezone_t type so that you could do something like: timezone_t * tzNY = tzmake("US/Eastern"); // EDT/EST timezone timezone_t * tzUTC = tzmake("Universal"); // or just mktz("") timezone_t * tzlocal = tzmake(NULL); Then you could do stuff like: struct tm nyTime, gmTime, localTime; time_t now; now = time(); tztime(& nyTime, & now, tzNY); // would do the same as gmtime(). tztime(& gmTime, & now, tzUTC); // would do the same as localtime(). tztime(& localtime, & now, tzlocal): // The last one could also be achieved by: tztime(& localtime, & now, NULL); tzrem(tzNY); tzrem(tzUTC); tzrem(tzlocal); ----------------- The existing approach appear simple enough but the problem is that tzset() has the following deficiencies as I see it: 1. It always only operate through TZ variable - would be nice if there was a version that took the data as string so that tzset() could essentially be implemented by calling that function with getenv("TZ") as argument. 2. It leaves the result in various global variables which are defined around the code. Would be nice if the function instead created a struct and kept all data that is to survive the function call within that struct. 3. For backwards compatibility then tzset() should essentially do the folowing: void tzset(void) { struct timezone_t * tzi = tzmake(getenv("TZ")); // copy data from tzi to various global variables. // timezone, altzone, daylight and tzname etc. // details of this depends on exactly what data // are stored in timezone_t // This could also be placed in a separate function // so user can set these variables based on a // previously generated tzmake() call. tzsettz(tzi); tzrem(tzi); } How much work would it take to do such a rewrite? After browsing the source I find that there are numerous global variables between tzset.c and tzfile.c that are not documented anywhere but still are used such as tz_rules and __use_tzfile just to name two of them. Also, if some applications want to avoid allocation of data one could have a version that took the timezone_t struct on input and filled it in. The problem here is how to handle timezone strings. However, assuming that timezone strings are usually small (3-5 letters max for strings like UTC, CEDT, etc.) one could define that timezone_t has allocated say 8 bytes for each of the strings so that it is fixed size. Then one could: struct timezone_t tzUTC; tzmake(& tzUTC, "Universal"); instead of the tzUTC = tzmake("Universal"); I wrote above. In this case the tzrem() function would not be necessary. Yet again both approaches would be possible where tzmake first malloc() a struct large enough to hold the data and then called the other version to fill in the struct. IN this case tzrem would still be needed and you would need two different versions of tzmake(). For example: timezone_t * tzcreate(getenv("TZ")); which was implemented as: timezone_t * tzcreate(const char * tzid) { timezone_t * res = malloc(sizeof(timezone_t)); if (res == NULL) return NULL; tzmake(res,tzid); return res; } Finally, and not really related to the above. I am trying at the moment to read and understand the code. I notice that the tzfile is opened with "rc" mode. I am not sure exactly what the "c" letter there indicates. It says something about prohibiting cancelattion but I am not exactly sure what that means in practice. Is it that if user interrupts the process while in the middle of say reading the file the interrupt will be waiting until the file is closed or what? Alf
participants (1)
-
Alf Salte