Take another look and distinguish carefully between 'struct' and 'union'.
I suggest that you don't do anything with the struct, and instead just work with the 64-bit time_t value returned by now().
The union allows me to tell the compiler to force the time_t value and the struct containing the two longs to occupy the same memory space. That lash-up allows access to the entire 64-bit time as a single unsigned long long variable, or to access either the upper or lower 32-bit value as an unsigned long, which makes adjustment very much easier when whichever time source overflowed.
Whether anything is "wasted" depends on what you need. The minimal code I posted is for people to hack on to suit their own needs. I was fairly well pleased to shrink the executable part as far as I did - and I'll be really pleased if anyone can show me how to shrink it further.