把时间存储到单个数字中与把日期存储到单个数字中是类似的,因此,你可以先阅读一下13.1。另一方面,这两者之间也有差别。
首先,你应该注意到,一天中的时间比一年中的日期有更强的“确定性”。你知道一分钟内有多少秒,一小时内有多少分,一天内有多少小时。这种确定性使时间处理起来更容易,而且不容易出错。
在选择把时间转换为数字的方法时,你最好遵循下面这些原则:
如果你已经阅读了13.1,你可能会认为处理这个问题的一个好办法就是用位域来表示时间。这确实是一个不错的办法,有其巧妙之处。请看下面这个把时间表示为一个整数的程序:
/*
* The bit field structures for representing time
*/
typedef struct
{
unsigned int Hour : 5;
unsigned int Minute :6;
} TimeType;
typedef union
{
TimeType time;
int Number;
} TimeConverter;
/*
* Convert time to a number, returning zero when the values are
* out of range.
*/
int TimeToNumber( int Hour, int Minute)
{
TimeConverter convert;
if (Hour<l || Hour>24 || Minute< 1 || Minute>60)
return 0;
convert, time. Hour = Hour;
convert, time. Minute = Minute;
return convert. Number+ 1;
}
/*
* Convert a number back into the two time
* elements that compose it.
*/
void NumberToTime( int Number, int *Hour, int * Minute)
{
TimeConverter convert;
convert. Number = Number - 1;
* Hour = convert. time. Hour;
* Minute = convert. time. Minute;
}
/*
* A main routine that tests everything to
* ensure its proper functioning.
*/
main()
{
int Number, Hour, Minute;
Hour=13;
Minute = 13;
Number = TimeToNumber( Hour, Minute);
NumberToTime( Number, &Hour, &Minute) ;
printf( "The time after conversion is %d:%d. \n" , Hour, Minute);
}
在时间表示中加入秒是很容易的,你只需在TimeType结构中加入一个秒域,并在每个转换函数中多加一个参数。
但是,假设你想把转换所得的数字用作时钟,让它整天“滴答滴答”地走个不停,你应该怎样做呢?如果用位域来完成这项任务,你就先需要把数字转换为位域,然后增加秒值,并检测秒值是否达到了60;如果秒值达到了60,你还需要增加分值,并再次检测分值是否达到了60……。这个过程太繁琐了!
这里的问题是:TimeType结构中的各个成员并不是刚好能纳入一个位域——它们的上限临界值并不是2的幂。因此,用数学的方法表示时间更好。这做起来相当简单,你可以用从当天开始时到当天某一点为止所度过的秒(或分)数来表示该点的时间。如果你用这种方法表示时间,那么在相应的数字上加1就相当于在时间上加1秒(或分)。下面的程序就是用这种方法表示时间的:
# include <stdio. h>
# include <stdlib. h>
/*
* A subroutine to convert hours and minutes into an
* integer number. This does not checking for the sake
* of brevity (you've seen it done before!).
*/
int TimeToNumber(int Hours, int Minutes)
{
return Minutes+ Hours * 60;
}
/*
* Convert an integer to hours and minutes.
*/
void NumberToTimeC int Number, int * Hours, int * Minutes)
{
* Minutes = Number % 60;
* Hours = Number / 60;
}
/*
* A quickie way to show time.
*/
void ShowTime(int Number)
{
int Hours, Minutes;
NumberToTimeC Number, &Hours, &Minutes);
printf("%02d:%02d\n", Hours, Minutes);
}
/*
* A main loop to test the salient features of the time class.
*/
main()
{
int Number, a;
Number = TimeToNumber(9,32);
printf("Time starts at :%d" , Number);
ShowTime(Number);
/*
* Assure yourself that minutes are added correctly.
* /
for( a = 0; a<10; + +a)
{
printf( "After 32 minutes :");
Number + = 32; / * Add 32 minutes to the time. * /
ShowTime(Number);
}
}
这个程序提供了一种更好的表示时间的方法。它容易操作,并且更为紧凑。它的代码还可以进一步压缩,加入秒的表示留给读者作为练习。
这种格式类似于C函数timelocal()和timegm()所使用的格式,这些函数都可以从任意给定的时间/日期开始计算秒数。只要对本章所提供的时间和日期处理程序稍作修改,你就可以使用这些程序了,而且还可以使用你自己定义的时间格式。