time_t, tm*, and timezones (please read!) 
Author Message
 time_t, tm*, and timezones (please read!)

    Hello...

    I am having some difficulty coming to terms with how C/C++ handles time.
In the client/server application that I am writing, the client and server
will periodically exchange information dealing with times and dates -- so I
want to make sure that I am interpreting the Visual C++ documentation
correctly.

    1) As I understand it, time_t stores the  number of seconds passed since
midnight, Jan 1, 1970 GMT. So, if the client and server are in different
time zones, and both computers call time(NULL) at the same time, both time()
calls will return the exact same time_t value assuming that the OSs' clocks
are set correctly. Correct?

    2) When a user on the client types in a date, (i.e. "10/15/1997"), I
want to convert this string to a time_t and transmit it to the server. The
server does NOT know the time zone of the client. The client does NOT know
the time zone of the server. My idea is for the client to ALWAYS translate
ALL dates into "GM time" prior to transmitting the data to the server. But
here is my problem:
    If the user enters "10/15/1997", I can parse the string and fill in a tm
structure. However, there is no field in the tm structure representing the
time zone -- so when mktime() is called against the tm structure that I
filled in, mktime() just ASSUMES that the time zone is local. This is a


mktime() to generate its return value based on GM time instead of local
time?

    3) Does standard C++ have a date class? I know that MFC has a date
class, but for this particular project I can't link to MFC. Standard C++
must have SOME kind of date class, but I can't find it for the life of me.

    Thanks for your consideration...
--
and his name was,

David Sworder



Mon, 05 Aug 2002 03:00:00 GMT  
 time_t, tm*, and timezones (please read!)

Quote:

>     The simplest way is to note that the values in the struct tm passed to
> mktime, do not need to be in the proper ranges --- mktime will normalize
> them first, and then build the time_t.  So, just add the appropriate
number
> of hours to the tm.tm_hour element to adjust it to UTC.  mktime will deal
> with changing the date if necessary.

    Yes, but the question then becomes: "How do I find the number of hours
between my time and UTC?" It's true the VC++ has a _timezone variable that
contains the difference between the local time zone and GM time zone,
expressed in seconds...BUT, that value is only valid TODAY. For example,
right now the value equals 8 hrs. But in April, this value might only be
7hrs because of Daylight Savings.

    So I guess what I'm trying to say is: The trick that you mentioned above
would only work for TODAYs date, but not for some arbitrary date -- unless
you know the DST rules for every location in which your application will be
functioning... Please let me know if I missed something. In the meantime,
I'll check out your date class.

David



Mon, 05 Aug 2002 03:00:00 GMT  
 time_t, tm*, and timezones (please read!)

Quote:

>    Hello...

>    I am having some difficulty coming to terms with how C/C++ handles time.
>In the client/server application that I am writing, the client and server
>will periodically exchange information dealing with times and dates -- so I
>want to make sure that I am interpreting the Visual C++ documentation
>correctly.

>    1) As I understand it, time_t stores the  number of seconds passed since
>midnight, Jan 1, 1970 GMT.

Some implementations do this however the C language itself doesn't specify
the representation used by time_t so you souldn't generally assume that
different systems will use the same format.

Quote:
>So, if the client and server are in different
>time zones, and both computers call time(NULL) at the same time, both time()
>calls will return the exact same time_t value assuming that the OSs' clocks
>are set correctly. Correct?

Maybe, maybe not.

Quote:
>    2) When a user on the client types in a date, (i.e. "10/15/1997"), I
>want to convert this string to a time_t and transmit it to the server. The
>server does NOT know the time zone of the client. The client does NOT know
>the time zone of the server. My idea is for the client to ALWAYS translate
>ALL dates into "GM time" prior to transmitting the data to the server. But
>here is my problem:
>    If the user enters "10/15/1997", I can parse the string and fill in a tm
>structure. However, there is no field in the tm structure representing the
>time zone -- so when mktime() is called against the tm structure that I
>filled in, mktime() just ASSUMES that the time zone is local.

That's reasonable, and as far as I can see from your problem description
the time entered by a user will be a local time so that's no problem.

Quote:
>This is a


>mktime() to generate its return value based on GM time instead of local
>time?

The return value of mktime() is in the standard format for that particular
implementation. If that happens to be seconds since Jan 1 1970 GMT then that
is what mktime() will return. It is the *input* data that mktime()
always takes as being a local time specification.

--
-----------------------------------------


-----------------------------------------



Mon, 05 Aug 2002 03:00:00 GMT  
 time_t, tm*, and timezones (please read!)
<< 1) As I understand it, time_t stores the  number of seconds passed since
midnight, Jan 1, 1970 GMT. So, if the client and server are in different
time zones, and both computers call time(NULL) at the same time, both time()
calls will return the exact same time_t value assuming that the OSs' clocks
are set correctly. Correct? >>

Not a safe assumption in most cases. Believe me, you cannot depend on this.
You are better off including synchronization as part of your project.

To solve your problem, simply accept the time and convert it to GMT before
transmitting it. And convert back to local time before displaying the time.
Functions for this purpose are declared in time.h.

You do not need to know the local machine's time zone to convert between
local and GMT, and back (assuming the time zone has been set correctly in
the local machine). Carefully study the functions in time.h. You will see
this is true.

Using the functions in time.h, you can even acquire the time zone in a
machine that does not provide explicit access to this information. This
approach is actually a good idea from a portability standpoint. The only
thing you cannot portably do is *set* the local machine's time zone.

<< Standard C++ must have SOME kind of date class, but I can't find it for
the life of me. >>

Standard C++ does not have an intrinsic date or time class. I believe this
was because the creators of C++ realized just what a can of worms dates and
times are, and decided to leave this up to individual developers.

--

Paul Lutus
www.arachnoid.com


Quote:
>     Hello...

>     I am having some difficulty coming to terms with how C/C++ handles
time.
> In the client/server application that I am writing, the client and server
> will periodically exchange information dealing with times and dates -- so
I
> want to make sure that I am interpreting the Visual C++ documentation
> correctly.

>     1) As I understand it, time_t stores the  number of seconds passed
since
> midnight, Jan 1, 1970 GMT. So, if the client and server are in different
> time zones, and both computers call time(NULL) at the same time, both
time()
> calls will return the exact same time_t value assuming that the OSs'
clocks
> are set correctly. Correct?

>     2) When a user on the client types in a date, (i.e. "10/15/1997"), I
> want to convert this string to a time_t and transmit it to the server. The
> server does NOT know the time zone of the client. The client does NOT know
> the time zone of the server. My idea is for the client to ALWAYS translate
> ALL dates into "GM time" prior to transmitting the data to the server. But
> here is my problem:
>     If the user enters "10/15/1997", I can parse the string and fill in a
tm
> structure. However, there is no field in the tm structure representing the
> time zone -- so when mktime() is called against the tm structure that I
> filled in, mktime() just ASSUMES that the time zone is local. This is a


> mktime() to generate its return value based on GM time instead of local
> time?

>     3) Does standard C++ have a date class? I know that MFC has a date
> class, but for this particular project I can't link to MFC. Standard C++
> must have SOME kind of date class, but I can't find it for the life of me.

>     Thanks for your consideration...
> --
> and his name was,

> David Sworder



Mon, 05 Aug 2002 03:00:00 GMT  
 time_t, tm*, and timezones (please read!)

[snip]
Quote:
>     If the user enters "10/15/1997", I can parse the string and fill in a tm
> structure. However, there is no field in the tm structure representing the
> time zone -- so when mktime() is called against the tm structure that I
> filled in, mktime() just ASSUMES that the time zone is local. This is a


> mktime() to generate its return value based on GM time instead of local
> time?

[snip]

The idea to solve this problem is to "calculate" a delta of the computer's
timezone to the UTC. You only have to take a certain date, e.g.
1970-01-02 00:00:00, call mktime(), and substract the expected value, here
24 * 60 * 60. The result is usable for "corrections". See also the
example below.

kind regards,
Steffen

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

int main(int argc, char *argv[])
{
  struct tm tm ;
  int delta, elapsed ;

  if (argc != 2)
  {
    fprintf(stderr, "usage: %s YYYY-MM-DD HH:MM:SS\n", basename(argv[0])) ;
    return 1 ;
  }

  tm.tm_year  = 70 ;
  tm.tm_mon   =  0 ;
  tm.tm_mday  =  2 ;
  tm.tm_hour  =  0 ;
  tm.tm_min   =  0 ;
  tm.tm_sec   =  0 ;
  tm.tm_isdst =  0 ;

  delta = 24 * 60 * 60 - (int) mktime(&tm) ;

  {
    int year = 1970 ;
    int month = 1 ;
    int dom = 1 ;
    int hour = 0 ;
    int minute = 0 ;
    int second = 0 ;

    sscanf(argv[1], "%d-%d-%d %d:%d:%d", &year, &month,
           &dom, &hour, &minute, &second) ;

    tm.tm_year = year - 1900 ;
    tm.tm_mon = month - 1 ;
    tm.tm_mday = dom ;
    tm.tm_hour = hour ;
    tm.tm_min = minute ;
    tm.tm_sec = second ;
  }

  elapsed = delta + (int) mktime(&tm) ;

  tm = *gmtime((time_t*) &elapsed) ;

  printf("%d (%d) {%04d-%02d-%02d %02d:%02d:%02d}\n", elapsed, delta,
         tm.tm_year + 1900,
         tm.tm_mon + 1,
         tm.tm_mday,
         tm.tm_hour,
         tm.tm_min,
         tm.tm_sec) ;

  return 0 ;

Quote:
}

--



Sun, 11 Aug 2002 03:00:00 GMT  
 time_t, tm*, and timezones (please read!)
[...]

Quote:
> The idea to solve this problem is to "calculate" a delta of the computer's
> timezone to the UTC. You only have to take a certain date, e.g.
> 1970-01-02 00:00:00, call mktime(), and substract the expected value, here
> 24 * 60 * 60. The result is usable for "corrections". See also the
> example below.

This ignores Daylight Saving Time.

--

San Diego Supercomputer Center           <*>  <http://www.sdsc.edu/~kst>
Welcome to the last year of the 20th century.



Sun, 11 Aug 2002 03:00:00 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. time_t, tm*, and timezones (please read!)

2. Converting a struct tm in UTC to a time_t

3. Fast conversion between time_t and struct tm?

4. Converting a struct tm in UTC to a time_t

5. struct tm -> time_t converter wanted

6. From (struct tm) to (time_t) ?

7. Convert tm struct to time_t ?

8. about function struct tm *localtime( const time_t *timer );

9. Compare tm and time_t

10. Insight(TM) -vs- Purify(TM)

11. Time_t question, need help please

12. What's US DST handling? (was: time_t & struct tm confusion)

 

 
Powered by phpBB® Forum Software