/* * hms - calculate in hours, minutes, and seconds * * Copyright (C) 2010 Landon Curt Noll * * Calc is open software; you can redistribute it and/or modify it under * the terms of the version 2.1 of the GNU Lesser General Public License * as published by the Free Software Foundation. * * Calc is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General * Public License for more details. * * A copy of version 2.1 of the GNU Lesser General Public License is * distributed with calc under the filename COPYING-LGPL. You should have * received a copy with calc; if not, write to Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * @(#) $Revision: 30.2 $ * @(#) $Id: hms.cal,v 30.2 2010/09/02 06:14:16 chongo Exp $ * @(#) $Source: /usr/local/src/bin/calc/cal/RCS/hms.cal,v $ * * Under source code control: 2010/09/01 17:14:55 * File existed as early as: 2010 * * Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/ */ obj hms {hour, min, sec}; define hms(hour, min, sec) { local obj hms ans; /* return value */ /* default missing args to 0 */ if (isnull(sec)) { sec = 0; } if (isnull(min)) { min = 0; } /* load object */ ans.hour = hour; ans.min = min; ans.sec = sec; /* return properly formed object */ ans = fixhms(ans); return ans; } define hms_add(a, b) { local obj hms ans; /* return value */ /* initalize value to 1st arg */ if (istype(a, ans)) { /* 1st arg is hms object, load it */ ans.hour = a.hour; ans.min = a.min; ans.sec = a.sec; } else { /* 1st arg is not hms, assume scalar hours */ ans.hour = a; ans.min = 0; ans.sec = 0; } /* add value of 2nd arg */ if (istype(b, ans)) { /* 2nd arg is hms object, add it */ ans.hour += b.hour; ans.min += b.min; ans.sec += b.sec; } else { /* 2nd arg is not hms, add scalar hours */ ans.hour += b; } /* return normalized result */ ans = fixhms(ans); return ans; } define hms_neg(a) { local obj hms ans; /* return value */ /* negate argument */ if (istype(a, ans)) { /* 1st arg is hms object, load it */ ans.hour = -a.hour; ans.min = -a.min; ans.sec = -a.sec; } else { /* 2nd arg is not hms, negate scalar hours */ ans.hour = -a; ans.min = 0; ans.sec = 0; } /* return normalized result */ ans = fixhms(ans); return ans; } define hms_sub(a, b) { local obj hms ans; /* return value */ /* initalize value to 1st arg */ if (istype(a, ans)) { /* 1st arg is hms object, load it */ ans.hour = a.hour; ans.min = a.min; ans.sec = a.sec; } else { /* 1st arg is not hms, assume scalar hours */ ans.hour = a; ans.min = 0; ans.sec = 0; } /* subtract value of 2nd arg */ if (istype(b, ans)) { /* 2nd arg is hms object, subtract it */ ans.hour -= b.hour; ans.min -= b.min; ans.sec -= b.sec; } else { /* 2nd arg is not hms, subtract scalar hours */ ans.hour -= b; } /* return normalized result */ ans = fixhms(ans); return ans; } define hms_mul(a, b) { local obj hms ans; /* return value */ /* hms object multiplication */ if (istype(a, ans) && istype(b, ans)) { ans.hour = hms_abs(a) * hms_abs(b); ans.min = 0; ans.sec = 0; /* scalar multiplication */ } else if (istype(a, ans)) { ans.hour = a.hour * b; ans.min = a.min * b; ans.sec = a.sec * b; } else { ans.hour = b.hour * a; ans.min = b.min * a; ans.sec = b.sec * a; } /* return normalized result */ ans = fixhms(ans); return ans; } define hms_print(a) { local obj hms ans; /* temp object for hms type testing */ /* firewall - arg must be a hms object */ if (! istype(a, ans)) { quit "hms_print called with non hms object"; } /* print in hms form */ print a.hour : ':' : a.min : ':' : a.sec :; } define hms_abs(a) { local obj hms ans; /* temp object for hms type testing */ local hour; /* return scalar value */ /* firewall - just absolute value non hms objects */ if (! istype(a, ans)) { return abs(a); } /* compute hours */ hour = a.hour + a.min / 60 + a.sec / 3600; /* return hours */ return hour; } define hms_norm(a) { local obj hms ans; /* temp object for hms type testing */ local hour; /* hours */ /* firewall - arg must be a hms object */ if (! istype(a, ans)) { quit "hms_norm called with non hms object"; } /* square hours (norm is the square of absolute value */ hour = hms_abs(a); /* return hours */ return hour*hour; } define hms_test(a) { local obj hms ans; /* temp value */ /* firewall - arg must be a hms object */ if (! istype(a, ans)) { quit "hms_test called with non hms object"; } /* return false of non-zero */ ans = fixhms(a); if (ans.hour == 0 && ans.min == 0 && ans.sec == 0) { /* false */ return 0; } /* true */ return 1; } define hms_int(a) { local obj hms ans; /* return value */ /* firewall - arg must be a hms object */ if (! istype(a, ans)) { quit "hms_int called with non hms object"; } /* normalize the argument */ ans = fixhms(a); /* truncate to the nearest second */ ans.sec = int(ans.sec); /* return value to the nearest second */ return ans; } define hms_frac(a) { local obj hms ans; /* return value */ /* firewall - arg must be a hms object */ if (! istype(a, ans)) { quit "hms_frac called with non hms object"; } /* normalize the argument */ ans = fixhms(a); /* remove all but fractional seconds */ ans.hour = 0; ans.min = 0; ans.sec = frac(ans.sec); /* return value to the second fraction */ return ans; } define hms_rel(a,b) { local abs_a, abs_b; /* scalars of the arguments */ /* compute scalars of the arguments */ abs_a = hms_abs(a); abs_b = hms_abs(b); /* return the comparison */ return cmp(abs_a, abs_b); } define hms_cmp(a,b) { local abs_a, abs_b; /* scalars of the arguments */ /* compute scalars of the arguments */ abs_a = hms_abs(a); abs_b = hms_abs(b); /* return the equality comparison */ return (abs_a == abs_b); } define hms_inc(a) { local obj hms ans; /* return value */ /* increment a hms object */ if (istype(a, ans)) { ans = a; ++ans.sec; /* return normalized result */ ans = fixhms(ans); return ans; } /* increment a scalar */ return a+1; } define hms_dec(a) { local obj hms ans; /* return value */ /* decrement a hms object */ if (istype(a, ans)) { ans = a; --ans.sec; /* return normalized result */ ans = fixhms(ans); return ans; } /* decrement a scalar */ return a-1; } define fixhms(a) { local obj hms ans; /* temp value */ /* firewall */ if (! istype(a, ans)) { quit "attempt to fix a non hms object"; } /* force minutes to be intergral */ a.min += frac(a.hour) * 60; a.hour = int(a.hour); /* force hours to be intergral */ a.sec += frac(a.min) * 60; a.min = int(a.min); /* carry excess seconds into minutes */ a.min += a.sec // 60; a.sec %= 60; /* carry excess minutes into hours */ a.hour += a.min // 60; a.min %= 60; /* round hours by day */ a.hour %= 24; /* return normalized result */ return a; } if (config("resource_debug") & 3) { print "obj hms {hour, min, sec} defined"; }