views:

95

answers:

2

Hi,

I'm currently migrating some of my code from Cocoa (Apple's Objective-C API) to C, in order to make it available for other operating systems, such as GNU/Linux.

In Cocoa, there were many great things like creating NSTimeZone objects from their string descriptors using timeZoneWithAbbreviation:. This allowed me to use values like "Europe/Paris" to easily create NSTimeZone objects. Another important method for me was secondsFromGMTForDate: because it automatically considers DST rules for you.

Right now, the closest thing to NSTimeZone I've found for C is the struct timezone (see here). However, I do not see how I can easily get the GMT "offset" in seconds for a specific time and timezone. Neither do I understand how to get timezone structs if you only have a description like "Europe/Paris".

I'm sorry if all this sounds trivial, but I haven't found any good example on this!

Thanks for any help!

-- Marc

+2  A: 

Unfortunately, you are treading into difficult territory. There isn't a good, widely available time zone library not attached to other major projects. You can look at the code that comes with the Olson Database (of time zones), and you can look at ICU (Internationalization Components for Unicode).

Jonathan Leffler
Cocoa uses ICU, so ICU should give you equivalent behavior.
Steven R. Loomis
+3  A: 

The following is my understanding and may be wrong...

I'm not sure how OS X does it, but on Linux, the standard C timezone functions use the Olson database, which is really quite powerful (since it has a full list of locale descriptions and keeps track of historical time zone rules as well as current rules).

To set a time zone, call tzset. This function is automatically called by other time-related functions, but you can manually specify a different time zone from the system default by setting the TZ environment variable then calling tzset. For example:

int main(int argc, char *argv[]) {
    time_t t = time(NULL);
    printf("%s\n", ctime(&t));

    setenv("TZ", "America/Chicago", 1);
    printf("%s\n", ctime(&t));

    return 0;
}

Calling tzset also sets the timezone global variable, which you can use to find the GMT offset in seconds for the current time zone.

These functions only let you use one time zone at a time, and although all of this (except for possibly the timezone global variable) should be standard C, platforms other than Linux may not have the full support for lists of locales, daylight savings time changes, etc. If you find that this doesn't meet your needs, then you can try using third-party libraries, such as the code distributed with the [Olson database] or ICU's TimeZone class (also usable from C).

Josh Kelley