basin
basin

Reputation: 4190

How do I set TZ env var to CET in visual C?

Here's my code:

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

char env_TZ[] = "TZ=CET";

int main(int argc, char* argv[])
{
    time_t submissionTime = 1359120032;
    struct tm local_time;
    char str[30];
    int ofsmm;

    putenv(env_TZ);
    tzset();
    printf("%s (%s)\n", tzname[0], tzname[1]);
    local_time = *localtime(&submissionTime);
    strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S", &local_time);
    ofsmm = -(int)(timezone/60) + (local_time.tm_isdst?60:0);
    printf("%s %+05d\n", str, ofsmm/60*100 + ofsmm % 60);
    return 0;
}

What should be in env_TZ? Definitely not "CET": it sets timezone to zero.
Where's the list of supported values?
It seems that the name I use doesn't matter in visual C, what matters is the number after, for example "FOO-1".

Upvotes: 2

Views: 3390

Answers (1)

Matt Johnson-Pint
Matt Johnson-Pint

Reputation: 241778

Timezone handling in C++ is designed around POSIX style time zones, such as PST8PDT. There isn't a predefined list, but rather a format for describing the time zone rules. They are limited in that they only let you define the current rule. They have no way to express changes to those rules.

You might want to refer to the following documentation links:

In particular, the following bits stand out for MS Visual C++:

If the TZ environment variable is set, the C run-time library assumes rules appropriate to the United States for implementing the calculation of daylight-saving time (DST).

And more troubling:

TZ is a Microsoft extension and not part of the ANSI standard definition of localtime.

So it probably doesn't support the full POSIX time zone extended formats, such as the ones described in this excellent writeup by IBM for AIX.

I am really not certain if it does or doesn't support the extended format, you would have to check. I found the full correct POSIX style TZ variable for Central European Time here, which is:

CET-1CEST,M3.5.0/2,M10.5.0/3

If it doesn't support the extensions the best you could do is CET-1CEST - but that would end up using US daylight transition rules rather than the European ones.

You could consider using Boost, since it appears to have full support for POSIX time zones.

But what you probably want to do instead is use the IANA/Olson standard time zone database. This format of time zone would be specified by something like Europe/Paris, and supports the full history of time zone changes in the area you specify. There appears to be a C++ implementation in a library called ICU. You can see a list of valid zones in this format here.

Time zones are much harder in native code then they are in managed .Net code. If there's any way you can run .Net code instead, I highly recommend using Noda Time, which provides a full IANA/Olson database internally. You could also use Windows time zones via the .Net TimeZoneInfo class, but they're not as standardized as IANA zones.

Upvotes: 1

Related Questions