tags:

views:

181

answers:

2

I have a multi-threaded application which needs to display certain dates to the user. The dates are stored using UTC Unix time values. However, the date must be displayed in the time zone of the user, not the local server time or UTC. Basically, I need a function like this:

struct tm *usertime_r(const time_t *timer, struct tm *result, const int timezone) {
  <just like localtime_r, except it uses UTC+timezone as the timezone>
}

This function must be thread safe, so I don't believe that setting the TZ environment variable would be an option.

+2  A: 

If you know the user's offset-from-UTC in seconds, you can just add/subtract that from the time_t and pass the result to gmtime_r.

For example, Australian Eastern Daylight Time is +11, which means you'd add (11*3600) to the time value.

caf
A: 

As a corollary to caf's answer, the <tzinfo.h> header can be used to get the offset-from-UTC for a given timezone. The public domain timezone database contains tons of information; on Linux distros I've used, it's browseable in /usr/share/zoneinfo, and I believe Apple packages it with iTunes for Win32.

From the command line on most distros, you can do this:

# it's easy to find out what timezones are available
$ file /usr/share/zoneinfo/{US/Eastern,UTC}
/usr/share/zoneinfo/US/Eastern: timezone data
/usr/share/zoneinfo/UTC:        timezone data

# now examine them
$ zdump US/Eastern UTC
US/Eastern  Wed Dec 23 00:11:31 2009 EST
GMT         Wed Dec 23 05:11:31 2009 UTC

Looks like US/Eastern is currently in standard time (it would print EDT during the summer), and that it's 5 hours before UTC, which gives you your offset-from-UTC.

Tom