473,472 Members | 2,153 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

using mktime()

I created a function that breaks down a date into broken down time, I
subtract a certain number of seconds from that, then use mktime() to
recompute the calendar time.

It works basically except every so often, I get the date 060207 (Feb 7,
2006) which is obviously not correct. When it does this it always gives me
this date.

I tracked it down to my mktime() call, when I get to a certain date, mktime
returns a number in 4000000000, when it should return a number in
1000000000. But I am not sure why. The variable in my tm struct all have
the correct date, but mktime returns this.

It is happening to me when the date I am changing is: 040727 but it has done
this on others as well.

I am thinking that something goes wrong in mktime() to cause it to return
some default number. Perhaps something wrong in one of my time_broken
members and then it gets past to mktime?

Suggestions? Thanks a bunch!

Here's my code:

int adjust_time()
{
struct tm time_broken; /* time in broken time */
struct tm tb; /* adjusted time */
time_t time_calendar=0; /* calendar time as a long int */
int sec,min,hour,mday,mon,year;
long int dt; /* temp variables */
int tm;
/* if CHG_TIME==0, no conversion necessary */
if(CHG_TIME==0)
{
return 1;
}

/* parse out time & date info */
sec=0;
min=TIME%100;
hour=TIME/100;
mday=DATE%100;
mon=((DATE%10000)/100)-1;

/* year must be represented as years since 1900 */
/* If the year is < 40, we assume it's in 2000's */
/* If the year is >= 40, we assume it's in 1900's */
year=(DATE/10000);
if(year<40)
year=year+100;
/* create the struct tm */
time_broken.tm_sec=sec;
time_broken.tm_min=min;
time_broken.tm_hour=hour;
time_broken.tm_mday=mday;
time_broken.tm_mon=mon;
time_broken.tm_year=year;

/* get the number of seconds since
* Jan 1, 1970 */
time_calendar=mktime(&time_broken);

/* subtract CHGTIME from calendar time_t date */
time_calendar=time_calendar-(CHG_TIME*60);
tb=*(gmtime(&time_calendar));

/* calculate new time */
tm=(tb.tm_hour*100)+tb.tm_min;

/* calculate new date */
dt=( ((tb.tm_year%100)*10000) + ((tb.tm_mon+1)*100) + (tb.tm_mday) );

/* return new time & date */
TIME=tm;
DATE=dt;

return 0;
}
Nov 14 '05 #1
16 14273

"John Hanley" <ha****@ualberta.ca> wrote in message
news:11***************@proxy2.srv.ualberta.ca...
I created a function that breaks down a date into broken down time, I
subtract a certain number of seconds from that, then use mktime() to
recompute the calendar time.

It works basically except every so often, I get the date 060207 (Feb 7,
2006) which is obviously not correct. When it does this it always gives me this date.

I tracked it down to my mktime() call, when I get to a certain date, mktime returns a number in 4000000000, when it should return a number in
1000000000. But I am not sure why. The variable in my tm struct all have
the correct date, but mktime returns this.

It is happening to me when the date I am changing is: 040727 but it has done this on others as well.

I am thinking that something goes wrong in mktime() to cause it to return
some default number. Perhaps something wrong in one of my time_broken
members and then it gets past to mktime?

Suggestions? Thanks a bunch!

Here's my code:


You don't provide definitions for 'CHG_TIME', 'TIME', or
'DATE', so it's impossible to diagnose your problem. Try
posting a complete compilable example that demonstrates
the problem.

I don't know if it's an issue or not, but your reference to
dates above in the form of e.g. 040727 causes me to caution
you that if that's a literal numeric value, note that any
numeric literal whose first digit is zero is interpreted
by the compiler as an octal (base eight) representation.

-Mike

Nov 14 '05 #2
j

"John Hanley" <ha****@ualberta.ca> wrote in message
news:11***************@proxy2.srv.ualberta.ca...
I created a function that breaks down a date into broken down time, I
subtract a certain number of seconds from that, then use mktime() to
recompute the calendar time.

It works basically except every so often, I get the date 060207 (Feb 7,
2006) which is obviously not correct. When it does this it always gives me this date.

I tracked it down to my mktime() call, when I get to a certain date, mktime returns a number in 4000000000, when it should return a number in
1000000000. But I am not sure why. The variable in my tm struct all have
the correct date, but mktime returns this.

It is happening to me when the date I am changing is: 040727 but it has done this on others as well.

I am thinking that something goes wrong in mktime() to cause it to return
some default number. Perhaps something wrong in one of my time_broken
members and then it gets past to mktime?

Suggestions? Thanks a bunch!

Here's my code:

int adjust_time()
{
struct tm time_broken; /* time in broken time */
struct tm tb; /* adjusted time */
time_t time_calendar=0; /* calendar time as a long int */
int sec,min,hour,mday,mon,year;
long int dt; /* temp variables */
int tm;
/* if CHG_TIME==0, no conversion necessary */
if(CHG_TIME==0)
{
return 1;
}

/* parse out time & date info */
sec=0;
min=TIME%100;
hour=TIME/100;
mday=DATE%100;
mon=((DATE%10000)/100)-1;

/* year must be represented as years since 1900 */
/* If the year is < 40, we assume it's in 2000's */
/* If the year is >= 40, we assume it's in 1900's */
year=(DATE/10000);
if(year<40)
year=year+100;
/* create the struct tm */
time_broken.tm_sec=sec;
time_broken.tm_min=min;
time_broken.tm_hour=hour;
time_broken.tm_mday=mday;
time_broken.tm_mon=mon;
time_broken.tm_year=year;

/* get the number of seconds since
* Jan 1, 1970 */
time_calendar=mktime(&time_broken);


You never assign a meaningful value to member ``tm_isdst''.
mktime thus uses an indeterminate value and the consequence
is undefined behaviour.

--
j
Nov 14 '05 #3


John Hanley wrote:
I created a function that breaks down a date into broken down time, I
subtract a certain number of seconds from that, then use mktime() to
recompute the calendar time.

It works basically except every so often, I get the date 060207 (Feb 7,
2006) which is obviously not correct. When it does this it always gives me
this date.

I tracked it down to my mktime() call, when I get to a certain date, mktime
returns a number in 4000000000, when it should return a number in
1000000000. But I am not sure why. The variable in my tm struct all have
the correct date, but mktime returns this.

It is happening to me when the date I am changing is: 040727 but it has done
this on others as well.

I am thinking that something goes wrong in mktime() to cause it to return
some default number. Perhaps something wrong in one of my time_broken
members and then it gets past to mktime?

Suggestions? Thanks a bunch!

Here's my code:


The code is not complete and it is not easy to follow the logic.
But I see you are making some errors. Apparently, you are
assuming that type time_t is type long representing seconds.
Standard C does not specify this to be fact. The Standard
only specifies that time_t be an arithmetic time capable of
representing time. And, it does not specify anything on
its instrumentality. So, to be portable, the code must not
assume the type to be type long and the values representing
seconds. To get around this, Standard C provides functions
that will allow you to manipulate time. So, to correct
your function adjust_time, you will need to convert the
time_t value to broken down time and the adjust the struct
member tm_sec in the number of seconds. Then call function
mktime to generate a new time_t value.
Another problem: check your return values.
You did not check the return value
of your mktime function. time_t's range of dates is limited.
Function mktime will return (time_t)-1 should it be uncapable
of representing that date. I can't be sure, but the values
you are getting in the range of 4000000000 may be result of
function mktime returning a (time_t)-1 value.

An example:

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

time_t AdjustTime(time_t tvalue, int secs)
{
struct tm *tp;
time_t ret;

if((ret = (tvalue != (time_t)-1)))
{
tp = localtime(&tvalue);
if(secs > INT_MAX - tp->tm_sec)
ret = (time_t)-1;
else
{
tp->tm_sec+=secs;
tp->tm_isdst = -1;
ret = mktime(tp);
}
}
return ret;
}

int main(void)
{
time_t date;
struct tm t;

/* make a time_t value for 25DEC2005 12:00:00 */
t.tm_year = 2005-1900;
t.tm_mon = 11;
t.tm_mday = 25;
t.tm_hour = 12;
t.tm_min = t.tm_sec = t.tm_isdst = 0;

if((date = mktime(&t)) == (time_t)-1)
puts("Time is not available");
else
{
printf("date represents %s"
"Attemping to subtract 60 secs\n",ctime(&date));
if((date = AdjustTime(date, -60)) != (time_t)-1)
printf("The new date is %s",ctime(&date));
else puts("Time for the new date is unavailable");
}
return 0;
}
--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #4
> The code is not complete and it is not easy to follow the logic.
But I see you are making some errors. Apparently, you are
assuming that type time_t is type long representing seconds.
you're right, that was what I was assuming.
Standard C does not specify this to be fact. The Standard
only specifies that time_t be an arithmetic time capable of
representing time. And, it does not specify anything on
its instrumentality. So, to be portable, the code must not
assume the type to be type long and the values representing
seconds. To get around this, Standard C provides functions
that will allow you to manipulate time. So, to correct
your function adjust_time, you will need to convert the
time_t value to broken down time and the adjust the struct
member tm_sec in the number of seconds. Then call function
mktime to generate a new time_t value.
I see what you mean. My problem is that I am actually trying to adjust
minutes (from 1 to 59) and subtract the CHG_TIME number from the number of
minutes. However, if my date is Jan 1, 2000 at 00:00, by changing the
minutes, the hour, day, month, & year all have to change as well. That's
why I thought if I could get the time_t value as calendar time, subtract
from it number of minutes*60 (the correct number of seconds), and use
mktime(), I would get the adjusted date (the date-CHG_TIME).

I was under the assumption that the calendar time is the number of seconds
since Jan 1, 1970, and my subtracting so many seconds from that value and
calling mktime(), I would get an earlier date.

So if I were to adjust the broken time instead of the calendar time, how
would I handle the change in minutes, hour, date, month year without having
to do it manually?

Thanks so much for the help! I really appreciate it!

John



Another problem: check your return values.
You did not check the return value
of your mktime function. time_t's range of dates is limited.
Function mktime will return (time_t)-1 should it be uncapable
of representing that date. I can't be sure, but the values
you are getting in the range of 4000000000 may be result of
function mktime returning a (time_t)-1 value.

An example:

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

time_t AdjustTime(time_t tvalue, int secs)
{
struct tm *tp;
time_t ret;

if((ret = (tvalue != (time_t)-1)))
{
tp = localtime(&tvalue);
if(secs > INT_MAX - tp->tm_sec)
ret = (time_t)-1;
else
{
tp->tm_sec+=secs;
tp->tm_isdst = -1;
ret = mktime(tp);
}
}
return ret;
}

int main(void)
{
time_t date;
struct tm t;

/* make a time_t value for 25DEC2005 12:00:00 */
t.tm_year = 2005-1900;
t.tm_mon = 11;
t.tm_mday = 25;
t.tm_hour = 12;
t.tm_min = t.tm_sec = t.tm_isdst = 0;

if((date = mktime(&t)) == (time_t)-1)
puts("Time is not available");
else
{
printf("date represents %s"
"Attemping to subtract 60 secs\n",ctime(&date));
if((date = AdjustTime(date, -60)) != (time_t)-1)
printf("The new date is %s",ctime(&date));
else puts("Time for the new date is unavailable");
}
return 0;
}
--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #5

"j" <ja**********@bellsouth.net> wrote in message
news:RU***************@bignews6.bellsouth.net...

"John Hanley" <ha****@ualberta.ca> wrote in message
news:11***************@proxy2.srv.ualberta.ca...
I created a function that breaks down a date into broken down time, I
subtract a certain number of seconds from that, then use mktime() to
recompute the calendar time.

It works basically except every so often, I get the date 060207 (Feb 7,
2006) which is obviously not correct. When it does this it always gives

me
this date.

I tracked it down to my mktime() call, when I get to a certain date,

mktime
returns a number in 4000000000, when it should return a number in
1000000000. But I am not sure why. The variable in my tm struct all have the correct date, but mktime returns this.

It is happening to me when the date I am changing is: 040727 but it has

done
this on others as well.

I am thinking that something goes wrong in mktime() to cause it to return some default number. Perhaps something wrong in one of my time_broken
members and then it gets past to mktime?

Suggestions? Thanks a bunch!

Here's my code:

int adjust_time()
{
struct tm time_broken; /* time in broken time */
struct tm tb; /* adjusted time */
time_t time_calendar=0; /* calendar time as a long int */
int sec,min,hour,mday,mon,year;
long int dt; /* temp variables */
int tm;
/* if CHG_TIME==0, no conversion necessary */
if(CHG_TIME==0)
{
return 1;
}

/* parse out time & date info */
sec=0;
min=TIME%100;
hour=TIME/100;
mday=DATE%100;
mon=((DATE%10000)/100)-1;

/* year must be represented as years since 1900 */
/* If the year is < 40, we assume it's in 2000's */
/* If the year is >= 40, we assume it's in 1900's */
year=(DATE/10000);
if(year<40)
year=year+100;
/* create the struct tm */
time_broken.tm_sec=sec;
time_broken.tm_min=min;
time_broken.tm_hour=hour;
time_broken.tm_mday=mday;
time_broken.tm_mon=mon;
time_broken.tm_year=year;

/* get the number of seconds since
* Jan 1, 1970 */
time_calendar=mktime(&time_broken);


You never assign a meaningful value to member ``tm_isdst''.
mktime thus uses an indeterminate value and the consequence
is undefined behaviour.


Very good eye. I set tm_isdst to -1 each time (as I have no idea of DST on
any of these dates) and it seemed to work great.

Now, I was looking at the next reply from Al Bowers' and he mentioned that
my assumption of time_t calendar time as being actual seconds, my be an
incorrect assumption.

What I have been doing is getting the calendar time from broken time,
subtracting so many seconds from it (which is actually equivalent to 1 to 59
minutes) and converting the calendar time back to broken time. The reason I
do it this way is so that if it's Jan 1, 2000 at 00:00, subtracting 45
minutes (45*60 seconds) from this gets me an entirely new date, not just a
change in minutes.

Is this approach ok, or will I run into any future undefined behaviour?

Thanks so much for the help! I very much appreciate it!

Best regards,
John
Nov 14 '05 #6
> I see what you mean. My problem is that I am actually trying to adjust
minutes (from 1 to 59) and subtract the CHG_TIME number from the number of
minutes. However, if my date is Jan 1, 2000 at 00:00, by changing the
minutes, the hour, day, month, & year all have to change as well. That's
why I thought if I could get the time_t value as calendar time, subtract
from it number of minutes*60 (the correct number of seconds), and use
mktime(), I would get the adjusted date (the date-CHG_TIME).
sorry, that should read "and use gmtime(), I would get the adjusted date..."

I was under the assumption that the calendar time is the number of seconds
since Jan 1, 1970, and my subtracting so many seconds from that value and
calling mktime(), I would get an earlier date.
here too. "...and calling gmtime(), i would get an earlier date".

sorry for the confusion.

So if I were to adjust the broken time instead of the calendar time, how
would I handle the change in minutes, hour, date, month year without having to do it manually?

Thanks so much for the help! I really appreciate it!

John



Another problem: check your return values.
You did not check the return value
of your mktime function. time_t's range of dates is limited.
Function mktime will return (time_t)-1 should it be uncapable
of representing that date. I can't be sure, but the values
you are getting in the range of 4000000000 may be result of
function mktime returning a (time_t)-1 value.

An example:

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

time_t AdjustTime(time_t tvalue, int secs)
{
struct tm *tp;
time_t ret;

if((ret = (tvalue != (time_t)-1)))
{
tp = localtime(&tvalue);
if(secs > INT_MAX - tp->tm_sec)
ret = (time_t)-1;
else
{
tp->tm_sec+=secs;
tp->tm_isdst = -1;
ret = mktime(tp);
}
}
return ret;
}

int main(void)
{
time_t date;
struct tm t;

/* make a time_t value for 25DEC2005 12:00:00 */
t.tm_year = 2005-1900;
t.tm_mon = 11;
t.tm_mday = 25;
t.tm_hour = 12;
t.tm_min = t.tm_sec = t.tm_isdst = 0;

if((date = mktime(&t)) == (time_t)-1)
puts("Time is not available");
else
{
printf("date represents %s"
"Attemping to subtract 60 secs\n",ctime(&date));
if((date = AdjustTime(date, -60)) != (time_t)-1)
printf("The new date is %s",ctime(&date));
else puts("Time for the new date is unavailable");
}
return 0;
}
--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/


Nov 14 '05 #7


John Hanley wrote:
The code is not complete and it is not easy to follow the logic.
But I see you are making some errors. Apparently, you are
assuming that type time_t is type long representing seconds.

you're right, that was what I was assuming.

Standard C does not specify this to be fact. The Standard
only specifies that time_t be an arithmetic time capable of
representing time. And, it does not specify anything on
its instrumentality. So, to be portable, the code must not
assume the type to be type long and the values representing
seconds. To get around this, Standard C provides functions
that will allow you to manipulate time. So, to correct
your function adjust_time, you will need to convert the
time_t value to broken down time and the adjust the struct
member tm_sec in the number of seconds. Then call function
mktime to generate a new time_t value.

I see what you mean. My problem is that I am actually trying to adjust
minutes (from 1 to 59) and subtract the CHG_TIME number from the number of
minutes. However, if my date is Jan 1, 2000 at 00:00, by changing the
minutes, the hour, day, month, & year all have to change as well. That's
why I thought if I could get the time_t value as calendar time, subtract
from it number of minutes*60 (the correct number of seconds), and use
mktime(), I would get the adjusted date (the date-CHG_TIME).

I was under the assumption that the calendar time is the number of seconds
since Jan 1, 1970, and my subtracting so many seconds from that value and
calling mktime(), I would get an earlier date.


You should not make this assumption if you are writing portable Standard
C code.
So if I were to adjust the broken time instead of the calendar time, how
would I handle the change in minutes, hour, date, month year without having
to do it manually?
You will need to update the members in the struct tm. When you call
function mktime all values will be normalized and put in range. For
example you can substract 2 min by just modifying the tm_sec -= 120
or you can substract from tm_min -= 2. Both are valid.

Example:

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

int main(void)
{
time_t date;
struct tm t;

/* make a time_t value for 25DEC2005 12:00:00 */
t.tm_year = 2005-1900;
t.tm_mon = 11;
t.tm_mday = 25;
t.tm_hour = 12;
t.tm_min = t.tm_sec = t.tm_isdst = 0;

/* substract 120 sec (2 minutes) */
if((date = mktime(&t)) != (time_t)-1)
{
printf("The Date is: %s",ctime(&date));
t.tm_sec -= 120;
t.tm_isdst = -1;
if((date = mktime(&t)) != (time_t)-1)
{
printf("Subst. 2min: %s",ctime(&date));
t = *gmtime(&date);
t.tm_isdst = -1;
if((date = mktime(&t)) != (time_t)-1)
printf("GMT date is: %s",ctime(&date));
}
else puts("Time unavailable");
}
else puts("Time unavailable");
return 0;
}

Thanks so much for the help! I really appreciate it!

John

Another problem: check your return values.
You did not check the return value
of your mktime function. time_t's range of dates is limited.
Function mktime will return (time_t)-1 should it be uncapable
of representing that date. I can't be sure, but the values
you are getting in the range of 4000000000 may be result of
function mktime returning a (time_t)-1 value.

An example:

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

time_t AdjustTime(time_t tvalue, int secs)
{
struct tm *tp;
time_t ret;

if((ret = (tvalue != (time_t)-1)))
{
tp = localtime(&tvalue);
if(secs > INT_MAX - tp->tm_sec)
ret = (time_t)-1;
else
{
tp->tm_sec+=secs;
tp->tm_isdst = -1;
ret = mktime(tp);
}
}
return ret;
}

int main(void)
{
time_t date;
struct tm t;

/* make a time_t value for 25DEC2005 12:00:00 */
t.tm_year = 2005-1900;
t.tm_mon = 11;
t.tm_mday = 25;
t.tm_hour = 12;
t.tm_min = t.tm_sec = t.tm_isdst = 0;

if((date = mktime(&t)) == (time_t)-1)
puts("Time is not available");
else
{
printf("date represents %s"
"Attemping to subtract 60 secs\n",ctime(&date));
if((date = AdjustTime(date, -60)) != (time_t)-1)
printf("The new date is %s",ctime(&date));
else puts("Time for the new date is unavailable");
}
return 0;
}
--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/



--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #8
On Sat, 12 Feb 2005 10:00:16 -0700, John Hanley
<ha****@ualberta.ca> wrote:
Very good eye. I set tm_isdst to -1 each time (as I have no idea of DST on
any of these dates) and it seemed to work great.
If you want it to assume local time, that is the correct thing to do.
To assume GMT (UT) set that field to zero (if you are manipulating dates
it is easier in GMT, convert to and from local time only when doing I/O).
Now, I was looking at the next reply from Al Bowers' and he mentioned that
my assumption of time_t calendar time as being actual seconds, my be an
incorrect assumption.
Correct. It could be a floating point number of nanofortnights since the
Big Bang for all you know. The only thing guaranteed is that (time_t)-1
is an error value. It might not even be a linear representation, it
could use bit fields for years, months, days, hours, minutes, seconds
etc. (like the MSDOS filetimes did). The function difftime() will do
whatever magic is needed to return the difference of two time_t values
as a double number of seconds, localtime() and gmtime() will break it
down into the structure, and mktime() will create a time_t from the
structure.
What I have been doing is getting the calendar time from broken time,
subtracting so many seconds from it (which is actually equivalent to 1 to 59
minutes) and converting the calendar time back to broken time. The reason I
do it this way is so that if it's Jan 1, 2000 at 00:00, subtracting 45
minutes (45*60 seconds) from this gets me an entirely new date, not just a
change in minutes.

Is this approach ok, or will I run into any future undefined behaviour?


It will probably work until something changes. It is, however undefined
in the C standard (IIRC POSIX.1 defines it for systems which comply with
that standard).

The correct way to manipulate times is to use the broken-down structure,
mess about with the fields and make that back into a time_t using
mktime(). For instance, to get the time 2:23:45 from now use:

time_t now = time(NULL);
time_t then;
struct tm tt = *gmtime(&now);
tt.tm_hour += 2;;
tt.tm_min += 23;
tt.tm_sec += 45;
then = mktime(&tt);

(that's a snippet, not a complete program -- some of the pedants will
complain about not including headers and the like if I don't say that).

Unfortunately, the C standard doesn't say anything about the allowable
ranges of the fields, except that they are of type int and the normal
ranges are what you would expect. In particular, it doesn't say whether
negative values have the correct effect, so while adding to times is no
problem reducing them could be undefined...

Chris C
Nov 14 '05 #9


Chris Croughton wrote:
On Sat, 12 Feb 2005 10:00:16 -0700, John Hanley
What I have been doing is getting the calendar time from broken time,
subtracting so many seconds from it (which is actually equivalent to 1 to 59
minutes) and converting the calendar time back to broken time. The reason I
do it this way is so that if it's Jan 1, 2000 at 00:00, subtracting 45
minutes (45*60 seconds) from this gets me an entirely new date, not just a
change in minutes.

Is this approach ok, or will I run into any future undefined behaviour?

It will probably work until something changes. It is, however undefined
in the C standard (IIRC POSIX.1 defines it for systems which comply with
that standard).

The correct way to manipulate times is to use the broken-down structure,
mess about with the fields and make that back into a time_t using
mktime(). For instance, to get the time 2:23:45 from now use:

time_t now = time(NULL);
time_t then;
struct tm tt = *gmtime(&now);
tt.tm_hour += 2;;
tt.tm_min += 23;
tt.tm_sec += 45;
then = mktime(&tt);

(that's a snippet, not a complete program -- some of the pedants will
complain about not including headers and the like if I don't say that).

Unfortunately, the C standard doesn't say anything about the allowable
ranges of the fields, except that they are of type int and the normal
ranges are what you would expect. In particular, it doesn't say whether
negative values have the correct effect, so while adding to times is no
problem reducing them could be undefined...


No. What the Standard says is that function mktime will bring
all values into range. For example the range for struct tm member
tm_sec is 0-59. If tm_sec has the value of say -69 the function
mktime will bring tm_sec into range by subtracting 1 from tm_min.
And on up the ladder, if necessary, until finally tm_mon and
tm_year are determined. Then tm_wday and tm_yday components of the
struct are set appropriately. I would think that a Standard C
that would allow you to add to a time but make reducing it undefined
would be unwise.

--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #10
On Sat, 12 Feb 2005 10:11:09 -0700, John Hanley wrote:
I see what you mean. My problem is that I am actually trying to adjust
minutes (from 1 to 59) and subtract the CHG_TIME number from the number of
minutes. However, if my date is Jan 1, 2000 at 00:00, by changing the
minutes, the hour, day, month, & year all have to change as well. That's
why I thought if I could get the time_t value as calendar time, subtract
from it number of minutes*60 (the correct number of seconds), and use
mktime(), I would get the adjusted date (the date-CHG_TIME).


sorry, that should read "and use gmtime(), I would get the adjusted date..."


Normally you would use localtime(). Note that mktime() works from local
time, not UTC.

Lawrence
Nov 14 '05 #11

"Al Bowers" <xa******@rapidsys.com> wrote in message
news:37*************@individual.net...


John Hanley wrote:
I created a function that breaks down a date into broken down time, I
subtract a certain number of seconds from that, then use mktime() to
recompute the calendar time.

It works basically except every so often, I get the date 060207 (Feb 7,
2006) which is obviously not correct. When it does this it always gives me this date.

I tracked it down to my mktime() call, when I get to a certain date, mktime returns a number in 4000000000, when it should return a number in
1000000000. But I am not sure why. The variable in my tm struct all have the correct date, but mktime returns this.

It is happening to me when the date I am changing is: 040727 but it has done this on others as well.

I am thinking that something goes wrong in mktime() to cause it to return some default number. Perhaps something wrong in one of my time_broken
members and then it gets past to mktime?

Suggestions? Thanks a bunch!

Here's my code:


The code is not complete and it is not easy to follow the logic.
But I see you are making some errors. Apparently, you are
assuming that type time_t is type long representing seconds.
Standard C does not specify this to be fact. The Standard
only specifies that time_t be an arithmetic time capable of
representing time. And, it does not specify anything on
its instrumentality. So, to be portable, the code must not
assume the type to be type long and the values representing
seconds. To get around this, Standard C provides functions
that will allow you to manipulate time. So, to correct
your function adjust_time, you will need to convert the
time_t value to broken down time and the adjust the struct
member tm_sec in the number of seconds. Then call function
mktime to generate a new time_t value.


Ok. So I tried this and after calling mktime, I then call gmtime to convert
the (normalized) calendar time back into broken time. I need the broken
time because I need the values of month, day, year, etc each separately. So
I created a test program as follows. Here I am subtracting minutes (as my
program needs to subtract 0-59 minutes from the date):

eg:

struct tm time_broken; /* time in broken time */
time_t time_calendar=0; /* calendar time as a long int */

/* create the struct tm */
time_broken.tm_sec=0;
time_broken.tm_min=0;
time_broken.tm_hour=0;
time_broken.tm_mday=1;
time_broken.tm_mon=0;
time_broken.tm_year=104; /* years since 1900 */
time_broken.tm_isdst=-1;

time_broken.tm_min=time_broken.tm_min-45;

time_calendar=mktime(&time_broken);

time_broken=*(gmtime(&time_calendar));

printf("%s\n",asctime(&time_broken));

and I get the correct date.

Am I making any incorrect assumptions here? Will this work ok?

Thanks a bunch for the help!

John
Nov 14 '05 #12


John Hanley wrote:

Ok. So I tried this and after calling mktime, I then call gmtime to convert
the (normalized) calendar time back into broken time. I need the broken
time because I need the values of month, day, year, etc each separately. So
I created a test program as follows. Here I am subtracting minutes (as my
program needs to subtract 0-59 minutes from the date):

eg:

struct tm time_broken; /* time in broken time */
time_t time_calendar=0; /* calendar time as a long int */

/* create the struct tm */
time_broken.tm_sec=0;
time_broken.tm_min=0;
time_broken.tm_hour=0;
time_broken.tm_mday=1;
time_broken.tm_mon=0;
time_broken.tm_year=104; /* years since 1900 */
time_broken.tm_isdst=-1;

time_broken.tm_min=time_broken.tm_min-45;

time_calendar=mktime(&time_broken);

Just a reminder that the return value of mktime should
be checked. The range of times on many implementations
is limited. Therefore, it is not unusual for you to
encounter the (time_t)-1 return value indicating time
is not available for the arguments you supplied.
time_broken=*(gmtime(&time_calendar));

printf("%s\n",asctime(&time_broken));

--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #13
On Sat, 12 Feb 2005 23:33:50 -0500, Al Bowers <xa******@rapidsys.com>
wrote:
Chris Croughton wrote: <snip>
The correct way to [offset] times is to use the broken-down structure,
mess about with the fields and make that back into a time_t using
mktime(). For instance, to get the time 2:23:45 from now use:

time_t now = time(NULL);
time_t then;
struct tm tt = *gmtime(&now);
tt.tm_hour += 2;;
tt.tm_min += 23;
tt.tm_sec += 45;
then = mktime(&tt);

(that's a snippet, not a complete program -- some of the pedants will
complain about not including headers and the like if I don't say that).

Unfortunately, the C standard doesn't say anything about the allowable
ranges of the fields, except that they are of type int and the normal
ranges are what you would expect. In particular, it doesn't say whether
negative values have the correct effect, so while adding to times is no
problem reducing them could be undefined...


No. What the Standard says is that function mktime will bring
all values into range. For example the range for struct tm member


If the call is successful, yes. It (definitely) won't be if the
requested time is not representable in time_t, and it's not clear if
mktime() is allowed to fail in other cases that the implementor
decides are "too hard" -- the comments in the Olson public-domain
implementation imply to me that this might have happened.
tm_sec is 0-59. If tm_sec has the value of say -69 the function
mktime will bring tm_sec into range by subtracting 1 from tm_min.
Actually tm_sec is 0-60 to allow for (positive) leap seconds, which
are rarely if ever implemented. That is, leap seconds actually happen
(for now, there has been discussion of eliminating them) but (most?) C
implementations (and systems) just treat them as transient errors.
The only people I've heard of actually using them are the ones for
whom they were designed -- astronomers and space navigators, and their
only contact to most ordinary people, GPS.

Presumably you meant -60sec = -1min. -69sec = -2min leaving 51sec.
And on up the ladder, if necessary, until finally tm_mon and
tm_year are determined. Then tm_wday and tm_yday components of the
struct are set appropriately. I would think that a Standard C
that would allow you to add to a time but make reducing it undefined
would be unwise.


- David.Thompson1 at worldnet.att.net
Nov 14 '05 #14
Dave Thompson wrote:
<snip>
Actually tm_sec is 0-60 to allow for (positive) leap seconds, which
are rarely if ever implemented. That is, leap seconds actually happen
(for now, there has been discussion of eliminating them) but (most?) C
implementations (and systems) just treat them as transient errors.
The only people I've heard of actually using them are the ones for
whom they were designed -- astronomers and space navigators, and their
only contact to most ordinary people, GPS.


Is it your claim that astronomers don't have telephones, or that
they don't know how to use them?
Nov 14 '05 #15
Dave Thompson wrote:

No. What the Standard says is that function mktime will bring
all values into range. For example the range for struct tm member


If the call is successful, yes. It (definitely) won't be if the
requested time is not representable in time_t, and it's not clear if
mktime() is allowed to fail in other cases that the implementor
decides are "too hard" -- the comments in the Olson public-domain
implementation imply to me that this might have happened.

Yes, the Standard does not specify anthing on the resulting values of
the struct tm
members should and and when an implement of function mktime decides that
time is
not representable. The values may be changed or unchanged, in part or
in total.
tm_sec is 0-59. If tm_sec has the value of say -69 the function
mktime will bring tm_sec into range by subtracting 1 from tm_min.


Actually tm_sec is 0-60 to allow for (positive) leap seconds, which
are rarely if ever implemented. That is, leap seconds actually happen
(for now, there has been discussion of eliminating them) but (most?) C
implementations (and systems) just treat them as transient errors.
The only people I've heard of actually using them are the ones for
whom they were designed -- astronomers and space navigators, and their
only contact to most ordinary people, GPS.

I believe the Standard specifies the representable range as 0-59. I do
not recall any mention
of leap seconds in the Standard. Perhaps you are referring to an
implement that extends
the Standard. Unfortumately, I will be away from headquarters for a
week, and not have
access to the Standard document. Please correct me if I am wrong.
Presumably you meant -60sec = -1min. -69sec = -2min leaving 51sec.

Yes, the result to bring tm_sec into range would be a decrease of 2 in
tm_min and an
increase of 120 in tm_sec to bring it's value in range at 51 (120-69).
And on up the ladder, if necessary, until finally tm_mon and
tm_year are determined. Then tm_wday and tm_yday components of the
struct are set appropriately. I would think that a Standard C
that would allow you to add to a time but make reducing it undefined
would be unwise.



Al Bowers
Nov 14 '05 #16


Al Bowers wrote:
Dave Thompson wrote:


No. What the Standard says is that function mktime will bring
all values into range. For example the range for struct tm member

If the call is successful, yes. It (definitely) won't be if the
requested time is not representable in time_t, and it's not clear if
mktime() is allowed to fail in other cases that the implementor
decides are "too hard" -- the comments in the Olson public-domain
implementation imply to me that this might have happened.

Yes, the Standard does not specify anthing on the resulting values of
the struct tm
members should and and when an implement of function mktime decides that
time is
not representable. The values may be changed or unchanged, in part or
in total.
tm_sec is 0-59. If tm_sec has the value of say -69 the function
mktime will bring tm_sec into range by subtracting 1 from tm_min.

Actually tm_sec is 0-60 to allow for (positive) leap seconds, which
are rarely if ever implemented. That is, leap seconds actually happen
(for now, there has been discussion of eliminating them) but (most?) C
implementations (and systems) just treat them as transient errors.
The only people I've heard of actually using them are the ones for
whom they were designed -- astronomers and space navigators, and their
only contact to most ordinary people, GPS.

I believe the Standard specifies the representable range as 0-59. I do
not recall any mention
of leap seconds in the Standard. Perhaps you are referring to an
implement that extends
the Standard. Unfortumately, I will be away from headquarters for a
week, and not have
access to the Standard document. Please correct me if I am wrong.


Read it just this weekend in C Unleashed, so I am sure the range
is 0..60; however we can have the look at the standard:

"7.23.1 Components of time
.....
4 The range and precision of times representable in clock_t and time_t
are implementation-defined. The tm structure shall contain at least the
following members, in any order. The semantics of the members and their
normal ranges are expressed in the comments.265)
int tm_sec; // seconds after the minute [0, 60]
int tm_min; // minutes after the hour [0, 59]
int tm_hour; // hours since midnight [0, 23]
int tm_mday; // day of the month [1, 31]
int tm_mon; // months since January [0, 11]
int tm_year; // years since 1900
int tm_wday; // days since Sunday [0, 6]
int tm_yday; // days since January 1 [0, 365]
int tm_isdst; // Daylight Saving Time flag

__________________________________________________ ______________________
265) The range [0, 60] for tm_sec allows for a positive leap second.
"

Cheers
Michael
--
E-Mail: Mine is a gmx dot de address.

Nov 14 '05 #17

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Bengt Richter | last post by:
Python 2.3.2 (#49, Oct 2 2003, 20:02:00) on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import time >>> time.mktime((1969, 12, 31, 17, 0, 0, 0, 0, 0))...
2
by: Florian Quetting | last post by:
Hi, I'm getting mad with following problem: The code compiles, but I always get a segfault and I don't have any clue why. I can't see any differences in my way of calling mktime and others. ...
4
by: McBooCzech | last post by:
Hi, on Linux (Fedora FC4) and Python 2.4.1 I am trying to know the time delta in seconds between two times given in the HHMMSS format. My code looks like: import datetime, time...
1
by: KW | last post by:
Hi all, Appreciate if someone can help me out on this. Currently, I have a tm structure holding information of the UTC time, which is very likely to be in the past, meaning not the current...
3
by: JJ | last post by:
Here's the code. $link="http://xbox360cheat.org"; $close_date=$_POST; #last content change check if ($close_date == 0) $close_date = date("Y-m-d H:m:s", mktime(12, 0, 0, date("m"), date...
2
by: John Hanley | last post by:
I am getting some inconsistencies with mktime(). I allocate memory for my struct tm early in my program, and assign only *some* of the member variables. t->tm_sec=s; t->tm_min=m;...
1
osward
by: osward | last post by:
Hi everyone, Background 1. I have a table that consits 400+ rows of data and is growing by day. The table already has paging links at the bottom but I restricted to display rows of data only >=...
2
by: pedalpete | last post by:
I've got this error which keeps popping up, but I can't seem to figure out why. The error reads ' A non well formed numeric value encountered in filename on line <b>198</b>'. the lines...
5
by: Robert Latest | last post by:
Here's what happens on my Windows machine (Win XP / Cygwin) at work. I've googled a bit about this problem but only found references to instances where people referred to dates before the Epoch. ...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.