+ /* Add relative hours, minutes, and seconds. Ignore leap seconds;
+ i.e. "+ 10 minutes" means 600 seconds, even if one of them is a
+ leap second. Typically this is not what the user wants, but it's
+ too hard to do it the other way, because the time zone indicator
+ must be applied before relative times, and if mktime is applied
+ again the time zone will be lost. */
+ {
+ long int sum_ns = pc.seconds.tv_nsec + pc.rel_ns;
+ long int normalized_ns = (sum_ns % BILLION + BILLION) % BILLION;
+ time_t t0 = Start;
+ long int d1 = 60 * 60 * pc.rel_hour;
+ time_t t1 = t0 + d1;
+ long int d2 = 60 * pc.rel_minutes;
+ time_t t2 = t1 + d2;
+ long int d3 = pc.rel_seconds;
+ time_t t3 = t2 + d3;
+ long int d4 = (sum_ns - normalized_ns) / BILLION;
+ time_t t4 = t3 + d4;
+
+ if ((d1 / (60 * 60) ^ pc.rel_hour)
+ | (d2 / 60 ^ pc.rel_minutes)
+ | ((t1 < t0) ^ (d1 < 0))
+ | ((t2 < t1) ^ (d2 < 0))
+ | ((t3 < t2) ^ (d3 < 0))
+ | ((t4 < t3) ^ (d4 < 0)))
+ return false;
+
+ result->tv_sec = t4;
+ result->tv_nsec = normalized_ns;
+ return true;
+ }