Thread: Converting Time Zones To Central Standard Time (CST)

  1. #1
    Registered User
    Join Date
    Jan 2014
    Posts
    139

    Converting Time Zones To Central Standard Time (CST)

    I seem to be going in circles here and I would greatly appreciate any help I can get.




    I have a date that comes in as "2019-05-16T09:30:00-04:00" as an example. (I wont know the timezone in advance)


    In the example above it is -4:00 from UTC


    2019-05-16 09:30:00 - 04:00


    According to this chart UTC to CST Converter - Savvy Time
    adding 4 hours to 09:30:00 gives me 13:30 (or 8:30 AM converted to cst)




    My question is how do I get the incoming date to the actual CST time.


    Code:
    const char *time_details = "2019-05-16T09:30:00-04:00";
    struct tm tm2;
    strptime(time_details, "%Y-%m-%dT%H:%M:%S%z", &tm2);
    time_t tmIncomingTime = mktime(&tm2);
    struct tm * tmLocalTime = localtime(&tmIncomingTime);
    time_t t3 = mktime(tmLocalTime);

    The output of t3 is 9:30 which is not what I am expecting.


    How can I get this converting the timezones with the correct time.


    Thanks in advance.

  2. #2
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    %z is a glibc extension. It obeys RFC 822/ISO 8601 standard.
    Last edited by flp1969; 05-16-2019 at 10:28 AM.

  3. #3
    Registered User
    Join Date
    Jan 2014
    Posts
    139
    2019-05-16T09:30:00-04:00 to my understanding is in the RFC 822/ISO 8601 standard

    ISO 8601 - Wikipedia

    A single point in time can be represented by concatenating a complete date expression, the letter T as a delimiter, and a valid time expression. For example, "2007-04-05T14:30".
    If a time zone designator is required, it follows the combined date and time. For example, "2007-04-05T14:30Z" or "2007-04-05T12:30-02:00".
    Last edited by EverydayDiesel; 05-16-2019 at 11:44 AM.

  4. #4
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    But not RFC 822... RFC 822 uses +/-hhmm zone offset format.

    Take a look at this code (pay attention to the comments).
    Code:
    /* test.c */
    #define _GNU_SOURCE
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <time.h>
    
    static void f( char * );
    
    int main ( void )
    {
      char **p;
    
      // RFC 822/ISO 8601 standard date/time format.
      // The zone offset must be in format [+|-]hhmm.
      static char *tstrs[] = { "2019-05-16T16:30:00-0300",
                               "2019-05-16T16:30:00+0300",
                               NULL };
    
      p = tstrs;
      while ( *p )
        f( *p++ );
    }
    
    // strips the final '\n' from string pointed by p.
    #define stripnl(p) {char *tp_;if(tp_=strchr((p),'\n'))*tp_='\0';}
    
    void f( char *tstr )
    {
      struct tm tm = {0}; // strptime says tm should
                          // be initialized first. So,
                          // no garbage!
      time_t t, t2;
      long int offset;
      char *p, *q;
    
      // %F and %z are glibc extensions.
      // %F == %Y-%m-%d
      // %z expects a zone offset [+/-]hhmm (rfc822).
      strptime ( tstr, "%FT%H:%M:%S%z", &tm );
    
      // tm_gmtoff is a glibc extension.
      // mktime changes the buffer, so we cannot reuse tm.tm_gmtoff.
      offset = tm.tm_gmtoff;
      t = mktime ( &tm );
      t2 = t + offset;
    
      // ctime returns a pointer to a static buffer.
      // duplicate them.
      p = strdup( ctime( &t ) ); 
      q = strdup( ctime( &t2 ) ); 
    
      // strip final '\n' from buffers.
      stripnl( p );
      stripnl( q );
    
      printf( "%s -> %s (%s %s%ld secs)\n", 
              tstr, 
              q, p,
              offset >= 0 ? "+" : "", 
              offset );
    
      free( q );
      free( p );
    }

  5. #5
    Registered User
    Join Date
    Jan 2014
    Posts
    139
    so the data comes to me as "2019-05-16T09:30:00-04:00" and i can make it "2019-05-16T09:30:00-0400" but I am still lost on how to convert it to my current timezone


    Code:
    const char *time_details = "2019-05-16T09:30:00-0400";
    struct tm tm2;
    strptime(time_details, "%Y-%m-%dT%H:%M:%S%z", &tm2);
    time_t tmIncomingTime = mktime(&tm2);
    struct tm * tmLocalTime = localtime(&tmIncomingTime);
    time_t t3 = mktime(tmLocalTime);
    

  6. #6
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Quote Originally Posted by EverydayDiesel View Post
    so the data comes to me as "2019-05-16T09:30:00-04:00" and i can make it "2019-05-16T09:30:00-0400" but I am still lost on how to convert it to my current timezone

    Code:
    const char *time_details = "2019-05-16T09:30:00-0400";
    struct tm tm2;
    strptime(time_details, "%Y-%m-%dT%H:%M:%S%z", &tm2);
    time_t tmIncomingTime = mktime(&tm2);
    struct tm * tmLocalTime = localtime(&tmIncomingTime);
    time_t t3 = mktime(tmLocalTime);
    
    I think you didn't pay attention: strptime() dont change ALL the fields of struct tm. You NEED to initialize it FIRST:
    Code:
    struct tm tm2 = {0}; // init with all zeros
    On how to discover your timezone, take a look:
    Code:
    /* test.c */
    #include <stdio.h>
    #include <string.h>
    #include <time.h>
    
    int main( void )
    {
      struct tm *tm;
      time_t t;
      char *s;
    
      t = time(NULL);
      tm = localtime(&t);
      s = asctime(tm);
      { char *p = strchr( s, '\n' ); if ( p ) *p = '\0'; }
      printf( "%s\n", s );
    }
    Code:
    $ cc -g -o test test.c
    $ gdb -q test
    Reading symbols from test...done.
    (gdb) l
    1    /* test.c */
    2    #include <stdio.h>
    3    #include <string.h>
    4    #include <time.h>
    5    
    6    int main( void )
    7    {
    8      struct tm *tm;
    9      time_t t;
    10      char *s;
    (gdb) l
    11    
    12      t = time(NULL);
    13      tm = localtime(&t);
    14      s = asctime(tm);
    15      { char *p = strchr( s, '\n' ); if ( p ) *p = '\0'; }
    16      printf( "%s\n", s );
    17   }
    (gdb) b 14
    Breakpoint 1 at 0x7ff: file test.c, line 14.
    (gdb) r
    Starting program: /mnt/vol2/Work/tmp/test 
    
    Breakpoint 1, main () at test.c:14
    14      s = asctime(tm);
    (gdb) p *tm
    $1 = {tm_sec = 35, tm_min = 56, tm_hour = 19, tm_mday = 16, tm_mon = 4, tm_year = 119, tm_wday = 4, tm_yday = 135, 
      tm_isdst = 0, tm_gmtoff = -10800, tm_zone = 0x555555756500 "-03"}
    (gdb) c
    Continuing.
    Thu May 16 19:56:35 2019
    [Inferior 1 (process 10187) exited normally]
    (gdb) q
    $
    Well... after localtime() call tm.tm_gmtoff is -10800 (I'm brazillian, UTC-3 zone here).
    This offset is in seconds.

    Beware! This is a GNU extension from glibc (probably not available on MSVC and other compilers).
    Last edited by flp1969; 05-16-2019 at 05:05 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 04-17-2013, 11:32 PM
  2. Replies: 2
    Last Post: 04-17-2013, 12:25 AM
  3. How to write a program for Time Zones?
    By Sarath Karanam in forum C Programming
    Replies: 2
    Last Post: 03-02-2013, 12:57 PM
  4. FireWire and the difficulty of time zones
    By Aparavoid in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 05-27-2009, 03:56 PM
  5. Converting Zulu Time to Current Time
    By Caldus in forum C++ Programming
    Replies: 3
    Last Post: 06-08-2006, 08:54 PM

Tags for this Thread