+3  A: 

Here's a non-tested port of Steve Kass's solution to Informix.

Steve's solution itself is well tested under MS SQL Server. I like it better than my previous solutions because the conversion to am/pm time is exclusively done algebraically not requiring the help of any branching (with CASE statements and such).

Substitute the @milTime with column name if the numeric "military time" comes from the database. The @ variable is only there for test.

--declare @milTime int
--set @milTime = 1359
SELECT
  CAST(MOD((@milTime /100 + 11), 12) + 1 AS VARCHAR(2))
  ||':'
  ||SUBSTRING(CAST((@milTime%100 + 100) AS CHAR(3)) FROM 2 FOR 2)
  ||' '
  || SUBSTRING('ap' FROM (MOD(@milTime / 1200, 2) + 1) FOR 1)
  || 'm';

For reference here's my [fixed], CASE-based, solution for SQL Server

SELECT 
  CASE ((@milTime / 100) % 12)
      WHEN 0 THEN '12'
      ELSE CAST((@milTime % 1200) / 100 AS varchar(2))
  END 
  + ':' + RIGHT('0' + CAST((@milTime % 100) AS varchar(2)), 2)
  + CASE (@milTime / 1200) WHEN 0 THEN ' am' ELSE ' pm' END
mjv
concat = || for my informix.... i tried this and didn't work out... I'm still tinkering with it though
CheeseConQueso
@CheeseConQueso Yes, Informix has a different syntax. Also do see my edit with a new formula (I noted a bug for the times between 1200 and 1259)
mjv
I get sytax errors on these
CheeseConQueso
*even with the replacement of + with ||
CheeseConQueso
@Cheese See latest edits. I "ported" the snippet from Steve to Informix syntax. Should work as is or damn close.
mjv
% MODULUS is informix's kryptonite right now
CheeseConQueso
IDS 7.3x does not support CAST notation AFAIK. It does support modulus via the MOD(n,m) function.
Jonathan Leffler
cast works for me... see last sql stmt in edit of the question
CheeseConQueso
+3  A: 

mjv's second try still doesn't work. (For 0001 it gives 0:1 am, for example.)

Here's a T-SQL solution that should work better. It can be adapted to other dialects by using the appropriate syntax for concatenation and SUBSTRING.

It also works for the military time 2400 (12:00 am), which might be useful.

select
  cast((@milTime/100+11)%12+1 as varchar(2))
 +':'
 +substring(cast((@milTime%100+100) as char(3)),2,2)
 +' '
 +substring('ap',@milTime/1200%2+1,1)
 +'m';
Steve Kass
+1 for a purely algebraic solution (no branching: didn't like "my" CASE stmts). Also your solution properly handles the leading 0 in the minute part.
mjv
I don't think informix is having fun with the modulus operator
CheeseConQueso
+1  A: 

Not sure about informix, here's what I would do in Oracle (some examples, but untested as I'm at home):

  1. Turn integer into a string: To_Char (milTime), e.g. 1->'1', 545 -> '545', 1215 -> '1215'
  2. Make sure we always have a four character string: Right('0000'||To_Char(milTime), 4), e.g. 1-> '0001', 545 -> '0545', 1215 -> '1215'
  3. Turn into a datetime: To_Date (Right('0000'||To_Char(milTime), 4), 'HH24:MI')
  4. Output into desired format: To_Char(To_Date(..),'HH:MI AM')e.g. 1->'00:01 AM', 545 -> '05:45 AM', 1215 -> '12:15 PM'

Oracle's To_Date and To_Char are proprietary, but I'm sure that there are standard SQL or Informix functions that achieve the same result without having to resort to "calculations".

IronGoofy
There are equivalent functions in Informix - called TO_CHAR() and TO_DATE() but laden with Informix instead of Oracle semantics.
Jonathan Leffler
A: 

LONG-hand approach... but works

select  substr((mtg_rec.beg_tm-1200),0,1)||":"||substr((mtg_rec.beg_tm-1200),2,2)||" pm" beg_tm,
         substr((mtg_rec.end_tm-1200),0,1)||":"||substr((mtg_rec.end_tm-1200),2,2)||" pm" end_tm
    from    mtg_rec
    where   mtg_rec.beg_tm between 1300 and 2159
         and mtg_rec.end_tm between 1300 and 2159
    union
    select  substr((mtg_rec.beg_tm-1200),0,1)||":"||substr((mtg_rec.beg_tm-1200),2,2)||" pm" beg_tm,
         substr((mtg_rec.end_tm-1200),0,2)||":"||substr((mtg_rec.end_tm-1200),3,2)||" pm" end_tm
    from    mtg_rec
    where   mtg_rec.beg_tm between 1300 and 2159
         and mtg_rec.end_tm between 2159 and 2400
    union
    select  substr((mtg_rec.beg_tm-1200),0,2)||":"||substr((mtg_rec.beg_tm-1200),3,2)||" pm" beg_tm,
         substr((mtg_rec.end_tm-1200),0,2)||":"||substr((mtg_rec.end_tm-1200),3,2)||" pm" end_tm
         mtg_rec.days
    from    mtg_rec
    where   mtg_rec.beg_tm between 2159 and 2400
         and mtg_rec.end_tm between 2159 and 2400
    union
     select substr((mtg_rec.beg_tm),0,1)||":"||(substr((mtg_rec.beg_tm),2,2))||" am" beg_tm,
         substr((mtg_rec.end_tm),0,1)||":"||(substr((mtg_rec.end_tm),2,2))||" am" end_tm
         mtg_rec.days
    from    mtg_rec
    where   mtg_rec.beg_tm between 0 and 959
         and mtg_rec.end_tm between 0 and 959
    union
     select substr((mtg_rec.beg_tm),0,2)||":"||(substr((mtg_rec.beg_tm),3,2))||" am" beg_tm,
         substr((mtg_rec.end_tm),0,2)||":"||(substr((mtg_rec.end_tm),3,2))||" am" end_tm
         mtg_rec.days
    from    mtg_rec
    where   mtg_rec.beg_tm between 1000 and 1259
         and mtg_rec.end_tm between 1000 and 1259
    union
     select cast(beg_tm as varchar(4)),
         cast(end_tm as varchar(4))
    from    mtg_rec
    where   mtg_rec.beg_tm = 0
         and mtg_rec.end_tm = 0
    into temp time_machine with no log;
CheeseConQueso
there has to be a better way to do this with case'ing.... my result set comes out shorter than if I ignored the formatting.... wonder what the hell thats all about...
CheeseConQueso
That is ghastly - use the server to do the calculation and formatting for you, for pity's sake! That's why TO_CHAR() was added.
Jonathan Leffler
It also looks like your code won't handle times between midnight and 1 am correctly - those should appear as 12:01 am .. 12:59 am, not as 00:01 am .. 00:59 am.
Jonathan Leffler
Ghastly indeed... but I was just trying anything. I am going to check out your response now...
CheeseConQueso
+3  A: 

Please note that there is useful information at SO 440061 about converting between 12 hour and 24 hour notations for time (the opposite of this conversion); it isn't trivial, because 12:45 am comes half an hour before 1:15 am.

Next, please note that IDS version 7.31 finally reached its end of service on 2009-09-30; it is no longer a supported product.

You should be more precise with your version number; there are considerable differences between 7.30.UC1 and 7.31.UD8, for instance.

However, you should be able to use the TO_CHAR() function to format times as you need. Although this reference is to the IDS 11.50 Information Center, I believe that you will be able to use it in 7.31 (not necessarily in 7.30, but you should not have been using that for most of the last decade).

There is a '%R' format specifier for 24-hour time, it says. It also refers you to 'GL_DATETIME', where it says '%I' gives you the 12-hour time and '%p' gives you the am/pm indicator. I also found a 7.31.UD8 instance of IDS to validate this:

select to_char(datetime(2009-01-01 16:15:14) year to second, '%I:%M %p')
    from dual;

04:15 PM

select to_char(datetime(2009-01-01 16:15:14) year to second, '%1.1I:%M %p')
    from dual;

4:15 PM


I see from re-reading the question that you actually have SMALLINT values in the range 0000..2359 and need to get those converted. Often, I'd point out that Informix has a type for storing such values - DATETIME HOUR TO MINUTE - but I concede it occupies 3 bytes on disk instead of just 2, so it isn't as compact as a SMALLINT notation.

Steve Kass showed the SQL Server notation:

select
  cast((@milTime/100+11)%12+1 as varchar(2))
 +':'
 +substring(cast((@milTime%100+100) as char(3)),2,2)
 +' '
 +substring('ap',@milTime/1200%2+1,1)
 +'m';

The trick for getting the hour correct is neat - thanks Steve!

Translated into Informix for IDS 11.50, assuming that the table is:

CREATE TEMP TABLE times(begin_tm SMALLINT NOT NULL);

SELECT  begin_tm,
        (MOD(begin_tm/100 + 11, 12) + 1)::VARCHAR(2) || ':' ||
        SUBSTRING((MOD(begin_tm, 100) + 100)::CHAR(3) FROM 2) || ' ' ||
        SUBSTRING("ampm" FROM (MOD((begin_tm/1200)::INT, 2) * 2) + 1 FOR 2)
      FROM times
      ORDER BY begin_tm;

The SUBSTRING notation using FROM and FOR is standard SQL notation - weird, but so.

Example results:

     0    12:00 am 
     1    12:01 am 
    59    12:59 am 
   100    1:00 am  
   559    5:59 am  
   600    6:00 am  
   601    6:01 am  
   959    9:59 am  
  1000    10:00 am 
  1159    11:59 am 
  1200    12:00 pm 
  1201    12:01 pm 
  1259    12:59 pm 
  1300    1:00 pm  
  2159    9:59 pm  
  2200    10:00 pm 
  2359    11:59 pm 
  2400    12:00 am

Caution: the values 559-601 are in the list because I ran into a problem with rounding instead of truncation in the absence of the cast to integer.

Now, this was tested on IDS 11.50; IDS 7.3x won't have the cast notation. However, that isn't a problem; the next comment was going to deal with that...

As an exercise in how to write the expression in SQL without conditionals, etc, this is interesting, but if anyone wrote that more than once in an entire suite, I'd shoot them for lack of modularization. Clearly, this requires a stored procedure - and a stored procedure doesn't need the (explicit) casts or some of the other trickery, though the assignments enforce implicit casts:

CREATE PROCEDURE ampm_time(tm SMALLINT) RETURNING CHAR(8);
    DEFINE hh SMALLINT;
    DEFINE mm SMALLINT;
    DEFINE am SMALLINT;
    DEFINE m3 CHAR(3);
    DEFINE a3 CHAR(3);
    LET hh = MOD(tm / 100 + 11, 12) + 1;
    LET mm = MOD(tm, 100) + 100;
    LET am = MOD(tm / 1200, 2);
    LET m3 = mm;
    IF am = 0
    THEN LET a3 = ' am';
    ELSE LET a3 = ' pm';
    END IF;
    RETURN (hh || ':' || m3[2,3] || a3);
END PROCEDURE;

The Informix '[2,3]' notation is a primitive form of sub-string operator; primitive because (for reasons that still elude me) the subscripts must be literal integers (not variables, not expressions). It happens to work usefully here; in general, it is frustrating.

This stored procedure should work on any version of Informix (OnLine 5.x, SE 7.x, IDS 7.x or 9.x, 10.00, or 11.x) that you can lay hands on.

To illustrate the equivalence of (a minor variant on) the expression and the stored procedure:

SELECT  begin_tm,
        (MOD(begin_tm/100 + 11, 12) + 1)::VARCHAR(2) || ':' ||
        SUBSTRING((MOD(begin_tm, 100) + 100)::CHAR(3) FROM 2) ||
        SUBSTRING(' am pm' FROM (MOD((begin_tm/1200)::INT, 2) * 3) + 1 FOR 3),
        ampm_time(begin_tm)
      FROM times
      ORDER BY begin_tm;

Which produces the result:

     0  12:00 am        12:00 am
     1  12:01 am        12:01 am
    59  12:59 am        12:59 am
   100  1:00 am         1:00 am 
   559  5:59 am         5:59 am 
   600  6:00 am         6:00 pm 
   601  6:01 am         6:01 pm 
   959  9:59 am         9:59 pm 
  1000  10:00 am        10:00 pm
  1159  11:59 am        11:59 pm
  1200  12:00 pm        12:00 pm
  1201  12:01 pm        12:01 pm
  1259  12:59 pm        12:59 pm
  1300  1:00 pm         1:00 pm 
  2159  9:59 pm         9:59 pm 
  2200  10:00 pm        10:00 pm
  2359  11:59 pm        11:59 pm
  2400  12:00 am        12:00 am

This stored procedure can now be used multiple times in a single SELECT statement inside your ACE report without further ado.


[After comments from the original poster about not working...]

IDS 7.31 doesn't handle non-integer values passed to the MOD() function. Consequently, the divisions have to be stored in an explicit integer variable - thus:

CREATE PROCEDURE ampm_time(tm SMALLINT) RETURNING CHAR(8);
    DEFINE i2 SMALLINT;
    DEFINE hh SMALLINT;
    DEFINE mm SMALLINT;
    DEFINE am SMALLINT;
    DEFINE m3 CHAR(3);
    DEFINE a3 CHAR(3);
    LET i2 = tm / 100;
    LET hh = MOD(i2 + 11, 12) + 1;
    LET mm = MOD(tm, 100) + 100;
    LET i2 = tm / 1200;
    LET am = MOD(i2, 2);
    LET m3 = mm;
    IF am = 0
    THEN LET a3 = ' am';
    ELSE LET a3 = ' pm';
    END IF;
    RETURN (hh || ':' || m3[2,3] || a3);
END PROCEDURE;

This was tested on IDS 7.31.UD8 on Solaris 10 and worked correctly. I don't understand the syntax error reported; but there is an outside chance of there being a version dependency - it is always crucial to report version numbers and platforms just in case. Notice that I'm careful to document where various things worked; that isn't an accident, nor is it just fussiness -- it is based on many years of experience.

Jonathan Leffler
beg_tm not begin_tm.... but your pure sql version worked... im going to try and install the stored proc just for that ACE reporting... thanks, you remain insane
CheeseConQueso
can't get that proc to work... getting a 201 sytanx error on first line @ position 56 - "(" in char(8)
CheeseConQueso
Which version of IDS 7.3x do you have. The function compiles when I copy'n'paste from the answer into 7.31.UD8 on Solaris 10; I get an error -717 when running it though, identifying MOD() as the problem. Looking into that now...
Jonathan Leffler
OK - the problem appears to be that MOD(n,m) does not like a non-integer as an argument, but the division gives a decimal value.I'll work out how to tweak that in few minutes...
Jonathan Leffler
"(MOD(begin_tm/100 + 11, 12) + 1)::VARCHAR(2)" can be substituted with "cast((MOD(beg_tm/100 + 11, 12) + 1) as VARCHAR(2))".... but I couldn't cast the INT...
CheeseConQueso
nvm.... "SUBSTRING(' am pm' FROM (MOD(cast((beg_tm/1200) as INT), 2) * 3) + 1 FOR 3)" works
CheeseConQueso
ACE reports is too lazy to take either cast syntax btw
CheeseConQueso
Yes - ACE has a retrograde view of legitimate SQL syntax. I'd forgotten that would be a problem - sorry. Did you get the stored procedure to work? It is going to be the most reliable solution. If not, please (**please**!) identify your IDS (or is it SE?) version precisely.
Jonathan Leffler
IBM Informix Dynamic Server Version 10.00.FC9 ..... I don't know when they updated this, but I was unaware.... mustve been that service end date
CheeseConQueso
this stored proc took on a life of its own..... see http://stackoverflow.com/questions/1596189/sql-cant-create-an-informix-stored-procedure
CheeseConQueso
btw... what about a macro within ACE to handle this?
CheeseConQueso
Answer provided to alternative question. ACE doesn't have macros per se. I should have recognized the problem sooner - ISQL doesn't recognize stored procedure syntax. Sorry!
Jonathan Leffler
A: 
database SAMPLE end 

define 
variable hora char(8)    {variable which holds char string returned by the ace time}  
variable ftime char(7)   {variable which will hold formatted time string = HH:MM am/pm }
end

.
...SELECT data...
.

format

on every row
    let hora = time
    if hora[1,2] = "01" then
    begin
        let ftime[1,3] = " 1:"
        let ftime[4,5] = hora[4,5]
        let ftime[6,7] ="am"
    end

    if hora[1,2] = "02" then
    begin
        let ftime[1,3] = " 2:"
        let ftime[4,5] = hora[4,5]
        let ftime[6,7] ="am"
    end

    if hora[1,2] = "03" then
    begin
        let ftime[1,3] = " 3:"
        let ftime[4,5] = hora[4,5]
        let ftime[6,7] ="am"
    end

    if hora[1,2] = "04" then
    begin
        let ftime[1,3] = " 4:"
        let ftime[4,5] = hora[4,5]
        let ftime[6,7] ="am"
    end

    if hora[1,2] = "05" then
    begin
        let ftime[1,3] = " 5:"
        let ftime[4,5] = hora[4,5]
        let ftime[6,7] ="am"
    end

    if hora[1,2] = "06" then
    begin
        let ftime[1,3] = " 6:"
        let ftime[4,5] = hora[4,5]
        let ftime[6,7] ="am"
    end

    if hora[1,2] = "07" then
    begin
        let ftime[1,3] = " 7:"
        let ftime[4,5] = hora[4,5]
        let ftime[6,7] ="am"
    end

    if hora[1,2] = "08" then
    begin
        let ftime[1,3] = " 8:"
        let ftime[4,5] = hora[4,5]
        let ftime[6,7] ="am"
    end

    if hora[1,2] = "09" then
    begin
        let ftime[1,3] = " 9:"
        let ftime[4,5] = hora[4,5]
        let ftime[6,7] ="am"
    end

    if hora[1,2] = "10" then
    begin
        let ftime[1,3] = "10:"
        let ftime[4,5] = hora[4,5]
        let ftime[6,7] ="am"
    end

    if hora[1,2] = "11" then
    begin
        let ftime[1,3] = "11:"
        let ftime[4,5] = hora[4,5]
        let ftime[6,7] ="am"
    end

    if hora[1,2] = "12" then
    begin
        let ftime[1,3] = "12:"
        let ftime[4,5] = hora[4,5]
        let ftime[6,7] ="pm"
    end

    if hora[1,2] = "13" then
    begin
        let ftime[1,3] = " 1:"
        let ftime[4,5] = hora[4,5]
        let ftime[6,7] ="pm"
    end

    if hora[1,2] = "14" then
    begin
        let ftime[1,3] = " 2:"
        let ftime[4,5] = hora[4,5]
        let ftime[6,7] ="pm"
    end

    if hora[1,2] = "15" then
    begin
        let ftime[1,3] = " 3:"
        let ftime[4,5] = hora[4,5]
        let ftime[6,7] ="pm"
    end

    if hora[1,2] = "16" then
    begin
        let ftime[1,3] = " 4:"
        let ftime[4,5] = hora[4,5]
        let ftime[6,7] ="pm"
    end

    if hora[1,2] = "17" then
    begin
        let ftime[1,3] = " 5:"
        let ftime[4,5] = hora[4,5]
        let ftime[6,7] ="pm"
    end

    if hora[1,2] = "18" then
    begin
        let ftime[1,3] = " 6:"
        let ftime[4,5] = hora[4,5]
        let ftime[6,7] ="pm"
    end

    if hora[1,2] = "19" then
    begin
        let ftime[1,3] = " 7:"
        let ftime[4,5] = hora[4,5]
        let ftime[6,7] ="pm"
    end

    if hora[1,2] = "20" then
    begin
        let ftime[1,3] = " 8:"
        let ftime[4,5] = hora[4,5]
        let ftime[6,7] ="pm"
    end

    if hora[1,2] = "21" then
    begin
        let ftime[1,3] = " 9:"
        let ftime[4,5] = hora[4,5]
        let ftime[6,7] ="pm"
    end

    if hora[1,2] = "22" then
    begin
        let ftime[1,3] = "10:"
        let ftime[4,5] = hora[4,5]
        let ftime[6,7] ="pm"
    end

    if hora[1,2] = "23" then
    begin
        let ftime[1,3] = "11:"
        let ftime[4,5] = hora[4,5]
        let ftime[6,7] ="pm"
    end

    if hora[1,2] = "00" then
    begin
        let ftime[1,3] = "12:"
        let ftime[4,5] = hora[4,5]
        let ftime[6,7] ="am"
    end

    print "TIME:",ftime
Frank Computer
From Frank Computer: "well, mr. cheese with cheese.. did the long ACE report example for converting mil time to AM/PM work for you?.. I had to use it in, believe it, ACE version 2.10 of I-SQL for DOS because in that fosil version DATETIME or CURRENT didn't exist. the only way of extracting the MS-DOS system time was with the TIME constant available in ACE. Perform screens only had TODAY for current date, but no TIME."
CheeseConQueso
@Frank - haven't tried it yet since i have a working report, but I'll give it a shot when i have some slow time at work and I'll let you know.... thanks for the case stmt
CheeseConQueso
+1  A: 

The requestor said it had to be done for an ACE report, so I thought that my example in ACE format was appropriate!...

Example of military hour to AM/PM format in ACE:

format

on every row

let hora = time

if hora[1,2] = "01" then
begin 
let ftime[1,3] = " 1:"
let ftime[4,5] = hora[4,5] 
let ftime[6,7] ="am" 
end

if hora[1,2] = "02" then
begin
let ftime[1,3] = " 2:"
let ftime[4,5] = hora[4,5]
let ftime[6,7] ="am"
end

if hora[1,2] = "03" then
begin
let ftime[1,3] = " 3:"
let ftime[4,5] = hora[4,5]
let ftime[6,7] ="am"
end

if hora[1,2] = "04" then
begin
let ftime[1,3] = " 4:"
let ftime[4,5] = hora[4,5]
let ftime[6,7] ="am"
end

if hora[1,2] = "05" then
begin
let ftime[1,3] = " 5:"
let ftime[4,5] = hora[4,5]
let ftime[6,7] ="am"
end

if hora[1,2] = "06" then
begin
let ftime[1,3] = " 6:"
let ftime[4,5] = hora[4,5]
let ftime[6,7] ="am"
end

if hora[1,2] = "07" then
begin
let ftime[1,3] = " 7:"
let ftime[4,5] = hora[4,5]
let ftime[6,7] ="am"
end

if hora[1,2] = "08" then
begin
let ftime[1,3] = " 8:"
let ftime[4,5] = hora[4,5]
let ftime[6,7] ="am"
end

if hora[1,2] = "09" then
begin
let ftime[1,3] = " 9:"
let ftime[4,5] = hora[4,5]
let ftime[6,7] ="am"
end

if hora[1,2] = "10" then
begin
let ftime[1,3] = "10:"
let ftime[4,5] = hora[4,5]
let ftime[6,7] ="am"
end

if hora[1,2] = "11" then
begin
let ftime[1,3] = "11:"
let ftime[4,5] = hora[4,5]
let ftime[6,7] ="am"
end

if hora[1,2] = "12" then
begin
let ftime[1,3] = "12:"
let ftime[4,5] = hora[4,5]
let ftime[6,7] ="pm"
end

if hora[1,2] = "13" then
begin
let ftime[1,3] = " 1:"
let ftime[4,5] = hora[4,5]
let ftime[6,7] ="pm"
end

if hora[1,2] = "14" then
begin
let ftime[1,3] = " 2:"
let ftime[4,5] = hora[4,5]
let ftime[6,7] ="pm"
end

if hora[1,2] = "15" then
begin
let ftime[1,3] = " 3:"
let ftime[4,5] = hora[4,5]
let ftime[6,7] ="pm"
end

if hora[1,2] = "16" then
begin
let ftime[1,3] = " 4:"
let ftime[4,5] = hora[4,5]
let ftime[6,7] ="pm"
end

if hora[1,2] = "17" then
begin
let ftime[1,3] = " 5:"
let ftime[4,5] = hora[4,5]
let ftime[6,7] ="pm"
end

if hora[1,2] = "18" then
begin
let ftime[1,3] = " 6:"
let ftime[4,5] = hora[4,5]
let ftime[6,7] ="pm"
end

if hora[1,2] = "19" then
begin
let ftime[1,3] = " 7:"
let ftime[4,5] = hora[4,5]
let ftime[6,7] ="pm"
end

if hora[1,2] = "20" then
begin
let ftime[1,3] = " 8:"
let ftime[4,5] = hora[4,5]
let ftime[6,7] ="pm"
end

if hora[1,2] = "21" then
begin
let ftime[1,3] = " 9:"
let ftime[4,5] = hora[4,5]
let ftime[6,7] ="pm"
end

if hora[1,2] = "22" then
begin
let ftime[1,3] = "10:"
let ftime[4,5] = hora[4,5]
let ftime[6,7] ="pm"
end

if hora[1,2] = "23" then
begin
let ftime[1,3] = "11:"
let ftime[4,5] = hora[4,5]
let ftime[6,7] ="pm"
end

if hora[1,2] = "00" then
begin
let ftime[1,3] = "12:"
let ftime[4,5] = hora[4,5]
let ftime[6,7] ="am"
end

print "TIME:",ftime
Frank Computer
looks interesting.... ill check it out next monday
CheeseConQueso
+2  A: 

Ah, a fellow Jenzabar user (Jonathan, don't be too cruel about the schemas. They are literally decades old). Surprised you didn't ask this on the CX-Tech list. I'd've sent you an RCS-ready stored procedure for CX.

-sw

{
 Revision Information (Automatically maintained by 'make' - DON'T CHANGE)
 -------------------------------------------------------------------------
 $Header$
 -------------------------------------------------------------------------
}
procedure       se_get_inttime
privilege       owner
description     "Get time from an integer field and return as datetime"
inputs          param_time integer      "Integer formatted time"
returns         datetime hour to minute "Time in datetime format"
notes           "Get time from an integer field and return as datetime"

begin procedure

DEFINE tm_str VARCHAR(255);
DEFINE h INTEGER;
DEFINE m INTEGER;

IF (param_time < 0 OR param_time > 2359) THEN
RAISE EXCEPTION -746, 0, "Invalid time format. Should be: 0 - 2359";
END IF

LET tm_str = LPAD(param_time, 4, 0);

LET h = SUBSTR(tm_str, 1, 2);

IF (h < 0 OR h > 23) THEN
RAISE EXCEPTION -746, 0, "Invalid time format. Should be: 0 - 2359";
END IF

LET m = SUBSTR(tm_str, 3, 4);

IF (m < 0 OR m > 59) THEN
RAISE EXCEPTION -746, 0, "Invalid time format. Should be: 0 - 2359";
END IF

RETURN TO_DATE(h || ':' || m , '%R');

end procedure

grant
    execute to (group public)
Stephen Olander-Waters
this looks promising.... thanks ill give it a shot
CheeseConQueso