0

I compile C using the C99 version, and I want to try and output the timezone of the given time.

The IDE I use gives GMT+0 as the timezone, but I want to somehow output it with struct tm.

So I followed the instructions from this answer and made this program:

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

int main()
{
    time_t present = time(NULL);
    struct tm now = *localtime(&present);
    now.tm_mon += 1;
    now.tm_year += 1900;
    struct tm t = {0};
    localtime_r(&present, &t);
    printf("%i/%i/%i %i:%i:%i from %s\n", now.tm_mon, now.tm_mday, now.tm_year, now.tm_hour, now.tm_min, now.tm_sec, t.tm_zone);
}

And it seems like I got 2 errors here:

  1. implicit declaration of function 'localtime_r' is invalid in C99
  2. no member named 'tm_zone' in 'struct tm'

So I checked the IDE Manual, and find that localtime_r actually exists, and is part of the <time.h> library.

So now I'm wondering if the IDE's confused or something. I don't know how to fix it either.

This might get closed as it might "need debugging details", but read more.

Because of this whole situation, how can I get the timezone (maybe even the offset) in C99 and get it to be outputted with printf()?

  • I don't care about your "I didn't want to include the header files in the code shown above.", since the `#include`s are very much relevant. – Cheatah Jan 02 '21 at 12:25
  • @Cheatah You can delete your comment now. –  Jan 02 '21 at 12:38
  • 1
    `localtime_r` is not part of the standard library - it’s an extension offered by specific implementations, and its declaration is not exposed by default in those implementations. If your implementation actually supports it, you’ll have to define the macro `_POSIX_SOURCE` before including `time.h` to make it available. – John Bode Jan 02 '21 at 12:44
  • @JohnBode You can make that an answer. –  Jan 02 '21 at 13:01

1 Answers1

0

First, localtime_r is not part of the standard library - it's an extension offered by some implementations, and by default its declaration is not exposed in those implementations. To make it available, you'll have to define the macro _POSIX_SOURCE before including time.h to make it available. An easy way to do that is on the command line, like so:

gcc -o tz -D_POSIX_SOURCE -std=c11 -pedantic -Wall -Werror tz.c

otherwise, just define it in your source before including time.h:

#define _POSIX_SOURCE
#include <stdio.h>
#include <time.h>

Secondly, if all you're interested in is the local time zone then there's an easier way to do this - get the current time:

time_t t = time( NULL );

then use both localtime and gmtime to get the broken down time for the current time zone and UTC:

struct tm *local = localtime( &t );
struct tm *zulu  = gmtime( &t );

Then compute the difference between the tm_hour members of local and zulu, and that's your time zone.

int tz = zulu->tm_hour - local->tm_hour;

You'll want to check local->tm_isdst to account for daylight savings, but that should at least get you started.

John Bode
  • 119,563
  • 19
  • 122
  • 198