February 04, 2010 by Solorbob If one had two time structures and wanted to see if timeA was greater or less than timeB, how would one go about it? Below is the structure def. typedef struct { // structure for keeping time data ``````int seconds; int minutes; int hours; `````` }time; . . . time timeA,timeB; thanks, Shawn I'm quite a noob for writing in C, but if it's simply to check if timeA is greater than timeB, I would do sometime like this: ``````int A_bigger_B; if (timeA.hours>timeB.hours){ A_bigger_B=1; } elseif (timeA.minutes>timeB.minutes) { A_bigger_B=1; } elseif (timeA.seconds>timeB.seconds) { A_bigger_B=1; else { A_bigger_B=0; } `````` Warning, it doesn't check if there is an equality. Frozenlock If timeA is 4hr 30min and timeB is 5hr 20min, the first "if" will be skipped, but it will go into the second "if" because timeA.minutes is greater than timeB.minutes, so that's not quite right. ``````int sign = timeA.hours - timeB.hours; if (sign == 0) { sign = timeA.minutes - timeB.minutes; if (sign == 0) sign = timeA.seconds - timeB.seconds; } `````` I think that should work. Sign will be positive if A>B, negative if A shows you're right about the sizeof(int). If the overflow issue is relevant for this use, the basic concept still works. Just replace int with long int, unsigned long int, or if portability is required, a type that's explicit about how many bits it needs such as int32_t or uint32_t. Thanks. I'll keep the overflow in mind while making the changes. If you have the luxury of modifying the declaration of type "time", you could rewrite it into something more suitable for comparison; for example, (ab)using the fact that 16-bit AVRs are little-endian: ``````typedef union { struct { unsigned char s, m, h; } access; unsigned long value; } time_t; /* you can declare type_t variables and zero-initialize them at the same time, which is better than initializing them in the code block by writing t1.value = t2.value = 0; */ time_t t1 = {0}, t2 = {0}; // ... t1.access.h = 1; t1.access.m = 10; t1.access.s = 10; t2.access.h = 2; t2.access.m = 5; t2.access.s = 5; // comparing t1.value and t2.value gives the result if (t1.value < t2.value) ; // t1 was before t2 else if (t1.value > t2.value) ; // t1 was after t2 else ; // t1 and t2 mark the same point in time `````` NB. this works only on little-endian architectures, so 16-bit AVR (not AVR32 which is big-endian!) and x86 are both fine. For big-endianness you'd reverse the order of declarations inside the time_t.access struct, having hours up front and seconds at the end. Needless to say, use this approach only if you are 100% certain you will never ever want to port the code to another platform. To wrap things up, here's a nifty function from Jan Wolter's UNIX Incompatibility Notes, showing how to determine endianness during runtime: ``````int am_big_endian() { long one = 1; return !(*((char *)(&one))); } `````` HTH, Zoran Please replace all references to "16-bit AVR" with "8-bit AVR" in the above post. The code as shown would fail to work on a pure 16-bit architecture, anyway. :)