converting between UTC and localtime (Linux)

Posted on 2008-10-26
Last Modified: 2012-05-05
I'm working with libecal to manage and add events to Evolution. Evolution date/time events are set to UTC timezone. No matter what i do the events in the calendar are always entered according to the UTC,
so, for example, if i have a struct tm and i fill it with the following values:

       timestart.tm_year = 2008 - 1900;
       timestart.tm_mon = 11 - 1;
       timestart.tm_mday = 9;
       timestart.tm_hour = 12;
       timestart.tm_min = 00;
       timestart.tm_sec = 00;
       timestart.tm_isdst = -1;

instead of entering the event (appointment) on 11/09/1008 12:00 PM it will be set at 11/09/2008 10:00 AM because UTC is -2hs

i tried different approaches like

   time_t now = time(NULL);
   struct tm lcl = *localtime(&now);
   struct tm gmt = *gmtime(&now);

and then comparing the two values at lcl.tm_hour and gmt.tm_hour and fixing struct tm accordingly but it gets really messy.

how can i convert UTC timezone to the local timezone and fill the tm struct with the proper values?

(or if anyone know how to do it specifically for the libecal even better...)

Question by:urif
  • 2
  • 2
LVL 23

Accepted Solution

Mysidia earned 100 total points
ID: 22807918
You convert UTC calendar time to a 'struct tm'  in UTC  by calling gmtime().
UTC calendar time is a 'time_t'  integer variable which represents number of second since Jan 1, 1970.

You convert UTC calendar time to a 'struct tm'  representing the time in the LOCAL time zone by calling localtime().

You convert a  'tm'  structure to calendar time by calling the 'mktime()' function and taking its result.

So for example, if you have a timestamp 'now'  that you want to convert into a localtime structure
   struct tm lcl = *localtime(&now);

is correct.

If you want to convert 'lcl'  back to UTC 'calendar time' then you use

   time_t newtimestamp = mktime(lcl);

If you want to  change a tm structure manually IN THE LOCAL TIMEZONE,  I suggest you use localtime()  to fill it with values represented in the local timezone.

Then make your adjustments.
Use mktime()  to convert the structure to a 'time_t'  UTC calendar time value.

Then lastly call  gmtime()   and get its result, which is a 'struct tm' of the time in UTC.

 time_t now = time(0);
 struct tm X = *localtime(&now);
  /* make your changes to X */
 time_t  newtime  = mktime(&X);

 struct tm InUTC = *gmtime(&newtime);


Author Comment

ID: 22810746
ok, let me check and i'll get back to you shortly.

i assume the X.tm_hour has the local timezone hour and InUTC.tm_hour the UTC timezone? is that correct?

Author Comment

ID: 22811199
well, i tried it. it does give me the time in UTC and localtime, the same as the sample i wrote in the question:

 time_t now = time(NULL);
   struct tm lcl = *localtime(&now);
   struct tm gmt = *gmtime(&now);

now, i computer the difference (in my case 2hr) and when i add that difference to the struct tm and convert it to time_t i still get a different date or time or a segfault.

the idea is not to get the "now" time/date but a specific date filled by the user. while this sample works more of less for the "now" it still fails when i have to convert a struct tm that was filled with a specific date
LVL 23

Expert Comment

ID: 22811736
Use  localtime()  to fill in the 'struct tm'  initially.  

Then change values in the 'struct tm'  you  got with localtime()    to what the user input and  THEN proceed with the conversion  to a time_t using  mktime().

All fields must be properly filled in  (including some time zone fields)  in order for mktime()  to work correctly.

It's impossible to tell without seeing what code you are attempting to use, but a most likely reason for a segfault is that  the call to   gmtime()  or localtime()  fails

These functions may fail and return a null pointer if the 'struct tm'   isn't completely populated.

Dereferencing a null pointer causes a segfault.


Featured Post

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Have you ever been frustrated by having to click seven times in order to retrieve a small bit of information from the web, always the same seven clicks, scrolling down and down until you reach your target? When you know the benefits of the command l…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode ( They will have you believe that Unicode requires you to use…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question