Subject: interval rounding
From: olded@ix.netcom.com(Ed Schaefer)
Newsgroups: comp.databases.informix
Date: 25 Oct 1996 05:27:42 GMT

# There has been some discussion of rounding an interval
# to the nearest 1/4 hr in 4GL.  This should do it.  I haven't
# tested it as thoroughly as I might have, but I haven't
# seen problems.  Be advised that the interval is defined
# as day to minute.  Change this through out the functions
# if doesn't suit your needs.

# Let me know if anyone sees a problem.

# regards

# ed 
# schaefer
main
define dt1, dt2 datetime year to minute,
       inter, rnd_int interval day to minute,
       err_found smallint

let dt1 = "1996-10-24 18:57"
let dt2 = "1996-10-24 19:50"

let inter = dt2 - dt1 # original interval
# round factor is generally 1, 6, or 15
# rnd_type is Up, Down, or Normal
call rnd_interval(inter, 15, "U") returning rnd_int, err_found
display rnd_int # rounded interval

end main

#######################################################################
#
function rnd_interval(inter, rnd_factor, rnd_type)
#######################################################################
#
# This function rounds the interval inter based upon the rnd_factor 
# and the rnd_type.  The rnd factor is generally:
#  1 for no rounding
#  6 for 6 minute rounding
#  15 for 15 minute rounding
#  rnd_type is: "U"p, "D"own, or "N"ormal.  Typically you pick up or
down
# It passes back the rounded interval and 0 for no error and 1 for a
# null interval

    define inter interval day to minute,
           rnd_factor smallint,
           rnd_type char(1),
           h_min smallint,
           x smallint

    if inter is null
    then # error condition
       return inter, 0
    end if
    if rnd_factor is null or rnd_factor = 0 
    then
        let rnd_factor = 1
    end if

    if rnd_factor = 1
    then # nothing to round
        return inter, 0
    end if
   
    # get the total number of minutes of the interval
    let h_min = return_min(inter) 
    let h_min = h_min mod 60 # strip off the hours
    if h_min = 0
    then # if at the top of the hour then no rounding needed.
        return inter, 0
    end if

    # Determine the number of minutes relative to the rnd_factor
    let x = h_min mod rnd_factor
    if x = 0
    then # nothing to round
        return inter, 0
    end if

    # Check the rounding type 
    case
       when rnd_type = "D"
           # Round to prev factor.
           let inter = inter - x units minute
       when rnd_type = "U"
           # Round to next factor.
           let inter = inter - x units minute + rnd_factor units minute
       otherwise
           # Normal rounding
           if (x * 2) >= rnd_factor 
           then
               let inter = inter - x units minute + rnd_factor units
minute
           else
               let inter = inter - x units minute
           end if
    end case

    return inter, 0

end function

#######################################################################
###
function return_min(dinter)
#######################################################################
###
# This function takes an interval string and then returns the number of
# minutes.  This is only works if the interval is defined day-to-minute

    define dinter interval day to minute,
           dstring char(14),
           dday char(4),
           dhr  char(2),
           dmin  char(2),
           aday smallint,
           ahr smallint,
           amin smallint,
           totmin integer
    
    let dstring = dinter
    #do the day
    let dday[1] = dstring[1]
    let dday[2] = dstring[2]
    let dday[3] = dstring[3]
    #do the time
    let dhr[1] = dstring[5]
    let dhr[2] = dstring[6]
    let dmin[1] = dstring[8]
    let dmin[2] = dstring[9]

    #change data type
    let aday = dday
    let ahr = dhr
    let amin = dmin

    #if negative interval
    if dday[1] = "-" or 
       dday[2] = "-" or
       dday[3] = "-"
    then
       let ahr = ahr * (-1)
       let amin = amin * (-1)
    end if
    let totmin = (aday * 24 * 60) + (ahr * 60) + amin

    return totmin
end function
