• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 5238
  • Last Modified:

converting between UTC and localtime (Linux)

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...)

  • 2
  • 2
1 Solution
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);

urifAuthor Commented:
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?
urifAuthor Commented:
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
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

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now