converting between UTC and localtime (Linux)

Posted on 2008-10-26
Medium Priority
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
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
LVL 23

Accepted Solution

Mysidia earned 400 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

Visualize your virtual and backup environments

Create well-organized and polished visualizations of your virtual and backup environments when planning VMware vSphere, Microsoft Hyper-V or Veeam deployments. It helps you to gain better visibility and valuable business insights.

Question has a verified solution.

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

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.

718 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